aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Seifert <soap@gentoo.org>2018-03-19 08:16:25 -0700
committerJussi Pakkanen <jpakkane@gmail.com>2018-03-19 23:37:14 +0200
commit7eb187c5f2cf55c6d441db08a87bac02cb58a9dc (patch)
tree57d824083ff7a54fc08752b4574b23bcb8853ed3
parent50c66f1f5c099cb1286dab8a646bed55f39d1e3e (diff)
downloadmeson-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.py29
-rw-r--r--test cases/common/183 as-needed/config.h14
-rw-r--r--test cases/common/183 as-needed/libA.cpp7
-rw-r--r--test cases/common/183 as-needed/libA.h5
-rw-r--r--test cases/common/183 as-needed/libB.cpp19
-rw-r--r--test cases/common/183 as-needed/main.cpp7
-rw-r--r--test cases/common/183 as-needed/meson.build13
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)