diff options
author | David Seifert <soap@gentoo.org> | 2018-03-19 08:16:25 -0700 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2018-03-19 23:37:14 +0200 |
commit | 7eb187c5f2cf55c6d441db08a87bac02cb58a9dc (patch) | |
tree | 57d824083ff7a54fc08752b4574b23bcb8853ed3 | |
parent | 50c66f1f5c099cb1286dab8a646bed55f39d1e3e (diff) | |
download | meson-7eb187c5f2cf55c6d441db08a87bac02cb58a9dc.zip meson-7eb187c5f2cf55c6d441db08a87bac02cb58a9dc.tar.gz meson-7eb187c5f2cf55c6d441db08a87bac02cb58a9dc.tar.bz2 |
Add -Wl,-dead_strip_dylibs support
* `-Wl,-dead_strip_dylibs` is the analogue
of `-Wl,--as-needed` on macOS.
-rw-r--r-- | mesonbuild/compilers/compilers.py | 29 | ||||
-rw-r--r-- | test cases/common/183 as-needed/config.h | 14 | ||||
-rw-r--r-- | test cases/common/183 as-needed/libA.cpp | 7 | ||||
-rw-r--r-- | test cases/common/183 as-needed/libA.h | 5 | ||||
-rw-r--r-- | test cases/common/183 as-needed/libB.cpp | 19 | ||||
-rw-r--r-- | test cases/common/183 as-needed/main.cpp | 7 | ||||
-rw-r--r-- | test cases/common/183 as-needed/meson.build | 13 |
7 files changed, 91 insertions, 3 deletions
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 034fef4..f8dfc96 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -348,7 +348,7 @@ def get_base_link_args(options, linker, is_shared_module): pass try: if 'b_asneeded' in linker.base_options and options['b_asneeded'].value: - args.append('-Wl,--as-needed') + args.append(linker.get_asneeded_args()) except KeyError: pass try: @@ -900,6 +900,13 @@ ICC_STANDARD = 0 ICC_OSX = 1 ICC_WIN = 2 +# GNU ld cannot be installed on macOS +# https://github.com/Homebrew/homebrew-core/issues/17794#issuecomment-328174395 +# Hence, we don't need to differentiate between OS and ld +# for the sake of adding as-needed support +GNU_LD_AS_NEEDED = '-Wl,--as-needed' +APPLE_LD_AS_NEEDED = '-Wl,-dead_strip_dylibs' + def get_gcc_soname_args(gcc_type, prefix, shlib_name, suffix, path, soversion, is_shared_module): if soversion is None: sostr = '' @@ -1002,10 +1009,18 @@ class GnuCompiler: 'b_colorout', 'b_ndebug', 'b_staticpic'] if self.gcc_type != GCC_OSX: self.base_options.append('b_lundef') - self.base_options.append('b_asneeded') + self.base_options.append('b_asneeded') # All GCC backends can do assembly self.can_compile_suffixes.add('s') + # TODO: centralise this policy more globally, instead + # of fragmenting it into GnuCompiler and ClangCompiler + def get_asneeded_args(self): + if self.gcc_type == GCC_OSX: + return APPLE_LD_AS_NEEDED + else: + return GNU_LD_AS_NEEDED + def get_colorout_args(self, colortype): if mesonlib.version_compare(self.version, '>=4.9.0'): return gnu_color_args[colortype][:] @@ -1084,10 +1099,18 @@ class ClangCompiler: 'b_ndebug', 'b_staticpic', 'b_colorout'] if self.clang_type != CLANG_OSX: self.base_options.append('b_lundef') - self.base_options.append('b_asneeded') + self.base_options.append('b_asneeded') # All Clang backends can do assembly and LLVM IR self.can_compile_suffixes.update(['ll', 's']) + # TODO: centralise this policy more globally, instead + # of fragmenting it into GnuCompiler and ClangCompiler + def get_asneeded_args(self): + if self.clang_type == CLANG_OSX: + return APPLE_LD_AS_NEEDED + else: + return GNU_LD_AS_NEEDED + def get_pic_args(self): if self.clang_type in (CLANG_WIN, CLANG_OSX): return [] # On Window and OS X, pic is always on. diff --git a/test cases/common/183 as-needed/config.h b/test cases/common/183 as-needed/config.h new file mode 100644 index 0000000..b8fb60f --- /dev/null +++ b/test cases/common/183 as-needed/config.h @@ -0,0 +1,14 @@ +#if defined _WIN32 || defined __CYGWIN__ + #if defined BUILDING_DLL + #define DLL_PUBLIC __declspec(dllexport) + #else + #define DLL_PUBLIC __declspec(dllimport) + #endif +#else + #if defined __GNUC__ + #define DLL_PUBLIC __attribute__ ((visibility("default"))) + #else + #pragma message ("Compiler does not support symbol visibility.") + #define DLL_PUBLIC + #endif +#endif diff --git a/test cases/common/183 as-needed/libA.cpp b/test cases/common/183 as-needed/libA.cpp new file mode 100644 index 0000000..5f45bc0 --- /dev/null +++ b/test cases/common/183 as-needed/libA.cpp @@ -0,0 +1,7 @@ +#define BUILDING_DLL + +#include "libA.h" + +namespace meson_test_as_needed { + DLL_PUBLIC bool linked = false; +} diff --git a/test cases/common/183 as-needed/libA.h b/test cases/common/183 as-needed/libA.h new file mode 100644 index 0000000..8e76d22 --- /dev/null +++ b/test cases/common/183 as-needed/libA.h @@ -0,0 +1,5 @@ +#include "config.h" + +namespace meson_test_as_needed { + DLL_PUBLIC extern bool linked; +} diff --git a/test cases/common/183 as-needed/libB.cpp b/test cases/common/183 as-needed/libB.cpp new file mode 100644 index 0000000..a872394 --- /dev/null +++ b/test cases/common/183 as-needed/libB.cpp @@ -0,0 +1,19 @@ +#include "libA.h" + +#undef DLL_PUBLIC +#define BUILDING_DLL +#include "config.h" + +namespace meson_test_as_needed { + namespace { + bool set_linked() { + linked = true; + return true; + } + bool stub = set_linked(); + } + + DLL_PUBLIC int libB_unused_func() { + return 0; + } +} diff --git a/test cases/common/183 as-needed/main.cpp b/test cases/common/183 as-needed/main.cpp new file mode 100644 index 0000000..cecb2ff --- /dev/null +++ b/test cases/common/183 as-needed/main.cpp @@ -0,0 +1,7 @@ +#include <cstdlib> + +#include "libA.h" + +int main() { + return (meson_test_as_needed::linked == false ? EXIT_SUCCESS : EXIT_FAILURE); +} diff --git a/test cases/common/183 as-needed/meson.build b/test cases/common/183 as-needed/meson.build new file mode 100644 index 0000000..3b54aaa --- /dev/null +++ b/test cases/common/183 as-needed/meson.build @@ -0,0 +1,13 @@ +project('as-needed test', 'cpp') + +# Idea behind this test is to have -Wl,--as-needed prune +# away unneeded linkages, which would otherwise cause global +# static initialiser side-effects to set a boolean to true. + +# Credits for portable ISO C++ idea go to sarum9in + +libA = library('A', 'libA.cpp') +libB = library('B', 'libB.cpp', link_with : libA) + +main_exe = executable('C', 'main.cpp', link_with : [libA, libB]) +test('main test', main_exe) |