diff options
Diffstat (limited to 'mesonbuild/linkers')
-rw-r--r-- | mesonbuild/linkers/detect.py | 7 | ||||
-rw-r--r-- | mesonbuild/linkers/linkers.py | 118 |
2 files changed, 69 insertions, 56 deletions
diff --git a/mesonbuild/linkers/detect.py b/mesonbuild/linkers/detect.py index ee9bb08..6fbe6e4 100644 --- a/mesonbuild/linkers/detect.py +++ b/mesonbuild/linkers/detect.py @@ -39,7 +39,7 @@ def guess_win_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty use_linker_prefix: bool = True, invoked_directly: bool = True, extra_args: T.Optional[T.List[str]] = None) -> 'DynamicLinker': from . import linkers - env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env) + env.add_lang_args(comp_class.language, comp_class, for_machine) if invoked_directly or comp_class.get_argument_syntax() == 'msvc': rsp_syntax = RSPFileSyntax.MSVC @@ -128,7 +128,7 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty :extra_args: Any additional arguments required (such as a source file) """ from . import linkers - env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env) + env.add_lang_args(comp_class.language, comp_class, for_machine) extra_args = extra_args or [] system = env.machines[for_machine].system @@ -166,6 +166,9 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty linker = lld_cls( compiler, for_machine, comp_class.LINKER_PREFIX, override, system=system, version=v) + elif o.startswith("eld"): + linker = linkers.ELDDynamicLinker( + compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v) elif 'Snapdragon' in e and 'LLVM' in e: linker = linkers.QualcommLLVMDynamicLinker( compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v) 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]: |