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
This commit is contained in:
parent
6662f36ed3
commit
6963da616b
|
@ -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):
|
||||
|
|
|
@ -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 ();
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,46 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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')
|
|
@ -0,0 +1,6 @@
|
|||
#include "../lib.h"
|
||||
|
||||
SYMBOL_EXPORT
|
||||
int get_shnodep_value (void) {
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
shnodep = shared_library('shnodep', '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 ();
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
shshdep = shared_library('shshdep', 'lib.c', link_with : shnodep)
|
|
@ -0,0 +1,8 @@
|
|||
#include "../lib.h"
|
||||
|
||||
int get_stnodep_value (void);
|
||||
|
||||
SYMBOL_EXPORT
|
||||
int get_shstdep_value (void) {
|
||||
return get_stnodep_value ();
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
shstdep = shared_library('shstdep', 'lib.c', link_with : stnodep)
|
|
@ -0,0 +1,6 @@
|
|||
#include "../lib.h"
|
||||
|
||||
SYMBOL_EXPORT
|
||||
int get_stnodep_value (void) {
|
||||
return 2;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
stnodep = static_library('stnodep', '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 ();
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
stshdep = static_library('stshdep', 'lib.c', link_with : shnodep)
|
|
@ -0,0 +1,8 @@
|
|||
#include "../lib.h"
|
||||
|
||||
int get_stnodep_value (void);
|
||||
|
||||
SYMBOL_EXPORT
|
||||
int get_ststdep_value (void) {
|
||||
return get_stnodep_value ();
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
ststdep = static_library('ststdep', 'lib.c', link_with : stnodep)
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue