diff options
Diffstat (limited to 'mesonbuild/linkers/linkers.py')
-rw-r--r-- | mesonbuild/linkers/linkers.py | 118 |
1 files changed, 64 insertions, 54 deletions
diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index 59f60e0..c528db7 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -65,9 +65,8 @@ class StaticLinker: def get_coverage_link_args(self) -> T.List[str]: return [] - def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, - rpath_paths: T.Tuple[str, ...], build_rpath: str, - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: + def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str, + target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: return ([], set()) def thread_link_flags(self, env: 'Environment') -> T.List[str]: @@ -297,9 +296,8 @@ class DynamicLinker(metaclass=abc.ABCMeta): def bitcode_args(self) -> T.List[str]: raise MesonException('This linker does not support bitcode bundles') - def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, - rpath_paths: T.Tuple[str, ...], build_rpath: str, - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: + def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str, + target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: return ([], set()) def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str, @@ -703,13 +701,13 @@ class GnuLikeDynamicLinkerMixin(DynamicLinkerBase): sostr = '' if soversion is None else '.' + soversion return self._apply_prefix(f'-soname,{prefix}{shlib_name}.{suffix}{sostr}') - def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, - rpath_paths: T.Tuple[str, ...], build_rpath: str, - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: + def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str, + target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: m = env.machines[self.for_machine] if m.is_windows() or m.is_cygwin(): return ([], set()) - if not rpath_paths and not install_rpath and not build_rpath: + rpath_paths = target.determine_rpath_dirs() + if not rpath_paths and not target.install_rpath and not target.build_rpath and not extra_paths: return ([], set()) args: T.List[str] = [] origin_placeholder = '$ORIGIN' @@ -722,10 +720,12 @@ class GnuLikeDynamicLinkerMixin(DynamicLinkerBase): for p in all_paths: rpath_dirs_to_remove.add(p.encode('utf8')) # Build_rpath is used as-is (it is usually absolute). - if build_rpath != '': - all_paths.add(build_rpath) - for p in build_rpath.split(':'): + if target.build_rpath != '': + all_paths.add(target.build_rpath) + for p in target.build_rpath.split(':'): rpath_dirs_to_remove.add(p.encode('utf8')) + if extra_paths: + all_paths.update(extra_paths) # TODO: should this actually be "for (dragonfly|open)bsd"? if mesonlib.is_dragonflybsd() or mesonlib.is_openbsd(): @@ -740,7 +740,7 @@ class GnuLikeDynamicLinkerMixin(DynamicLinkerBase): # enough space in the ELF header to hold the final installation RPATH. paths = ':'.join(all_paths) paths_length = len(paths.encode('utf-8')) - install_rpath_length = len(install_rpath.encode('utf-8')) + install_rpath_length = len(target.install_rpath.encode('utf-8')) if paths_length < install_rpath_length: padding = 'X' * (install_rpath_length - paths_length) if not paths: @@ -873,10 +873,10 @@ class AppleDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): '-current_version', darwin_versions[1]]) return args - def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, - rpath_paths: T.Tuple[str, ...], build_rpath: str, - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: - if not rpath_paths and not install_rpath and not build_rpath: + def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str, + target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: + rpath_paths = target.determine_rpath_dirs() + if not rpath_paths and not target.install_rpath and not target.build_rpath and not extra_paths: return ([], set()) args: T.List[str] = [] rpath_dirs_to_remove: T.Set[bytes] = set() @@ -885,8 +885,10 @@ class AppleDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): origin_placeholder = '@loader_path' processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths]) - if build_rpath != '': - all_paths.update(build_rpath.split(':')) + if target.build_rpath != '': + all_paths.update(target.build_rpath.split(':')) + if extra_paths: + all_paths.update(extra_paths) for rp in all_paths: rpath_dirs_to_remove.add(rp.encode('utf8')) args.extend(self._apply_prefix('-rpath,' + rp)) @@ -1022,9 +1024,8 @@ class WASMDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, Dyna def get_asneeded_args(self) -> T.List[str]: return [] - def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, - rpath_paths: T.Tuple[str, ...], build_rpath: str, - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: + def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str, + target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: return ([], set()) @@ -1100,9 +1101,8 @@ class Xc16DynamicLinker(DynamicLinker): suffix: str, soversion: str, darwin_versions: T.Tuple[str, str]) -> T.List[str]: return [] - def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, - rpath_paths: T.Tuple[str, ...], build_rpath: str, - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: + def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str, + target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: return ([], set()) class CompCertDynamicLinker(DynamicLinker): @@ -1143,9 +1143,8 @@ class CompCertDynamicLinker(DynamicLinker): suffix: str, soversion: str, darwin_versions: T.Tuple[str, str]) -> T.List[str]: raise MesonException(f'{self.id} does not support shared libraries.') - def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, - rpath_paths: T.Tuple[str, ...], build_rpath: str, - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: + def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str, + target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: return ([], set()) class TIDynamicLinker(DynamicLinker): @@ -1235,6 +1234,12 @@ class QualcommLLVMDynamicLinker(LLVMDynamicLinker): id = 'ld.qcld' +class ELDDynamicLinker(GnuLikeDynamicLinkerMixin, PosixDynamicLinkerMixin, DynamicLinker): + + """Qualcomm's opensource embedded linker""" + + id = 'ld.eld' + class NAGDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): @@ -1249,17 +1254,19 @@ class NAGDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): id = 'nag' - def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, - rpath_paths: T.Tuple[str, ...], build_rpath: str, - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: - if not rpath_paths and not install_rpath and not build_rpath: + def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str, + target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: + rpath_paths = target.determine_rpath_dirs() + if not rpath_paths and not target.install_rpath and not target.build_rpath and not extra_paths: return ([], set()) args: T.List[str] = [] origin_placeholder = '$ORIGIN' processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths]) - if build_rpath != '': - all_paths.add(build_rpath) + if target.build_rpath != '': + all_paths.add(target.build_rpath) + if extra_paths: + all_paths.update(extra_paths) for rp in all_paths: args.extend(self._apply_prefix('-Wl,-Wl,,-rpath,,' + rp)) @@ -1294,10 +1301,10 @@ class PGIDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): return ['-shared'] return [] - def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, - rpath_paths: T.Tuple[str, ...], build_rpath: str, - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: + def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str, + target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: if not env.machines[self.for_machine].is_windows(): + rpath_paths = target.determine_rpath_dirs() return (['-R' + os.path.join(build_dir, p) for p in rpath_paths], set()) return ([], set()) @@ -1505,26 +1512,28 @@ class SolarisDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): def fatal_warnings(self) -> T.List[str]: return ['-z', 'fatal-warnings'] - def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, - rpath_paths: T.Tuple[str, ...], build_rpath: str, - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: - if not rpath_paths and not install_rpath and not build_rpath: + def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str, + target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: + rpath_paths = target.determine_rpath_dirs() + if not rpath_paths and not target.install_rpath and not target.build_rpath and not extra_paths: return ([], set()) processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) all_paths = mesonlib.OrderedSet([os.path.join('$ORIGIN', p) for p in processed_rpaths]) rpath_dirs_to_remove: T.Set[bytes] = set() for p in all_paths: rpath_dirs_to_remove.add(p.encode('utf8')) - if build_rpath != '': - all_paths.add(build_rpath) - for p in build_rpath.split(':'): + if target.build_rpath != '': + all_paths.add(target.build_rpath) + for p in target.build_rpath.split(':'): rpath_dirs_to_remove.add(p.encode('utf8')) + if extra_paths: + all_paths.update(extra_paths) # In order to avoid relinking for RPATH removal, the binary needs to contain just # enough space in the ELF header to hold the final installation RPATH. paths = ':'.join(all_paths) paths_length = len(paths.encode('utf-8')) - install_rpath_length = len(install_rpath.encode('utf-8')) + install_rpath_length = len(target.install_rpath.encode('utf-8')) if paths_length < install_rpath_length: padding = 'X' * (install_rpath_length - paths_length) if not paths: @@ -1575,16 +1584,15 @@ class AIXDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): # archives or not." return args - def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, - rpath_paths: T.Tuple[str, ...], build_rpath: str, - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: + def build_rpath_args(self, env: Environment, build_dir: str, from_dir: str, + target: BuildTarget, extra_paths: T.Optional[T.List[str]] = None) -> T.Tuple[T.List[str], T.Set[bytes]]: all_paths: mesonlib.OrderedSet[str] = mesonlib.OrderedSet() # install_rpath first, followed by other paths, and the system path last - if install_rpath != '': - all_paths.add(install_rpath) - if build_rpath != '': - all_paths.add(build_rpath) - for p in rpath_paths: + if target.install_rpath != '': + all_paths.add(target.install_rpath) + if target.build_rpath != '': + all_paths.add(target.build_rpath) + for p in target.determine_rpath_dirs(): all_paths.add(os.path.join(build_dir, p)) # We should consider allowing the $LIBPATH environment variable # to override sys_path. @@ -1598,6 +1606,8 @@ class AIXDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): for p in sys_path: if os.path.isdir(p): all_paths.add(p) + if extra_paths: + all_paths.update(extra_paths) return (self._apply_prefix('-blibpath:' + ':'.join(all_paths)), set()) def thread_flags(self, env: 'Environment') -> T.List[str]: |