Merge pull request #3831 from mesonbuild/symvisibility

Add gnu_symbol_visibility keyword argument
pull/4015/head
Jussi Pakkanen 6 years ago committed by GitHub
commit f91b463bf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      docs/markdown/Reference-manual.md
  2. 13
      docs/markdown/snippets/visibility.md
  3. 2
      mesonbuild/backend/ninjabackend.py
  4. 9
      mesonbuild/build.py
  5. 15
      mesonbuild/compilers/compilers.py
  6. 1
      mesonbuild/interpreter.py
  7. 16
      mesonbuild/minit.py
  8. 5
      test cases/failing build/2 hidden symbol/bob.c
  9. 3
      test cases/failing build/2 hidden symbol/bob.h
  10. 5
      test cases/failing build/2 hidden symbol/bobuser.c
  11. 14
      test cases/failing build/2 hidden symbol/meson.build

@ -511,6 +511,13 @@ be passed to [shared and static libraries](#library).
- `override_options` takes an array of strings in the same format as
`project`'s `default_options` overriding the values of these options
for this target only, since 0.40.0
- `gnu_symbol_visibility` specifies how symbols should be exported, see
e.g [the GCC Wiki](https://gcc.gnu.org/wiki/Visibility) for more
information. This value can either be an empty string or one of
`default`, `internal`, `hidden`, `protected` or `inlineshidden`, which
is the same as `hidden` but also includes things like C++ implicit
constructors as specified in the GCC manual. Ignored on compilers that
do not support GNU visibility arguments. Available since 0.48.0.
- `d_import_dirs` list of directories to look in for string imports used
in the D programming language
- `d_unittest`, when set to true, the D modules are compiled in debug mode
@ -976,15 +983,16 @@ dropped. That means that `join_paths('foo', '/bar')` returns `/bar`.
buildtarget library(library_name, list_of_sources, ...)
```
Builds a library that is either static, shared or both depending on the value of
`default_library` user option. You should use this instead of
[`shared_library`](#shared_library),
Builds a library that is either static, shared or both depending on
the value of `default_library` user option. You should use this
instead of [`shared_library`](#shared_library),
[`static_library`](#static_library) or
[`both_libraries`](#both_libraries) most of the time. This allows you
to toggle your entire project (including subprojects) from shared to
static with only one option.
The keyword arguments for this are the same as for [`executable`](#executable) with the following additions:
The keyword arguments for this are the same as for
[`executable`](#executable) with the following additions:
- `name_prefix` the string that will be used as the prefix for the
target output filename by overriding the default (only used for

@ -0,0 +1,13 @@
## Keyword argument for GNU symbol visibility
Build targets got a new keyword, `symbol_visibility` that controls how
symbols are exported from shared libraries. This is most commonly used
to hide implementation symbols like this:
```meson
shared_library('mylib', ...
gnu_symbol_visibility: 'hidden')
```
In this case only symbols explicitly marked as visible in the source
files get exported.

@ -1951,6 +1951,8 @@ rule FORTRAN_DEP_HACK%s
# Create an empty commands list, and start adding arguments from
# various sources in the order in which they must override each other
commands = CompilerArgs(compiler)
# Start with symbol visibility.
commands += compiler.gnu_symbol_visibility_args(target.gnu_symbol_visibility)
# Add compiler args for compiling this target derived from 'base' build
# options passed on the command-line, in default_options, etc.
# These have the lowest priority.

@ -71,6 +71,7 @@ buildtarget_kwargs = set([
'objects',
'override_options',
'sources',
'gnu_symbol_visibility',
])
known_build_target_kwargs = (
@ -817,6 +818,14 @@ This will become a hard error in a future Meson release.''')
self.implicit_include_directories = kwargs.get('implicit_include_directories', True)
if not isinstance(self.implicit_include_directories, bool):
raise InvalidArguments('Implicit_include_directories must be a boolean.')
self.gnu_symbol_visibility = kwargs.get('gnu_symbol_visibility', '')
if not isinstance(self.gnu_symbol_visibility, str):
raise InvalidArguments('GNU symbol visibility must be a string.')
if self.gnu_symbol_visibility != '':
permitted = ['default', 'internal', 'hidden', 'protected', 'inlineshidden']
if self.gnu_symbol_visibility not in permitted:
raise InvalidArguments('GNU symbol visibility arg %s not one of: %s',
self.symbol_visibility, ', '.join(permitted))
def get_filename(self):
return self.filename

@ -311,6 +311,14 @@ vs64_instruction_set_args = {'mmx': ['/arch:AVX'],
'neon': None,
}
gnu_symbol_visibility_args = {'': [],
'default': ['-fvisibility=default'],
'internal': ['-fvisibility=internal'],
'hidden': ['-fvisibility=hidden'],
'protected': ['-fvisibility=protected'],
'inlineshidden': ['-fvisibility=hidden', '-fvisibility-inlines-hidden'],
}
def sanitizer_compile_args(value):
if value == 'none':
return []
@ -1065,6 +1073,9 @@ class Compiler:
# building fails with undefined symbols.
return []
def gnu_symbol_visibility_args(self, vistype):
return []
GCC_STANDARD = 0
GCC_OSX = 1
GCC_MINGW = 2
@ -1280,6 +1291,8 @@ class GnuCompiler:
def openmp_flags(self):
return ['-fopenmp']
def gnu_symbol_visibility_args(self, vistype):
return gnu_symbol_visibility_args[vistype]
class ElbrusCompiler(GnuCompiler):
# Elbrus compiler is nearly like GCC, but does not support
@ -1422,6 +1435,8 @@ class ClangCompiler:
# Shouldn't work, but it'll be checked explicitly in the OpenMP dependency.
return []
def gnu_symbol_visibility_args(self, vistype):
return gnu_symbol_visibility_args[vistype]
class ArmclangCompiler:
def __init__(self):

@ -3854,6 +3854,7 @@ Try setting b_lundef to false instead.''')
@FeatureNewKwargs('build target', '0.42.0', ['rust_crate_type', 'build_rpath', 'implicit_include_directories'])
@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'])
def build_target_decorator_caller(self, node, args, kwargs):
return True

@ -72,16 +72,10 @@ lib_c_meson_template = '''project('{project_name}', 'c',
# not the executables that use the library.
lib_args = ['-DBUILDING_{utoken}']
# Hiding symbols that are not explicitly marked as exported
# requires a compiler flag on all compilers except VS.
cc = meson.get_compiler('c')
if cc.get_id() != 'msvc'
lib_args += ['-fvisibility=hidden']
endif
shlib = shared_library('{lib_name}', '{source_file}',
install : true,
c_args : lib_args,
gnu_symbol_visibility : 'hidden',
)
test_exe = executable('{test_exe_name}', '{test_source_file}',
@ -226,16 +220,10 @@ lib_cpp_meson_template = '''project('{project_name}', 'cpp',
# not the executables that use the library.
lib_args = ['-DBUILDING_{utoken}']
# Hiding symbols that are not explicitly marked as exported
# requires a compiler flag on all compilers except VS.
cpp = meson.get_compiler('cpp')
if cpp.get_id() != 'msvc'
lib_args += ['-fvisibility=hidden']
endif
shlib = shared_library('{lib_name}', '{source_file}',
install : true,
cpp_args : lib_args,
gnu_symbol_visibility : 'hidden',
)
test_exe = executable('{test_exe_name}', '{test_source_file}',

@ -0,0 +1,5 @@
#include"bob.h"
int hidden_function() {
return 7;
}

@ -0,0 +1,3 @@
#pragma once
int hidden_function();

@ -0,0 +1,5 @@
#include"bob.h"
int main(int argc, char **argv) {
return hidden_function();
}

@ -0,0 +1,14 @@
project('hidden symbol', 'c')
if host_machine.system() == 'windows' or host_machine.system() == 'cygwin'
cc = meson.get_compiler('c')
if cc.get_id() == 'gcc'
error('MESON_SKIP_TEST -fvisibility=hidden does not work on MinGW or Cygwin.')
endif
endif
l = shared_library('bob', 'bob.c',
gnu_symbol_visibility: 'hidden')
executable('bobuser', 'bobuser.c',
link_with: l)
Loading…
Cancel
Save