Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for symbol visibility export files #4747

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions mesonbuild/backend/ninjabackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -2448,6 +2448,20 @@ def guess_external_link_dependencies(self, linker, target, commands, internal):

return guessed_dependencies + absolute_libs

def get_export_symbol_file_args(self, linker, target):
args = []
dep_files = []
for f in target.symbol_export_files:
if isinstance(f, File):
relpath = f.rel_to_builddir(self.build_to_src)
elif isinstance(f, build.CustomTarget):
relpath = self.get_target_filename(f)
else:
raise RuntimeError('Broken, please file a bug.')
args += linker.get_symbol_export_file_args(relpath)
dep_files.append(relpath)
return (args, dep_files)

def generate_link(self, target, outfile, outname, obj_list, linker, extra_args=[], stdlib_args=[]):
if isinstance(target, build.StaticLibrary):
linker_base = 'STATIC'
Expand Down Expand Up @@ -2481,6 +2495,8 @@ def generate_link(self, target, outfile, outname, obj_list, linker, extra_args=[
commands += linker.get_linker_always_args()
# Add buildtype linker args: optimization level, etc.
commands += linker.get_buildtype_linker_args(self.get_option_for_target('buildtype', target))
export_file_commands, export_file_deps = self.get_export_symbol_file_args(linker, target)
commands += export_file_commands
# Add /DEBUG and the pdb filename when using MSVC
if self.get_option_for_target('debug', target):
commands += self.get_link_debugfile_args(linker, target, outname)
Expand Down Expand Up @@ -2586,6 +2602,7 @@ def generate_link(self, target, outfile, outname, obj_list, linker, extra_args=[
dep_targets.extend([self.get_dependency_filename(t) for t in dependencies])
dep_targets.extend([self.get_dependency_filename(t)
for t in target.link_depends])
dep_targets += export_file_deps
elem = NinjaBuildElement(self.all_outputs, outname, linker_rule, obj_list)
elem.add_dep(dep_targets + custom_target_libraries)
elem.add_item('LINK_ARGS', commands)
Expand Down
12 changes: 12 additions & 0 deletions mesonbuild/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
'objects',
'override_options',
'sources',
'symbol_export_file',
'gnu_symbol_visibility',
])

Expand Down Expand Up @@ -448,6 +449,7 @@ def __init__(self, name, subdir, subproject, is_cross, sources, objects, environ
self.link_targets = []
self.link_whole_targets = []
self.link_depends = []
self.symbol_export_files = []
self.name_prefix_set = False
self.name_suffix_set = False
self.filename = 'no_name'
Expand Down Expand Up @@ -936,6 +938,16 @@ def process_kwargs(self, kwargs, environment):
if self.gnu_symbol_visibility not in permitted:
raise InvalidArguments('GNU symbol visibility arg %s not one of: %s',
self.symbol_visibility, ', '.join(permitted))
for i in listify(kwargs.get('symbol_export_file', []), unholder=True):
if isinstance(i, str):
f = File(False, self.subdir, i)
if not os.path.exists(f.absolute_path(self.environment.source_dir,
self.environment.build_dir)):
raise InvalidArguments('Nonexisting file {}.'.format(i))
i = f
if not isinstance(i, (File, CustomTarget)):
raise InvalidArguments('Symbol_export_file must be a string, file or a custom target.')
self.symbol_export_files.append(i)

def _extract_pic_pie(self, kwargs, arg):
# Check if we have -fPIC, -fpic, -fPIE, or -fpie in cflags
Expand Down
3 changes: 3 additions & 0 deletions mesonbuild/compilers/c.py
Original file line number Diff line number Diff line change
Expand Up @@ -1497,6 +1497,9 @@ def gen_vs_module_defs_args(self, defsfile):
# so if a module defs file is specified, we use that to export symbols
return ['/DEF:' + defsfile]

def get_symbol_export_file_args(self, path):
return ['/DEF:' + path]

def gen_pch_args(self, header, source, pchname):
objname = os.path.splitext(pchname)[0] + '.obj'
return objname, ['/Yc' + header, '/Fp' + pchname, '/Fo' + objname]
Expand Down
6 changes: 6 additions & 0 deletions mesonbuild/compilers/compilers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,9 @@ def language_stdlib_only_link_flags(self):
def gnu_symbol_visibility_args(self, vistype):
return []

def get_symbol_export_file_args(self, path):
raise EnvironmentException('Compiler {} does not support symbol exports.'.format(self.get_id()))

def get_gui_app_args(self, value):
return []

Expand Down Expand Up @@ -1547,6 +1550,9 @@ def openmp_flags(self):
def gnu_symbol_visibility_args(self, vistype):
return gnu_symbol_visibility_args[vistype]

def get_symbol_export_file_args(self, path):
return ['-Wl,--version-script=' + path]

def gen_vs_module_defs_args(self, defsfile):
if not isinstance(defsfile, str):
raise RuntimeError('Module definitions file should be str')
Expand Down
1 change: 1 addition & 0 deletions mesonbuild/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3950,6 +3950,7 @@ def build_target(self, node, args, kwargs, targetholder):
@FeatureNewKwargs('build target', '0.41.0', ['rust_args'])
@FeatureNewKwargs('build target', '0.40.0', ['build_by_default'])
@FeatureNewKwargs('build target', '0.48.0', ['gnu_symbol_visibility'])
@FeatureNewKwargs('build target', '0.50.0', ['symbol_export_file'])
def build_target_decorator_caller(self, node, args, kwargs):
return True

Expand Down
2 changes: 2 additions & 0 deletions test cases/common/213 version file/bob.sym
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
EXPORTS
bobMcBob
2 changes: 2 additions & 0 deletions test cases/common/213 version file/bob.sym.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
EXPORTS
@in@
70 changes: 70 additions & 0 deletions test cases/common/213 version file/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
project('linker script', 'c')

cc = meson.get_compiler('c')

if build_machine.system() == 'cygwin'
error('MESON_SKIP_TEST does not work on cygwin for some reason.')
endif

if cc.get_id() == 'clang-cl'
error('MESON_SKIP_TEST uses lld which is not supported yet. Patches welcome.')
endif


# Static map file
if cc.get_id() == 'msvc'
suffix = '.sym'
else
suffix = '.map'
endif

mapfile = 'bob' + suffix

l = shared_library('bob', 'bob.c', symbol_export_file: mapfile)
e = executable('prog', 'prog.c', link_with : l)
test('core', e)

# configure_file
conf = configuration_data()
conf.set('in', 'bobMcBob')
m = configure_file(
input : 'bob' + suffix + '.in',
output : 'bob-conf' + suffix,
configuration : conf,
)

l = shared_library('bob-conf', 'bob.c', symbol_export_file: m)
e = executable('prog-conf', 'prog.c', link_with : l)
test('core', e)

## custom_target
python = find_program('python3', required : false)
if not python.found()
python = find_program('python')
endif
m = custom_target(
'bob-ct' + suffix,
command : [python, '@INPUT0@', '@INPUT1@', '@OUTPUT@'],
input : ['copy.py', 'bob' + suffix],
output : 'bob-ct' + suffix,
)

l = shared_library('bob-ct', ['bob.c', m], symbol_export_file: m)
e = executable('prog-ct', 'prog.c', link_with : l)
test('core', e)

# File
mapfile = files('bob' + suffix)

l = shared_library('bob-files', 'bob.c', symbol_export_file: mapfile)
e = executable('prog-files', 'prog.c', link_with : l)
test('core', e)

subdir('sub')

# With map file in subdir
mapfile = files('sub/foo' + suffix)

l = shared_library('bar', 'bob.c', symbol_export_file: mapfile)
e = executable('prog-bar', 'prog.c', link_with : l)
test('core', e)
2 changes: 2 additions & 0 deletions test cases/common/213 version file/sub/foo.sym
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
EXPORTS
bobMcBob
5 changes: 5 additions & 0 deletions test cases/common/213 version file/sub/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mapfile = 'foo' + suffix

l = shared_library('foo', '../bob.c', symbol_export_file: mapfile)
e = executable('prog-foo', '../prog.c', link_with : l)
test('core', e)
56 changes: 0 additions & 56 deletions test cases/linuxlike/3 linker script/meson.build

This file was deleted.

6 changes: 0 additions & 6 deletions test cases/linuxlike/3 linker script/sub/meson.build

This file was deleted.