diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2018-12-06 00:44:47 +0200 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2018-12-06 16:20:54 +0200 |
commit | c44a5a1aeca638f46b4a2d8d4a9fcb0a554037df (patch) | |
tree | 71c4fd88e2fdd98dfd61d8c3f539999ea22a658b | |
parent | 4db1b3a09f8e1f9faf7747beca2bc77ae0e5a6a5 (diff) | |
download | meson-c44a5a1aeca638f46b4a2d8d4a9fcb0a554037df.zip meson-c44a5a1aeca638f46b4a2d8d4a9fcb0a554037df.tar.gz meson-c44a5a1aeca638f46b4a2d8d4a9fcb0a554037df.tar.bz2 |
Deduplicate export-dynamic and pthread. Closes #4567.
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 4 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 16 | ||||
-rwxr-xr-x | run_unittests.py | 28 | ||||
-rw-r--r-- | test cases/unit/49 ldflagdedup/bob.c | 5 | ||||
-rw-r--r-- | test cases/unit/49 ldflagdedup/meson.build | 12 | ||||
-rw-r--r-- | test cases/unit/49 ldflagdedup/prog.c | 7 |
6 files changed, 69 insertions, 3 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 5606c41..f49649b 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2442,7 +2442,7 @@ rule FORTRAN_DEP_HACK%s 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()) + commands.extend_preserving_lflags(dep.get_link_args()) need_threads |= dep.need_threads() need_openmp |= dep.need_openmp() for d in target.get_dependencies(): @@ -2450,7 +2450,7 @@ rule FORTRAN_DEP_HACK%s for dep in d.get_external_deps(): need_threads |= dep.need_threads() need_openmp |= dep.need_openmp() - commands.extend_direct(dep.get_link_args()) + commands.extend_preserving_lflags(dep.get_link_args()) if need_openmp: commands += linker.openmp_flags() if need_threads: diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 3761433..bdc90da 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -612,7 +612,10 @@ class CompilerArgs(list): dedup2_suffixes = () dedup2_args = () # Arg prefixes and args that must be de-duped by returning 1 - dedup1_prefixes = ('-l', '-Wl,-l') + # + # NOTE: not thorough. A list of potential corner cases can be found in + # https://github.com/mesonbuild/meson/pull/4593#pullrequestreview-182016038 + dedup1_prefixes = ('-l', '-Wl,-l', '-Wl,--export-dynamic') dedup1_suffixes = ('.lib', '.dll', '.so', '.dylib', '.a') # Match a .so of the form path/to/libfoo.so.0.1.0 # Only UNIX shared libraries require this. Others have a fixed extension. @@ -748,6 +751,17 @@ class CompilerArgs(list): for elem in iterable: self.append_direct(elem) + def extend_preserving_lflags(self, iterable): + normal_flags = [] + lflags = [] + for i in iterable: + if i.startswith('-l') or i.startswith('-L'): + lflags.append(i) + else: + normal_flags.append(i) + self.extend(normal_flags) + self.extend_direct(lflags) + def __add__(self, args): new = CompilerArgs(self, self.compiler) new += args diff --git a/run_unittests.py b/run_unittests.py index cbd031a..4810264 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -118,6 +118,21 @@ def skipIfNoPkgconfig(f): return f(*args, **kwargs) return wrapped +def skipIfNoPkgconfigDep(depname): + ''' + Skip this test if the given pkg-config dep is not found, unless we're on CI. + ''' + def wrapper(func): + @functools.wraps(func) + def wrapped(*args, **kwargs): + if not is_ci() and shutil.which('pkg-config') is None: + raise unittest.SkipTest('pkg-config not found') + if not is_ci() and subprocess.call(['pkg-config', '--exists', depname]) != 0: + raise unittest.SkipTest('pkg-config dependency {} not found.'.format(depname)) + return func(*args, **kwargs) + return wrapped + return wrapper + def skip_if_not_language(lang): def wrapper(func): @functools.wraps(func) @@ -4393,6 +4408,19 @@ endian = 'little' def test_install_subdir_symlinks_with_default_umask_and_mode(self): self.install_subdir_invalid_symlinks('196 install_mode', 'sub1') + @skipIfNoPkgconfigDep('gmodule-2.0') + def test_ldflag_dedup(self): + testdir = os.path.join(self.unit_test_dir, '49 ldflagdedup') + if is_cygwin() or is_osx(): + raise unittest.SkipTest('Not applicable on Cygwin or OSX.') + self.init(testdir) + build_ninja = os.path.join(self.builddir, 'build.ninja') + max_count = 0 + search_term = '-Wl,--export-dynamic' + with open(build_ninja, 'r', encoding='utf-8') as f: + for line in f: + max_count = max(max_count, line.count(search_term)) + self.assertEqual(max_count, 1, 'Export dynamic incorrectly deduplicated.') class LinuxCrossArmTests(BasePlatformTests): ''' diff --git a/test cases/unit/49 ldflagdedup/bob.c b/test cases/unit/49 ldflagdedup/bob.c new file mode 100644 index 0000000..a68d4b1 --- /dev/null +++ b/test cases/unit/49 ldflagdedup/bob.c @@ -0,0 +1,5 @@ +#include<gmodule.h> + +int func() { + return 0; +} diff --git a/test cases/unit/49 ldflagdedup/meson.build b/test cases/unit/49 ldflagdedup/meson.build new file mode 100644 index 0000000..0bbcc50 --- /dev/null +++ b/test cases/unit/49 ldflagdedup/meson.build @@ -0,0 +1,12 @@ +project('lddedup', 'c') + +# Chosen because its ldflags contains -Wl,--export-dynamic, +# which must be deduplicated. +gm = dependency('gmodule-2.0') + +lib = static_library('bob', 'bob.c', + dependencies: gm) + +executable('prog', 'prog.c', + link_with: lib, + dependencies: gm) diff --git a/test cases/unit/49 ldflagdedup/prog.c b/test cases/unit/49 ldflagdedup/prog.c new file mode 100644 index 0000000..02c599d --- /dev/null +++ b/test cases/unit/49 ldflagdedup/prog.c @@ -0,0 +1,7 @@ +#include<gmodule.h> + +int func(); + +int main(int argc, char **argv) { + return func(); +} |