Skip to content

Commit

Permalink
Allow selecting the dynamic linker
Browse files Browse the repository at this point in the history
This uses the normal meson mechanisms, an LD environment variable or via
cross/native files.

Fixes: mesonbuild#6057
  • Loading branch information
dcbaker committed Nov 26, 2019
1 parent f71e7d3 commit a524d22
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 77 deletions.
17 changes: 17 additions & 0 deletions docs/markdown/snippets/linker_override.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Generic Overrider for Dynamic Linker selection

Previous to meson 0.52.0 you set the dynamic linker using compiler specific
flags passed via language flags and hoped things worked out. In meson 0.52.0
meson started detecting the linker and making intelligent decisions about
using it. Unfortunately this broke choosing a non-default linker.

Now there is a generic mechanism for doing this, you may use the LD
environment variable (with normal meson environment variable rules), or add
the following to a cross or native file:

```ini
[binaries]
ld = 'gold'
```

And meson will select the linker if possible.
6 changes: 6 additions & 0 deletions mesonbuild/compilers/compilers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,12 @@ def get_dependency_compile_args(self, dep):
def get_dependency_link_args(self, dep):
return dep.get_link_args()

@classmethod
def use_linker_args(cls, linker: str) -> typing.List[str]:
"""Get a list of arguments to pass to the compiler to set the linker.
"""
return []


