ninjabackend: Pass the import library to SHSYM

We actually use this while linking on Windows, and hence we need to
extract symbols from this file, and not the DLL.

However, we cannot pass it instead of the DLL because it's an optional
output of the compiler. It will not be written out at all if there are
no symbols in the DLL, and we cannot know that at configure time. This
means we cannot describe it as an output of any ninja target, or the
input of any ninja target. We must pass it as an argument without
semantic meaning.
pull/6637/head
Nirbheek Chauhan 5 years ago
parent 72c6cbd990
commit 5dcbf10a1b
  1. 14
      mesonbuild/backend/ninjabackend.py
  2. 11
      mesonbuild/scripts/symbolextractor.py

@ -1590,6 +1590,7 @@ int dummy;
'symbolextractor',
ninja_quote(quote_func(self.environment.get_build_dir())),
'$in',
'$IMPLIB',
'$out']
symrule = 'SHSYM'
symcmd = args + ['$CROSS']
@ -2308,12 +2309,17 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
self.add_build(elem)
return pch_objects
def get_target_shsym_filename(self, target):
# Always name the .symbols file after the primary build output because it always exists
targetdir = self.get_target_private_dir(target)
return os.path.join(targetdir, target.get_filename() + '.symbols')
def generate_shsym(self, target):
target_name = target.get_filename()
target_file = self.get_target_filename(target)
targetdir = self.get_target_private_dir(target)
symname = os.path.join(targetdir, target_name + '.symbols')
symname = self.get_target_shsym_filename(target)
elem = NinjaBuildElement(self.all_outputs, symname, 'SHSYM', target_file)
# The library we will actually link to, which is an import library on Windows (not the DLL)
elem.add_item('IMPLIB', self.get_target_filename_for_linking(target))
if self.environment.is_cross_build():
elem.add_item('CROSS', '--cross-host=' + self.environment.machines[target.for_machine].system)
self.add_build(elem)
@ -2593,7 +2599,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
def get_dependency_filename(self, t):
if isinstance(t, build.SharedLibrary):
return os.path.join(self.get_target_private_dir(t), t.get_filename() + '.symbols')
return self.get_target_shsym_filename(t)
elif isinstance(t, mesonlib.File):
if t.is_built:
return t.relative_name()

@ -129,7 +129,7 @@ def osx_syms(libfilename: str, outfilename: str):
result += [' '.join(x.split()[0:2]) for x in output.split('\n')]
write_if_changed('\n'.join(result) + '\n', outfilename)
def gen_symbols(libfilename: str, outfilename: str, cross_host: str):
def gen_symbols(libfilename: str, impfilename: str, outfilename: str, cross_host: str):
if cross_host is not None:
# In case of cross builds just always relink. In theory we could
# determine the correct toolset, but we would need to use the correct
@ -151,14 +151,15 @@ def gen_symbols(libfilename: str, outfilename: str, cross_host: str):
def run(args):
global TOOL_WARNING_FILE
options = parser.parse_args(args)
if len(options.args) != 3:
print('symbolextractor.py <shared library file> <output file>')
if len(options.args) != 4:
print('symbolextractor.py <shared library file> <import library> <output file>')
sys.exit(1)
privdir = os.path.join(options.args[0], 'meson-private')
TOOL_WARNING_FILE = os.path.join(privdir, 'symbolextractor_tool_warning_printed')
libfile = options.args[1]
outfile = options.args[2]
gen_symbols(libfile, outfile, options.cross_host)
impfile = options.args[2] # Only used on Windows
outfile = options.args[3]
gen_symbols(libfile, impfile, outfile, options.cross_host)
return 0
if __name__ == '__main__':

Loading…
Cancel
Save