diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2018-08-08 04:31:09 +0530 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek.chauhan@gmail.com> | 2018-08-11 04:16:18 -0700 |
commit | ae5ebd258f45cbca94197c8d380628095680544d (patch) | |
tree | 84547775db7b037c73b160db0191e61bef718958 | |
parent | 9ddc305e0727f5c89a61459c15325b31bf88f7da (diff) | |
download | meson-ae5ebd258f45cbca94197c8d380628095680544d.zip meson-ae5ebd258f45cbca94197c8d380628095680544d.tar.gz meson-ae5ebd258f45cbca94197c8d380628095680544d.tar.bz2 |
PkgConfigDependency: Don't try to resolve internal compiler libs
-lc -lm -ldl -lrt -lpthread are special linker arguments that should
never be resolved to on-disk libraries.
Closes https://github.com/mesonbuild/meson/issues/3879
-rw-r--r-- | mesonbuild/compilers/c.py | 11 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 3 | ||||
-rw-r--r-- | mesonbuild/dependencies/base.py | 12 | ||||
-rwxr-xr-x | run_unittests.py | 25 |
4 files changed, 43 insertions, 8 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 2530adf..2dfe794 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -47,11 +47,14 @@ from .compilers import ( RunResult, ) +gnu_compiler_internal_libs = ('m', 'c', 'pthread', 'dl', 'rt') + class CCompiler(Compiler): library_dirs_cache = {} program_dirs_cache = {} find_library_cache = {} + internal_libs = gnu_compiler_internal_libs def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs): # If a child ObjC or CPP class has already set it, don't set it ourselves @@ -905,10 +908,13 @@ class CCompiler(Compiler): # First try if we can just add the library as -l. # Gcc + co seem to prefer builtin lib dirs to -L dirs. # Only try to find std libs if no extra dirs specified. - if not extra_dirs: + if not extra_dirs or libname in self.internal_libs: args = ['-l' + libname] if self.links(code, env, extra_args=args): return args + # Don't do a manual search for internal libs + if libname in self.internal_libs: + return None # Not found or we want to use a specific libtype? Try to find the # library file itself. patterns = self.get_library_naming(env, libtype) @@ -1188,7 +1194,8 @@ class IntelCCompiler(IntelCompiler, CCompiler): class VisualStudioCCompiler(CCompiler): std_warn_args = ['/W3'] std_opt_args = ['/O2'] - ignore_libs = ('m', 'c', 'pthread') + ignore_libs = gnu_compiler_internal_libs + internal_libs = () def __init__(self, exelist, version, is_cross, exe_wrap, is_64): CCompiler.__init__(self, exelist, version, is_cross, exe_wrap) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 25835a3..cb3ed23 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -661,6 +661,9 @@ class Compiler: # Libraries to ignore in find_library() since they are provided by the # compiler or the C library. Currently only used for MSVC. ignore_libs = () + # Libraries that are internal compiler implementations, and must not be + # manually searched. + internal_libs = () # Cache for the result of compiler checks which can be cached compiler_check_cache = {} diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index b9a6c6f..45ff96b 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -623,12 +623,16 @@ class PkgConfigDependency(ExternalDependency): # arguments as-is and then adding the libpaths at the end. else: args = None - if args: + if args is not None: libs_found.add(lib) # Replace -l arg with full path to library if available - # else, library is provided by the compiler and can't be resolved - if not args[0].startswith('-l'): - lib = args[0] + # else, library is either to be ignored, or is provided by + # the compiler, can't be resolved, and should be used as-is + if args: + if not args[0].startswith('-l'): + lib = args[0] + else: + continue else: # Library wasn't found, maybe we're looking in the wrong # places or the library will be provided with LDFLAGS or diff --git a/run_unittests.py b/run_unittests.py index e0f2fe5..efb69ad 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -51,11 +51,15 @@ from run_tests import get_builddir_target_args, get_backend_commands, Backend from run_tests import ensure_backend_detects_changes, run_configure_inprocess from run_tests import run_mtest_inprocess -# Fake class for mocking +# Fake classes for mocking class FakeBuild: def __init__(self, env): self.environment = env +class FakeCompilerOptions: + def __init__(self): + self.value = [] + def get_dynamic_section_entry(fname, entry): if is_cygwin() or is_osx(): raise unittest.SkipTest('Test only applicable to ELF platforms') @@ -605,6 +609,7 @@ class InternalTests(unittest.TestCase): env = Environment('', '', get_fake_options('')) compiler = env.detect_c_compiler(False) env.coredata.compilers = {'c': compiler} + env.coredata.compiler_options['c_link_args'] = FakeCompilerOptions() p1 = Path(tmpdir) / '1' p2 = Path(tmpdir) / '2' p1.mkdir() @@ -614,6 +619,12 @@ class InternalTests(unittest.TestCase): # libbar.a is in both prefixes (p1 / 'libbar.a').open('w').close() (p2 / 'libbar.a').open('w').close() + # Ensure that we never statically link to these + (p1 / 'libpthread.a').open('w').close() + (p1 / 'libm.a').open('w').close() + (p1 / 'libc.a').open('w').close() + (p1 / 'libdl.a').open('w').close() + (p1 / 'librt.a').open('w').close() def fake_call_pkgbin(self, args, env=None): if '--libs' not in args: @@ -622,6 +633,8 @@ class InternalTests(unittest.TestCase): return 0, '-L{} -lfoo -L{} -lbar'.format(p1.as_posix(), p2.as_posix()) if args[0] == 'bar': return 0, '-L{} -lbar'.format(p2.as_posix()) + if args[0] == 'internal': + return 0, '-L{} -lpthread -lm -lc -lrt -ldl'.format(p1.as_posix()) old_call = PkgConfigDependency._call_pkgbin old_check = PkgConfigDependency.check_pkgconfig @@ -634,6 +647,14 @@ class InternalTests(unittest.TestCase): [(p1 / 'libfoo.a').as_posix(), (p2 / 'libbar.a').as_posix()]) bar_dep = PkgConfigDependency('bar', env, kwargs) self.assertEqual(bar_dep.get_link_args(), [(p2 / 'libbar.a').as_posix()]) + internal_dep = PkgConfigDependency('internal', env, kwargs) + if compiler.get_id() == 'msvc': + self.assertEqual(internal_dep.get_link_args(), []) + else: + link_args = internal_dep.get_link_args() + for link_arg in link_args: + for lib in ('pthread', 'm', 'c', 'dl', 'rt'): + self.assertNotIn('lib{}.a'.format(lib), link_arg, msg=link_args) # Test ends PkgConfigDependency._call_pkgbin = old_call PkgConfigDependency.check_pkgconfig = old_check @@ -2797,7 +2818,7 @@ class WindowsTests(BasePlatformTests): if cc.id != 'msvc': raise unittest.SkipTest('Not using MSVC') # To force people to update this test, and also test - self.assertEqual(set(cc.ignore_libs), {'c', 'm', 'pthread'}) + self.assertEqual(set(cc.ignore_libs), {'c', 'm', 'pthread', 'dl', 'rt'}) for l in cc.ignore_libs: self.assertEqual(cc.find_library(l, env, []), []) |