backends: fix rpath match pattern

Since -Wl,-rpath= is not the only valid rpath ldflags syntax we
need to try and match all valid rpath ldflags.

In addition we should prevent -Wl,--just-symbols from being used to
set rpath due to inconsistent compiler support.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
pull/7618/head
James Hilliard 4 years ago committed by Nirbheek Chauhan
parent 9a6824147e
commit a0b1abf634
  1. 30
      mesonbuild/backend/backends.py
  2. 39
      run_unittests.py

@ -14,6 +14,7 @@
from collections import OrderedDict
from functools import lru_cache
from pathlib import Path
import enum
import json
import os
@ -455,10 +456,35 @@ class Backend:
args.extend(self.environment.coredata.get_external_link_args(target.for_machine, lang))
except Exception:
pass
# Match rpath formats:
# -Wl,-rpath=
# -Wl,-rpath,
rpath_regex = re.compile(r'-Wl,-rpath[=,]([^,]+)')
# Match solaris style compat runpath formats:
# -Wl,-R
# -Wl,-R,
runpath_regex = re.compile(r'-Wl,-R[,]?([^,]+)')
# Match symbols formats:
# -Wl,--just-symbols=
# -Wl,--just-symbols,
symbols_regex = re.compile(r'-Wl,--just-symbols[=,]([^,]+)')
for arg in args:
if arg.startswith('-Wl,-rpath='):
for dir in arg.replace('-Wl,-rpath=','').split(':'):
rpath_match = rpath_regex.match(arg)
if rpath_match:
for dir in rpath_match.group(1).split(':'):
dirs.add(dir)
runpath_match = runpath_regex.match(arg)
if runpath_match:
for dir in runpath_match.group(1).split(':'):
# The symbols arg is an rpath if the path is a directory
if Path(dir).is_dir():
dirs.add(dir)
symbols_match = symbols_regex.match(arg)
if symbols_match:
for dir in symbols_match.group(1).split(':'):
# Prevent usage of --just-symbols to specify rpath
if Path(dir).is_dir():
raise MesonException('Invalid arg for --just-symbols, {} is a directory.'.format(dir))
return dirs
def rpaths_for_bundled_shared_libraries(self, target, exclude_system=True):

@ -6469,19 +6469,34 @@ class LinuxlikeTests(BasePlatformTests):
self.init(yonder_dir)
self.build()
self.install(use_destdir=False)
self.new_builddir()
# Build an app that uses that installed library.
# Supply the rpath to the installed library via LDFLAGS
# (as systems like buildroot and guix are wont to do)
# and verify install preserves that rpath.
env = {'LDFLAGS': '-Wl,-rpath=' + yonder_libdir,
'PKG_CONFIG_PATH': os.path.join(yonder_libdir, 'pkgconfig')}
self.init(testdir, override_envvars=env)
self.build()
self.install(use_destdir=False)
got_rpath = get_rpath(os.path.join(yonder_prefix, 'bin/rpathified'))
self.assertEqual(got_rpath, yonder_libdir)
# Since rpath has multiple valid formats we need to
# test that they are all properly used.
rpath_formats = [
('-Wl,-rpath=', False),
('-Wl,-rpath,', False),
('-Wl,--just-symbols=', True),
('-Wl,--just-symbols,', True),
('-Wl,-R', False),
('-Wl,-R,', False)
]
for rpath_format, exception in rpath_formats:
# Build an app that uses that installed library.
# Supply the rpath to the installed library via LDFLAGS
# (as systems like buildroot and guix are wont to do)
# and verify install preserves that rpath.
self.new_builddir()
env = {'LDFLAGS': rpath_format + yonder_libdir,
'PKG_CONFIG_PATH': os.path.join(yonder_libdir, 'pkgconfig')}
if exception:
with self.assertRaises(subprocess.CalledProcessError):
self.init(testdir, override_envvars=env)
break
self.init(testdir, override_envvars=env)
self.build()
self.install(use_destdir=False)
got_rpath = get_rpath(os.path.join(yonder_prefix, 'bin/rpathified'))
self.assertEqual(got_rpath, yonder_libdir, rpath_format)
@skip_if_not_base_option('b_sanitize')
def test_pch_with_address_sanitizer(self):

Loading…
Cancel
Save