aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/linkers
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/linkers')
-rw-r--r--mesonbuild/linkers/detect.py7
-rw-r--r--mesonbuild/linkers/linkers.py118
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]: