From aee9f589398fa3d6c42b50dd1000598ef36ecfb3 Mon Sep 17 00:00:00 2001 From: Rafael Ávila de Espíndola Date: Wed, 18 Jul 2018 15:24:59 -0700 Subject: Handle transitive links to 'threads' dependencies. (#3895) Meson already had code to propagate link dependencies from static libraries to programs that use those static libraries. Unfortunately, it was not handling the special cases of 'threads' and 'openmp' dependencies. --- mesonbuild/backend/ninjabackend.py | 21 ++++++++++++++------- test cases/common/205 static threads/lib1.c | 13 +++++++++++++ test cases/common/205 static threads/lib2.c | 5 +++++ test cases/common/205 static threads/meson.build | 13 +++++++++++++ test cases/common/205 static threads/prog.c | 6 ++++++ 5 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 test cases/common/205 static threads/lib1.c create mode 100644 test cases/common/205 static threads/lib2.c create mode 100644 test cases/common/205 static threads/meson.build create mode 100644 test cases/common/205 static threads/prog.c diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 09c49049d..035f83520 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2623,25 +2623,32 @@ rule FORTRAN_DEP_HACK%s dependencies = target.get_dependencies() internal = self.build_target_link_arguments(linker, dependencies) commands += internal - # For 'automagic' deps: Boost and GTest. Also dependency('threads'). - # pkg-config puts the thread flags itself via `Cflags:` - for d in target.external_deps: - if d.need_threads(): - commands += linker.thread_link_flags(self.environment) - elif d.need_openmp(): - commands += linker.openmp_flags() # Only non-static built targets need link args and link dependencies if not isinstance(target, build.StaticLibrary): + # For 'automagic' deps: Boost and GTest. Also dependency('threads'). + # pkg-config puts the thread flags itself via `Cflags:` + need_threads = False + need_openmp = False + commands += target.link_args # External deps must be last because target link libraries may depend on them. for dep in target.get_external_deps(): # Extend without reordering or de-dup to preserve `-L -l` sets # https://github.com/mesonbuild/meson/issues/1718 commands.extend_direct(dep.get_link_args()) + need_threads |= dep.need_threads() + need_openmp |= dep.need_openmp() for d in target.get_dependencies(): if isinstance(d, build.StaticLibrary): for dep in d.get_external_deps(): + need_threads |= dep.need_threads() + need_openmp |= dep.need_openmp() commands.extend_direct(dep.get_link_args()) + if need_openmp: + commands += linker.openmp_flags() + if need_threads: + commands += linker.thread_link_flags(self.environment) + # Add link args for c_* or cpp_* build options. Currently this only # adds c_winlibs and cpp_winlibs when building for Windows. This needs # to be after all internal and external libraries so that unresolved diff --git a/test cases/common/205 static threads/lib1.c b/test cases/common/205 static threads/lib1.c new file mode 100644 index 000000000..1aa786c66 --- /dev/null +++ b/test cases/common/205 static threads/lib1.c @@ -0,0 +1,13 @@ +#if defined _WIN32 +#include +#else +#include +#endif + +void *f(void) { +#if defined _WIN32 + return CreateThread; +#else + return pthread_create; +#endif +} diff --git a/test cases/common/205 static threads/lib2.c b/test cases/common/205 static threads/lib2.c new file mode 100644 index 000000000..e988814e2 --- /dev/null +++ b/test cases/common/205 static threads/lib2.c @@ -0,0 +1,5 @@ +extern void *f(void); + +void *g(void) { + return f(); +} diff --git a/test cases/common/205 static threads/meson.build b/test cases/common/205 static threads/meson.build new file mode 100644 index 000000000..427920034 --- /dev/null +++ b/test cases/common/205 static threads/meson.build @@ -0,0 +1,13 @@ +project('threads', 'c') + +thread_dep = dependency('threads') + + +lib1 = static_library('lib1', 'lib1.c', + dependencies : thread_dep) + +lib2 = static_library('lib2', 'lib2.c', + link_with : lib1) + +executable('prog', 'prog.c', + link_with : lib2) diff --git a/test cases/common/205 static threads/prog.c b/test cases/common/205 static threads/prog.c new file mode 100644 index 000000000..14a7c760f --- /dev/null +++ b/test cases/common/205 static threads/prog.c @@ -0,0 +1,6 @@ +extern void *g(void); + +int main(void) { + g(); + return 0; +} -- cgit v1.2.3