From d0172432a7eb95f1f5d16825d4440bc7e2da758f Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 10 Mar 2020 10:13:23 -0700 Subject: compilers: Don't put split soname args in start groups Some compilers that act as linker drivers (dmd and ldc) need to split arguments that GCC combines with , (ie, -Wl,-foo,bar -> -L=-foo -L=bar). As such we need to detect that the previous argument contained -soname, and not wrap that in a --start-group/--end-group This modifies the shared library test to demonstrate the problem, with a test case. Fixes #6359 --- mesonbuild/compilers/compilers.py | 10 ++++++++++ test cases/d/3 shared library/lld-test.py | 20 ++++++++++++++++++++ test cases/d/3 shared library/meson.build | 7 ++++++- test cases/d/3 shared library/sub/libstuff.d | 14 ++++++++++++++ test cases/d/3 shared library/sub/meson.build | 2 ++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 test cases/d/3 shared library/lld-test.py create mode 100644 test cases/d/3 shared library/sub/libstuff.d create mode 100644 test cases/d/3 shared library/sub/meson.build diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 436b09de4..03c7a6f07 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -569,7 +569,17 @@ class CompilerArgs(collections.abc.MutableSequence): isinstance(self.compiler.linker, (GnuLikeDynamicLinkerMixin, SolarisDynamicLinker))): group_start = -1 group_end = -1 + is_soname = False for i, each in enumerate(new): + if is_soname: + is_soname = False + continue + elif '-soname' in each: + # To proxy these arguments with D you need to split the + # arguments, thus you get `-L=-soname -L=lib.so` we don't + # want to put the lib in a link -roup + is_soname = True + continue if not each.startswith(('-Wl,-l', '-l')) and not each.endswith('.a') and \ not soregex.match(each): continue diff --git a/test cases/d/3 shared library/lld-test.py b/test cases/d/3 shared library/lld-test.py new file mode 100644 index 000000000..3f32f59fb --- /dev/null +++ b/test cases/d/3 shared library/lld-test.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 + +import argparse +import subprocess + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('ldd') + parser.add_argument('bin') + args = parser.parse_args() + + p, o, _ = subprocess.run([args.ldd, args.bin], stdout=subprocess.PIPE) + assert p == 0 + o = o.decode() + assert 'libstuff.so =>' in o, 'libstuff so not in linker path.' + assert 'libstuff.so => not found' not in o, 'libstuff.so not found correctly' + + +if __name__ == '__main__': + main() diff --git a/test cases/d/3 shared library/meson.build b/test cases/d/3 shared library/meson.build index b37b700e6..fa417794c 100644 --- a/test cases/d/3 shared library/meson.build +++ b/test cases/d/3 shared library/meson.build @@ -7,7 +7,7 @@ if dc.get_id() == 'gcc' endif endif -ldyn = shared_library('stuff', 'libstuff.d', install : true) +subdir('sub') ed = executable('app_d', 'app.d', link_with : ldyn, install : true) test('linktest_dyn', ed) @@ -19,3 +19,8 @@ pkgc.generate(name: 'test', description: 'A test of D attributes to pkgconfig.generate.', d_module_versions: ['Use_Static'] ) + +ldd = find_program('ldd', required : false) +if ldd.found() + test('ldd-test.py', ed) +endif diff --git a/test cases/d/3 shared library/sub/libstuff.d b/test cases/d/3 shared library/sub/libstuff.d new file mode 100644 index 000000000..8205490f7 --- /dev/null +++ b/test cases/d/3 shared library/sub/libstuff.d @@ -0,0 +1,14 @@ +import std.stdio; +import std.string : format; + +export int printLibraryString (string str) +{ + writeln ("Library says: %s".format (str)); + return 4; +} + +version (Windows) +{ + import core.sys.windows.dll; + mixin SimpleDllMain; +} diff --git a/test cases/d/3 shared library/sub/meson.build b/test cases/d/3 shared library/sub/meson.build new file mode 100644 index 000000000..fb4b99661 --- /dev/null +++ b/test cases/d/3 shared library/sub/meson.build @@ -0,0 +1,2 @@ +ldyn = shared_library('stuff', 'libstuff.d', install : true) + -- cgit v1.2.3