Preserve -L -l pairings fetched from external deps

While adding link args for external deps, sometimes different
libraries come from different prefixes, and an older version of the
same library might be present in other prefixes and we don't want to
accidentally pick that up.

For example:

/usr/local/lib/libglib-2.0.so
/usr/local/lib/pkgconfig/glib-2.0.pc
/usr/local/lib/libz.so
/usr/local/lib/pkgconfig/zlib.pc
/home/mesonuser/.local/lib/libglib-2.0.so
/home/mesonuser/.local/lib/pkgconfig/glib-2.0.pc

PKG_CONFIG_PATH="/home/mesonuser/.local/lib/pkgconfig/:/usr/local/lib/pkgconfig/"

If a target uses `dependencies : [glib_dep, zlib_dep]`, it will end up
using /usr/local/lib/libglib-2.0.so instead of
/home/mesonuser/.local/lib/libglib-2.0.so despite using the pkg-config
file in /home/mesonuser/.local/lib/pkgconfig because we reorder the -L
flag and separate it from the -l flag.

With this change, external link arguments will be added to the
compiler list without de-dup or reordering.

Closes https://github.com/mesonbuild/meson/issues/1718
pull/1932/head
Nirbheek Chauhan 8 years ago
parent f792641b34
commit d23e6b34c7
  1. 6
      mesonbuild/backend/ninjabackend.py
  2. 6
      mesonbuild/backend/vs2010backend.py
  3. 13
      mesonbuild/compilers.py
  4. 10
      run_unittests.py

@ -2294,11 +2294,13 @@ rule FORTRAN_DEP_HACK
commands += target.link_args commands += target.link_args
# External deps must be last because target link libraries may depend on them. # External deps must be last because target link libraries may depend on them.
for dep in target.get_external_deps(): for dep in target.get_external_deps():
commands += dep.get_link_args() # 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())
for d in target.get_dependencies(): for d in target.get_dependencies():
if isinstance(d, build.StaticLibrary): if isinstance(d, build.StaticLibrary):
for dep in d.get_external_deps(): for dep in d.get_external_deps():
commands += dep.get_link_args() commands.extend_direct(dep.get_link_args())
# Add link args for c_* or cpp_* build options. Currently this only # Add link args for c_* or cpp_* build options. Currently this only
# adds c_winlibs and cpp_winlibs when building for Windows. This needs # adds c_winlibs and cpp_winlibs when building for Windows. This needs
# to be after all internal and external libraries so that unresolved # to be after all internal and external libraries so that unresolved

@ -908,11 +908,13 @@ class Vs2010Backend(backends.Backend):
extra_link_args += target.link_args extra_link_args += target.link_args
# External deps must be last because target link libraries may depend on them. # External deps must be last because target link libraries may depend on them.
for dep in target.get_external_deps(): for dep in target.get_external_deps():
extra_link_args += dep.get_link_args() # Extend without reordering or de-dup to preserve `-L -l` sets
# https://github.com/mesonbuild/meson/issues/1718
extra_link_args.extend_direct(dep.get_link_args())
for d in target.get_dependencies(): for d in target.get_dependencies():
if isinstance(d, build.StaticLibrary): if isinstance(d, build.StaticLibrary):
for dep in d.get_external_deps(): for dep in d.get_external_deps():
extra_link_args += dep.get_link_args() extra_link_args.extend_direct(dep.get_link_args())
# Add link args for c_* or cpp_* build options. Currently this only # Add link args for c_* or cpp_* build options. Currently this only
# adds c_winlibs and cpp_winlibs when building for Windows. This needs # adds c_winlibs and cpp_winlibs when building for Windows. This needs
# to be after all internal and external libraries so that unresolved # to be after all internal and external libraries so that unresolved

@ -465,6 +465,19 @@ class CompilerArgs(list):
self.insert(i + 1, '-Wl,--end-group') self.insert(i + 1, '-Wl,--end-group')
return self.compiler.unix_args_to_native(self) return self.compiler.unix_args_to_native(self)
def append_direct(self, arg):
'''
Append the specified argument without any reordering or de-dup
'''
super().append(arg)
def extend_direct(self, iterable):
'''
Extend using the elements in the specified iterable without any
reordering or de-dup
'''
super().extend(iterable)
def __add__(self, args): def __add__(self, args):
new = CompilerArgs(self, self.compiler) new = CompilerArgs(self, self.compiler)
new += args new += args

@ -176,6 +176,16 @@ class InternalTests(unittest.TestCase):
l += ['-lbar'] l += ['-lbar']
self.assertEqual(l, ['-Lbardir', '-Lfoodir', '-lfoo', '-lbar']) self.assertEqual(l, ['-Lbardir', '-Lfoodir', '-lfoo', '-lbar'])
## Test that 'direct' append and extend works
l = cargsfunc(c, ['-Lfoodir', '-lfoo'])
self.assertEqual(l, ['-Lfoodir', '-lfoo'])
# Direct-adding a library and a libpath appends both correctly
l.extend_direct(['-Lbardir', '-lbar'])
self.assertEqual(l, ['-Lfoodir', '-lfoo', '-Lbardir', '-lbar'])
# Direct-adding the same library again still adds it
l.append_direct('-lbar')
self.assertEqual(l, ['-Lfoodir', '-lfoo', '-Lbardir', '-lbar', '-lbar'])
def test_commonpath(self): def test_commonpath(self):
from os.path import sep from os.path import sep
commonpath = mesonbuild.mesonlib.commonpath commonpath = mesonbuild.mesonlib.commonpath

Loading…
Cancel
Save