def get_largefile_args(compiler):
'''
Expand Down
4 changes: 4 additions & 0 deletions mesonbuild/compilers/mixins/gnu.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,10 @@ def get_include_args(self, path: str, is_system: bool) -> typing.List[str]:
return ['-isystem' + path]
return ['-I' + path]

@classmethod
def use_linker_args(cls, linker: str) -> typing.List[str]:
return ['-fuse-ld={}'.format(linker)]


class GnuCompiler(GnuLikeCompiler):
"""
Expand Down
4 changes: 4 additions & 0 deletions mesonbuild/compilers/mixins/visualstudio.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,3 +381,7 @@ def has_func_attribute(self, name: str, env: 'Environment') -> typing.Tuple[bool

def get_argument_syntax(self) -> str:
return 'msvc'

@classmethod
def use_linker_args(cls, linker: str) -> typing.List[str]:
return []
2 changes: 2 additions & 0 deletions mesonbuild/envconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,9 @@ def __init__(
'strip': 'STRIP',
'ar': 'AR',
'windres': 'WINDRES',
'ld': 'LD',

# Other tools
'cmake': 'CMAKE',
'qmake': 'QMAKE',
'pkgconfig': 'PKG_CONFIG',
Expand Down
159 changes: 96 additions & 63 deletions mesonbuild/environment.py

Large diffs are not rendered by default.

28 changes: 16 additions & 12 deletions mesonbuild/linkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,17 +247,21 @@ class DynamicLinker(metaclass=abc.ABCMeta):
} # type: typing.Dict[str, typing.List[str]]

def _apply_prefix(self, arg: str) -> typing.List[str]:
if isinstance(self.prefix_arg, str):
if self.prefix_arg is None:
return [arg]
elif isinstance(self.prefix_arg, str):
return [self.prefix_arg + arg]
return self.prefix_arg + [arg]

def __init__(self, exelist: typing.List[str], for_machine: mesonlib.MachineChoice,
id_: str, prefix_arg: typing.Union[str, typing.List[str]], *, version: str = 'unknown version'):
id_: str, prefix_arg: typing.Union[str, typing.List[str]],
always_args: typing.List[str], *, version: str = 'unknown version'):
self.exelist = exelist
self.for_machine = for_machine
self.version = version
self.id = id_
self.prefix_arg = prefix_arg
self.always_args = always_args

def __repr__(self) -> str:
return '<{}: v{} `{}`>'.format(type(self).__name__, self.version, ' '.join(self.exelist))
Expand All @@ -276,7 +280,7 @@ def get_accepts_rsp(self) -> bool:
return mesonlib.is_windows()

def get_always_args(self) -> typing.List[str]:
return []
return self.always_args.copy()

def get_lib_prefix(self) -> str:
return ''
Expand Down Expand Up @@ -713,7 +717,7 @@ class ArmDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):

def __init__(self, for_machine: mesonlib.MachineChoice,
*, version: str = 'unknown version'):
super().__init__(['armlink'], for_machine, 'armlink', '',
super().__init__(['armlink'], for_machine, 'armlink', '', [],
version=version)

def get_accepts_rsp(self) -> bool:
Expand Down Expand Up @@ -851,33 +855,33 @@ class MSVCDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):

"""Microsoft's Link.exe."""

def __init__(self, for_machine: mesonlib.MachineChoice, *,
def __init__(self, for_machine: mesonlib.MachineChoice, always_args: typing.List[str], *,
exelist: typing.Optional[typing.List[str]] = None,
prefix: typing.Union[str, typing.List[str]] = '',
machine: str = 'x86', version: str = 'unknown version'):
super().__init__(exelist or ['link.exe'], for_machine, 'link',
prefix, machine=machine, version=version)
prefix, always_args, machine=machine, version=version)


class ClangClDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):

"""Clang's lld-link.exe."""

def __init__(self, for_machine: mesonlib.MachineChoice, *,
def __init__(self, for_machine: mesonlib.MachineChoice, always_args: typing.List[str], *,
exelist: typing.Optional[typing.List[str]] = None,
prefix: typing.Union[str, typing.List[str]] = '',
version: str = 'unknown version'):
super().__init__(exelist or ['lld-link.exe'], for_machine,
'lld-link', prefix, version=version)
super().__init__(exelist or ['lld-link.exe'], for_machine, 'lld-link',
prefix, always_args, version=version)


class XilinkDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):

"""Intel's Xilink.exe."""

def __init__(self, for_machine: mesonlib.MachineChoice,
def __init__(self, for_machine: mesonlib.MachineChoice, always_args: typing.List[str],
*, version: str = 'unknown version'):
super().__init__(['xilink.exe'], for_machine, 'xilink', '', version=version)
super().__init__(['xilink.exe'], for_machine, 'xilink', '', always_args, version=version)


class SolarisDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):
Expand Down Expand Up @@ -934,7 +938,7 @@ def __init__(self, for_machine: mesonlib.MachineChoice,
*, version: str = 'unknown version'):
# Use optlink instead of link so we don't interfer with other link.exe
# implementations.
super().__init__(['optlink.exe'], for_machine, 'optlink', prefix_arg='', version=version)
super().__init__(['optlink.exe'], for_machine, 'optlink', '', [], version=version)

def get_allow_undefined_args(self) -> typing.List[str]:
return []
Expand Down
4 changes: 2 additions & 2 deletions run_unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ def test_compiler_args_class(self):
def test_compiler_args_class_gnuld(self):
cargsfunc = mesonbuild.compilers.CompilerArgs
## Test --start/end-group
linker = mesonbuild.linkers.GnuDynamicLinker([], MachineChoice.HOST, 'fake', '-Wl,')
linker = mesonbuild.linkers.GnuDynamicLinker([], MachineChoice.HOST, 'fake', '-Wl,', [])
gcc = mesonbuild.compilers.GnuCCompiler([], 'fake', False, MachineChoice.HOST, mock.Mock(), linker=linker)
## Ensure that the fake compiler is never called by overriding the relevant function
gcc.get_default_include_dirs = lambda: ['/usr/include', '/usr/share/include', '/usr/local/include']
Expand Down Expand Up @@ -474,7 +474,7 @@ def test_compiler_args_class_gnuld(self):
def test_compiler_args_remove_system(self):
cargsfunc = mesonbuild.compilers.CompilerArgs
## Test --start/end-group
linker = mesonbuild.linkers.GnuDynamicLinker([], MachineChoice.HOST, 'fake', '-Wl,')
linker = mesonbuild.linkers.GnuDynamicLinker([], MachineChoice.HOST, 'fake', '-Wl,', [])
gcc = mesonbuild.compilers.GnuCCompiler([], 'fake', False, MachineChoice.HOST, mock.Mock(), linker=linker)
## Ensure that the fake compiler is never called by overriding the relevant function
gcc.get_default_include_dirs = lambda: ['/usr/include', '/usr/share/include', '/usr/local/include']
Expand Down

0 comments on commit a524d22

Please sign in to comment.