You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
5.0 KiB

  1. From 1ce4258c219fe08b6d6eaa6aa944f27d91d054cb Mon Sep 17 00:00:00 2001
  2. From: James Hilliard <james.hilliard1@gmail.com>
  3. Date: Sat, 18 Jul 2020 17:01:33 -0600
  4. Subject: [PATCH] backends: fix rpath match pattern
  5. Since -Wl,-rpath= is not the only valid rpath ldflags syntax we
  6. need to try and match all valid rpath ldflags.
  7. In addition we should prevent -Wl,--just-symbols from being used to
  8. set rpath due to inconsistent compiler support.
  9. Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
  10. ---
  11. mesonbuild/backend/backends.py | 30 ++++++++++++++++++++++++--
  12. run_unittests.py | 39 +++++++++++++++++++++++-----------
  13. 2 files changed, 55 insertions(+), 14 deletions(-)
  14. diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
  15. index cfd3a397fd..e053f67e6b 100644
  16. --- a/mesonbuild/backend/backends.py
  17. +++ b/mesonbuild/backend/backends.py
  18. @@ -14,6 +14,7 @@
  19. from collections import OrderedDict
  20. from functools import lru_cache
  21. +from pathlib import Path
  22. import enum
  23. import json
  24. import os
  25. @@ -455,10 +456,35 @@ def get_external_rpath_dirs(self, target):
  26. args.extend(self.environment.coredata.get_external_link_args(target.for_machine, lang))
  27. except Exception:
  28. pass
  29. + # Match rpath formats:
  30. + # -Wl,-rpath=
  31. + # -Wl,-rpath,
  32. + rpath_regex = re.compile(r'-Wl,-rpath[=,]([^,]+)')
  33. + # Match solaris style compat runpath formats:
  34. + # -Wl,-R
  35. + # -Wl,-R,
  36. + runpath_regex = re.compile(r'-Wl,-R[,]?([^,]+)')
  37. + # Match symbols formats:
  38. + # -Wl,--just-symbols=
  39. + # -Wl,--just-symbols,
  40. + symbols_regex = re.compile(r'-Wl,--just-symbols[=,]([^,]+)')
  41. for arg in args:
  42. - if arg.startswith('-Wl,-rpath='):
  43. - for dir in arg.replace('-Wl,-rpath=','').split(':'):
  44. + rpath_match = rpath_regex.match(arg)
  45. + if rpath_match:
  46. + for dir in rpath_match.group(1).split(':'):
  47. dirs.add(dir)
  48. + runpath_match = runpath_regex.match(arg)
  49. + if runpath_match:
  50. + for dir in runpath_match.group(1).split(':'):
  51. + # The symbols arg is an rpath if the path is a directory
  52. + if Path(dir).is_dir():
  53. + dirs.add(dir)
  54. + symbols_match = symbols_regex.match(arg)
  55. + if symbols_match:
  56. + for dir in symbols_match.group(1).split(':'):
  57. + # Prevent usage of --just-symbols to specify rpath
  58. + if Path(dir).is_dir():
  59. + raise MesonException('Invalid arg for --just-symbols, {} is a directory.'.format(dir))
  60. return dirs
  61. def rpaths_for_bundled_shared_libraries(self, target, exclude_system=True):
  62. diff --git a/run_unittests.py b/run_unittests.py
  63. index b5294b9f82..73131c75b7 100755
  64. --- a/run_unittests.py
  65. +++ b/run_unittests.py
  66. @@ -6451,19 +6451,34 @@ def test_global_rpath(self):
  67. self.init(yonder_dir)
  68. self.build()
  69. self.install(use_destdir=False)
  70. - self.new_builddir()
  71. - # Build an app that uses that installed library.
  72. - # Supply the rpath to the installed library via LDFLAGS
  73. - # (as systems like buildroot and guix are wont to do)
  74. - # and verify install preserves that rpath.
  75. - env = {'LDFLAGS': '-Wl,-rpath=' + yonder_libdir,
  76. - 'PKG_CONFIG_PATH': os.path.join(yonder_libdir, 'pkgconfig')}
  77. - self.init(testdir, override_envvars=env)
  78. - self.build()
  79. - self.install(use_destdir=False)
  80. - got_rpath = get_rpath(os.path.join(yonder_prefix, 'bin/rpathified'))
  81. - self.assertEqual(got_rpath, yonder_libdir)
  82. + # Since rpath has multiple valid formats we need to
  83. + # test that they are all properly used.
  84. + rpath_formats = [
  85. + ('-Wl,-rpath=', False),
  86. + ('-Wl,-rpath,', False),
  87. + ('-Wl,--just-symbols=', True),
  88. + ('-Wl,--just-symbols,', True),
  89. + ('-Wl,-R', False),
  90. + ('-Wl,-R,', False)
  91. + ]
  92. + for rpath_format, exception in rpath_formats:
  93. + # Build an app that uses that installed library.
  94. + # Supply the rpath to the installed library via LDFLAGS
  95. + # (as systems like buildroot and guix are wont to do)
  96. + # and verify install preserves that rpath.
  97. + self.new_builddir()
  98. + env = {'LDFLAGS': rpath_format + yonder_libdir,
  99. + 'PKG_CONFIG_PATH': os.path.join(yonder_libdir, 'pkgconfig')}
  100. + if exception:
  101. + with self.assertRaises(subprocess.CalledProcessError):
  102. + self.init(testdir, override_envvars=env)
  103. + break
  104. + self.init(testdir, override_envvars=env)
  105. + self.build()
  106. + self.install(use_destdir=False)
  107. + got_rpath = get_rpath(os.path.join(yonder_prefix, 'bin/rpathified'))
  108. + self.assertEqual(got_rpath, yonder_libdir, rpath_format)
  109. @skip_if_not_base_option('b_sanitize')
  110. def test_pch_with_address_sanitizer(self):