From 6963da616bc26708061878788240dbbb11cddc39 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 30 Mar 2017 23:38:28 +0530 Subject: [PATCH] Don't add dependencies recursively while linking We were doing this on the basis of an old comment, but there was no test for it and I couldn't reproduce the issue with clang on Linux at all. Let's add a (somewhat comprehensive) test and see if it breaks anywhere if we stop doing this. Halves the size of gstreamer's build.ninja from 20M to 8.7M Closes https://github.com/mesonbuild/meson/issues/1057 --- mesonbuild/backend/backends.py | 12 ++--- .../3rdorderdeps/lib.c.in | 8 ++++ .../3rdorderdeps/main.c.in | 16 +++++++ .../3rdorderdeps/meson.build | 44 ++++++++++++++++++ test cases/common/153 recursive linking/lib.h | 12 +++++ .../common/153 recursive linking/main.c | 46 +++++++++++++++++++ .../common/153 recursive linking/meson.build | 22 +++++++++ .../153 recursive linking/shnodep/lib.c | 6 +++ .../153 recursive linking/shnodep/meson.build | 1 + .../153 recursive linking/shshdep/lib.c | 8 ++++ .../153 recursive linking/shshdep/meson.build | 1 + .../153 recursive linking/shstdep/lib.c | 8 ++++ .../153 recursive linking/shstdep/meson.build | 1 + .../153 recursive linking/stnodep/lib.c | 6 +++ .../153 recursive linking/stnodep/meson.build | 1 + .../153 recursive linking/stshdep/lib.c | 8 ++++ .../153 recursive linking/stshdep/meson.build | 1 + .../153 recursive linking/ststdep/lib.c | 8 ++++ .../153 recursive linking/ststdep/meson.build | 1 + test cases/frameworks/7 gnome/gir/meson.build | 2 +- test cases/vala/11 generated vapi/meson.build | 2 +- 21 files changed, 204 insertions(+), 10 deletions(-) create mode 100644 test cases/common/153 recursive linking/3rdorderdeps/lib.c.in create mode 100644 test cases/common/153 recursive linking/3rdorderdeps/main.c.in create mode 100644 test cases/common/153 recursive linking/3rdorderdeps/meson.build create mode 100644 test cases/common/153 recursive linking/lib.h create mode 100644 test cases/common/153 recursive linking/main.c create mode 100644 test cases/common/153 recursive linking/meson.build create mode 100644 test cases/common/153 recursive linking/shnodep/lib.c create mode 100644 test cases/common/153 recursive linking/shnodep/meson.build create mode 100644 test cases/common/153 recursive linking/shshdep/lib.c create mode 100644 test cases/common/153 recursive linking/shshdep/meson.build create mode 100644 test cases/common/153 recursive linking/shstdep/lib.c create mode 100644 test cases/common/153 recursive linking/shstdep/meson.build create mode 100644 test cases/common/153 recursive linking/stnodep/lib.c create mode 100644 test cases/common/153 recursive linking/stnodep/meson.build create mode 100644 test cases/common/153 recursive linking/stshdep/lib.c create mode 100644 test cases/common/153 recursive linking/stshdep/meson.build create mode 100644 test cases/common/153 recursive linking/ststdep/lib.c create mode 100644 test cases/common/153 recursive linking/ststdep/meson.build diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 4cfdd9ebd..3044ce617 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -453,15 +453,11 @@ class Backend: for d in deps: if not isinstance(d, (build.StaticLibrary, build.SharedLibrary)): raise RuntimeError('Tried to link with a non-library target "%s".' % d.get_basename()) - if isinstance(compiler, compilers.LLVMDCompiler) or isinstance(compiler, compilers.DmdDCompiler): - args += ['-L' + self.get_target_filename_for_linking(d)] + if isinstance(compiler, (compilers.LLVMDCompiler, compilers.DmdDCompiler)): + d_arg = '-L' + self.get_target_filename_for_linking(d) else: - args.append(self.get_target_filename_for_linking(d)) - # If you have executable e that links to shared lib s1 that links to shared library s2 - # you have to specify s2 as well as s1 when linking e even if e does not directly use - # s2. Gcc handles this case fine but Clang does not for some reason. Thus we need to - # explictly specify all libraries every time. - args += self.build_target_link_arguments(compiler, d.get_dependencies()) + d_arg = self.get_target_filename_for_linking(d) + args.append(d_arg) return args def determine_windows_extra_paths(self, target): diff --git a/test cases/common/153 recursive linking/3rdorderdeps/lib.c.in b/test cases/common/153 recursive linking/3rdorderdeps/lib.c.in new file mode 100644 index 000000000..461f85995 --- /dev/null +++ b/test cases/common/153 recursive linking/3rdorderdeps/lib.c.in @@ -0,0 +1,8 @@ +#include "../lib.h" + +int get_@DEPENDENCY@dep_value (void); + +SYMBOL_EXPORT +int get_@LIBTYPE@@DEPENDENCY@dep_value (void) { + return get_@DEPENDENCY@dep_value (); +} diff --git a/test cases/common/153 recursive linking/3rdorderdeps/main.c.in b/test cases/common/153 recursive linking/3rdorderdeps/main.c.in new file mode 100644 index 000000000..8155f357e --- /dev/null +++ b/test cases/common/153 recursive linking/3rdorderdeps/main.c.in @@ -0,0 +1,16 @@ +#include + +#include "../lib.h" + +SYMBOL_IMPORT int get_@LIBTYPE@@DEPENDENCY@dep_value (void); + +int main(int argc, char *argv[]) { + int val; + + val = get_@LIBTYPE@@DEPENDENCY@dep_value (); + if (val != @VALUE@) { + printf("@LIBTYPE@@DEPENDENCY@ was %i instead of @VALUE@\n", val); + return -1; + } + return 0; +} diff --git a/test cases/common/153 recursive linking/3rdorderdeps/meson.build b/test cases/common/153 recursive linking/3rdorderdeps/meson.build new file mode 100644 index 000000000..a2907f383 --- /dev/null +++ b/test cases/common/153 recursive linking/3rdorderdeps/meson.build @@ -0,0 +1,44 @@ +dep3_libs = [] + +# Permutate all combinations of shared and static libraries up to three levels +# executable -> shared -> static -> shared (etc) +foreach dep2 : ['sh', 'st'] + foreach dep1 : ['sh', 'st'] + foreach libtype : ['sh', 'st'] + name = libtype + dep1 + dep2 + if dep2 == 'sh' + libret = 1 + elif dep2 == 'st' + libret = 2 + else + error('Unknown dep2 "@0@"'.format(dep2)) + endif + + if libtype == 'sh' + target = 'shared_library' + elif libtype == 'st' + target = 'static_library' + else + error('Unknown libtype "@0@"'.format(libtype)) + endif + + cdata = configuration_data() + cdata.set('DEPENDENCY', dep1 + dep2) + cdata.set('LIBTYPE', libtype) + cdata.set('VALUE', libret) + + lib_c = configure_file(input : 'lib.c.in', + output : name + '-lib.c', + configuration : cdata) + dep = get_variable(dep1 + dep2 + 'dep') + dep3_lib = build_target(name, lib_c, link_with : dep, target_type : target) + dep3_libs += [dep3_lib] + + main_c = configure_file(input : 'main.c.in', + output : name + '-main.c', + configuration : cdata) + dep3_bin = executable(name, main_c, link_with : dep3_lib) + test(name + 'test', dep3_bin) + endforeach + endforeach +endforeach diff --git a/test cases/common/153 recursive linking/lib.h b/test cases/common/153 recursive linking/lib.h new file mode 100644 index 000000000..b6b75fa05 --- /dev/null +++ b/test cases/common/153 recursive linking/lib.h @@ -0,0 +1,12 @@ +#if defined _WIN32 + #define SYMBOL_IMPORT __declspec(dllimport) + #define SYMBOL_EXPORT __declspec(dllexport) +#else + #define SYMBOL_IMPORT + #if defined __GNUC__ + #define SYMBOL_EXPORT __attribute__ ((visibility("default"))) + #else + #pragma message ("Compiler does not support symbol visibility.") + #define SYMBOL_EXPORT + #endif +#endif diff --git a/test cases/common/153 recursive linking/main.c b/test cases/common/153 recursive linking/main.c new file mode 100644 index 000000000..f1219a649 --- /dev/null +++ b/test cases/common/153 recursive linking/main.c @@ -0,0 +1,46 @@ +#include + +#include "lib.h" + +SYMBOL_IMPORT int get_stnodep_value (void); +SYMBOL_IMPORT int get_shnodep_value (void); +SYMBOL_IMPORT int get_shshdep_value (void); +SYMBOL_IMPORT int get_shstdep_value (void); +SYMBOL_IMPORT int get_stshdep_value (void); +SYMBOL_IMPORT int get_ststdep_value (void); + +int main(int argc, char *argv[]) { + int val; + + val = get_shnodep_value (); + if (val != 1) { + printf("shnodep was %i instead of 1\n", val); + return -1; + } + val = get_stnodep_value (); + if (val != 2) { + printf("stnodep was %i instead of 2\n", val); + return -2; + } + val = get_shshdep_value (); + if (val != 1) { + printf("shshdep was %i instead of 1\n", val); + return -3; + } + val = get_shstdep_value (); + if (val != 2) { + printf("shstdep was %i instead of 2\n", val); + return -4; + } + val = get_stshdep_value (); + if (val != 1) { + printf("shstdep was %i instead of 1\n", val); + return -5; + } + val = get_ststdep_value (); + if (val != 2) { + printf("ststdep was %i instead of 2\n", val); + return -6; + } + return 0; +} diff --git a/test cases/common/153 recursive linking/meson.build b/test cases/common/153 recursive linking/meson.build new file mode 100644 index 000000000..f17fc4a6e --- /dev/null +++ b/test cases/common/153 recursive linking/meson.build @@ -0,0 +1,22 @@ +project('recursive dependencies', 'c') + +# Test that you can link a shared executable to: +# - A shared library with no other deps +subdir('shnodep') +# - A static library with no other deps +subdir('stnodep') +# - A shared library with a shared library dep +subdir('shshdep') +# - A shared library with a static library dep +subdir('shstdep') +# - A static library with a shared library dep +subdir('stshdep') +# - A static library with a static library dep +subdir('ststdep') + +test('alldeps', + executable('alldeps', 'main.c', + link_with : [shshdep, shstdep, ststdep, stshdep])) + +# More combinations of static and shared libraries +subdir('3rdorderdeps') diff --git a/test cases/common/153 recursive linking/shnodep/lib.c b/test cases/common/153 recursive linking/shnodep/lib.c new file mode 100644 index 000000000..a3b7993c2 --- /dev/null +++ b/test cases/common/153 recursive linking/shnodep/lib.c @@ -0,0 +1,6 @@ +#include "../lib.h" + +SYMBOL_EXPORT +int get_shnodep_value (void) { + return 1; +} diff --git a/test cases/common/153 recursive linking/shnodep/meson.build b/test cases/common/153 recursive linking/shnodep/meson.build new file mode 100644 index 000000000..796f0ddcb --- /dev/null +++ b/test cases/common/153 recursive linking/shnodep/meson.build @@ -0,0 +1 @@ +shnodep = shared_library('shnodep', 'lib.c') diff --git a/test cases/common/153 recursive linking/shshdep/lib.c b/test cases/common/153 recursive linking/shshdep/lib.c new file mode 100644 index 000000000..715d12092 --- /dev/null +++ b/test cases/common/153 recursive linking/shshdep/lib.c @@ -0,0 +1,8 @@ +#include "../lib.h" + +int get_shnodep_value (void); + +SYMBOL_EXPORT +int get_shshdep_value (void) { + return get_shnodep_value (); +} diff --git a/test cases/common/153 recursive linking/shshdep/meson.build b/test cases/common/153 recursive linking/shshdep/meson.build new file mode 100644 index 000000000..020b481cf --- /dev/null +++ b/test cases/common/153 recursive linking/shshdep/meson.build @@ -0,0 +1 @@ +shshdep = shared_library('shshdep', 'lib.c', link_with : shnodep) diff --git a/test cases/common/153 recursive linking/shstdep/lib.c b/test cases/common/153 recursive linking/shstdep/lib.c new file mode 100644 index 000000000..5da8d0b2e --- /dev/null +++ b/test cases/common/153 recursive linking/shstdep/lib.c @@ -0,0 +1,8 @@ +#include "../lib.h" + +int get_stnodep_value (void); + +SYMBOL_EXPORT +int get_shstdep_value (void) { + return get_stnodep_value (); +} diff --git a/test cases/common/153 recursive linking/shstdep/meson.build b/test cases/common/153 recursive linking/shstdep/meson.build new file mode 100644 index 000000000..008f9f893 --- /dev/null +++ b/test cases/common/153 recursive linking/shstdep/meson.build @@ -0,0 +1 @@ +shstdep = shared_library('shstdep', 'lib.c', link_with : stnodep) diff --git a/test cases/common/153 recursive linking/stnodep/lib.c b/test cases/common/153 recursive linking/stnodep/lib.c new file mode 100644 index 000000000..4bc50bea2 --- /dev/null +++ b/test cases/common/153 recursive linking/stnodep/lib.c @@ -0,0 +1,6 @@ +#include "../lib.h" + +SYMBOL_EXPORT +int get_stnodep_value (void) { + return 2; +} diff --git a/test cases/common/153 recursive linking/stnodep/meson.build b/test cases/common/153 recursive linking/stnodep/meson.build new file mode 100644 index 000000000..0334f23ca --- /dev/null +++ b/test cases/common/153 recursive linking/stnodep/meson.build @@ -0,0 +1 @@ +stnodep = static_library('stnodep', 'lib.c') diff --git a/test cases/common/153 recursive linking/stshdep/lib.c b/test cases/common/153 recursive linking/stshdep/lib.c new file mode 100644 index 000000000..3cfa12bcb --- /dev/null +++ b/test cases/common/153 recursive linking/stshdep/lib.c @@ -0,0 +1,8 @@ +#include "../lib.h" + +int get_shnodep_value (void); + +SYMBOL_EXPORT +int get_stshdep_value (void) { + return get_shnodep_value (); +} diff --git a/test cases/common/153 recursive linking/stshdep/meson.build b/test cases/common/153 recursive linking/stshdep/meson.build new file mode 100644 index 000000000..7e8e7c82b --- /dev/null +++ b/test cases/common/153 recursive linking/stshdep/meson.build @@ -0,0 +1 @@ +stshdep = static_library('stshdep', 'lib.c', link_with : shnodep) diff --git a/test cases/common/153 recursive linking/ststdep/lib.c b/test cases/common/153 recursive linking/ststdep/lib.c new file mode 100644 index 000000000..fca870669 --- /dev/null +++ b/test cases/common/153 recursive linking/ststdep/lib.c @@ -0,0 +1,8 @@ +#include "../lib.h" + +int get_stnodep_value (void); + +SYMBOL_EXPORT +int get_ststdep_value (void) { + return get_stnodep_value (); +} diff --git a/test cases/common/153 recursive linking/ststdep/meson.build b/test cases/common/153 recursive linking/ststdep/meson.build new file mode 100644 index 000000000..92b0230a7 --- /dev/null +++ b/test cases/common/153 recursive linking/ststdep/meson.build @@ -0,0 +1 @@ +ststdep = static_library('ststdep', 'lib.c', link_with : stnodep) diff --git a/test cases/frameworks/7 gnome/gir/meson.build b/test cases/frameworks/7 gnome/gir/meson.build index f3a453433..27585410c 100644 --- a/test cases/frameworks/7 gnome/gir/meson.build +++ b/test cases/frameworks/7 gnome/gir/meson.build @@ -12,7 +12,7 @@ girlib = shared_library( girexe = executable( 'girprog', sources : 'prog.c', - dependencies : [glib, gobj, gir], + dependencies : [glib, gobj, gir, dep1_dep], link_with : girlib ) diff --git a/test cases/vala/11 generated vapi/meson.build b/test cases/vala/11 generated vapi/meson.build index 82f0c44e5..d5f38cad6 100644 --- a/test cases/vala/11 generated vapi/meson.build +++ b/test cases/vala/11 generated vapi/meson.build @@ -6,7 +6,7 @@ subdir('libbar') vapiexe = executable('vapigen-test', 'main.vala', - dependencies: [dependency('gobject-2.0'), libbar_vapi], + dependencies: [dependency('gobject-2.0'), libfoo_vapi, libbar_vapi], install: true, )