Skip to content

Commit

Permalink
Pass compiler linker detection
Browse files Browse the repository at this point in the history
If a user passes -fuse-ld=gold to gcc or clang, they expect that they'll
get ld.gold, not whatever the default is. Meson currently doesn't do
that, because it doesn't pass these arguments to the linker detection
logic. This patch fixes that. Another case that this is needed is with
clang's --target option

This is a bad solution, honestly, and it would be better to use $LD or a
cross/native file but this is needed for backwards compatability.

Fixes mesonbuild#6057
  • Loading branch information
dcbaker committed Nov 25, 2019
1 parent 979ce60 commit f6f849d
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 18 deletions.
6 changes: 4 additions & 2 deletions mesonbuild/compilers/compilers.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ class Compiler:
internal_libs = ()

LINKER_PREFIX = None # type: typing.Union[None, str, typing.List[str]]
INVOKES_LINKER = True

def __init__(self, exelist, version, for_machine: MachineChoice, info: 'MachineInfo',
linker: typing.Optional['DynamicLinker'] = None, **kwargs):
Expand Down Expand Up @@ -1159,7 +1160,8 @@ def log_var(var, val: Optional[str]):
return compile_flags, link_flags


def get_global_options(lang: str, properties: Properties) -> typing.Dict[str, coredata.UserOption]:
def get_global_options(lang: str, comp: typing.Type[Compiler],
properties: Properties) -> typing.Dict[str, coredata.UserOption]:
"""Retreive options that apply to all compilers for a given language."""
description = 'Extra arguments passed to the {}'.format(lang)
opts = {
Expand All @@ -1174,7 +1176,7 @@ def get_global_options(lang: str, properties: Properties) -> typing.Dict[str, co
if properties.fallback:
# Get from env vars.
# XXX: True here is a hack
compile_args, link_args = get_args_from_envvars(lang, True)
compile_args, link_args = get_args_from_envvars(lang, comp.INVOKES_LINKER)
else:
compile_args = []
link_args = []
Expand Down
2 changes: 2 additions & 0 deletions mesonbuild/compilers/mixins/visualstudio.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
'3': ['/W4'],
} # type: typing.Dict[str, typing.List[str]]

INVOKES_LINKER = False

def __init__(self, target: str):
self.base_options = ['b_pch', 'b_ndebug', 'b_vscrt'] # FIXME add lto, pgo and the like
self.target = target
Expand Down
7 changes: 4 additions & 3 deletions mesonbuild/coredata.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

if typing.TYPE_CHECKING:
from . import dependencies
from .compilers import Compiler
from .compilers import Compiler # noqa: F401
from .environment import Environment

OptionDictType = typing.Dict[str, 'UserOption[Any]']
Expand Down Expand Up @@ -743,12 +743,13 @@ def set_default_options(self, default_options, subproject, env):

self.set_options(options, subproject=subproject)

def add_lang_args(self, lang: str, for_machine: MachineChoice, env: 'Environment') -> None:
def add_lang_args(self, lang: str, comp: typing.Type['Compiler'],
for_machine: MachineChoice, env: 'Environment') -> None:
"""Add global language arguments that are needed before compiler/linker detection."""
from .compilers import compilers

optprefix = lang + '_'
for k, o in compilers.get_global_options(lang, env.properties[for_machine]).items():
for k, o in compilers.get_global_options(lang, comp, env.properties[for_machine]).items():
if not k.startswith(optprefix):
raise MesonException('Internal error, %s has incorrect prefix.' % k)
# prefixed compiler options affect just this machine
Expand Down
7 changes: 6 additions & 1 deletion mesonbuild/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,8 @@ def _handle_exceptions(self, exceptions, binaries, bintype='compiler'):
def _guess_win_linker(self, compiler: typing.List[str], comp_class: Compiler,
for_machine: MachineChoice, *,
use_linker_prefix: bool = True) -> 'DynamicLinker':
self.coredata.add_lang_args(comp_class.language, comp_class, for_machine, self)

# Explicitly pass logo here so that we can get the version of link.exe
if not use_linker_prefix or comp_class.LINKER_PREFIX is None:
check_args = ['/logo', '--version']
Expand All @@ -744,6 +746,8 @@ def _guess_win_linker(self, compiler: typing.List[str], comp_class: Compiler,
elif isinstance(comp_class.LINKER_PREFIX, list):
check_args = comp_class.LINKER_PREFIX + ['/logo'] + comp_class.LINKER_PREFIX + ['--version']

check_args += self.coredata.compiler_options[for_machine][comp_class.language + '_args'].value

override = [] # type: typing.List[str]
value = self.binaries[for_machine].lookup_entry('ld')
if value is not None:
Expand Down Expand Up @@ -797,7 +801,9 @@ def _guess_nix_linker(self, compiler: typing.List[str], comp_class: Compiler,
`-Xlinker=--version`) you must pass as a list.
:extra_args: Any additional arguments required (such as a source file)
"""
self.coredata.add_lang_args(comp_class.language, comp_class, for_machine, self)
extra_args = typing.cast(typing.List[str], extra_args or [])
extra_args += self.coredata.compiler_options[for_machine][comp_class.language + '_args'].value

if isinstance(comp_class.LINKER_PREFIX, str):
check_args = [comp_class.LINKER_PREFIX + '--version'] + extra_args
Expand Down Expand Up @@ -1505,7 +1511,6 @@ def compiler_from_language(self, lang: str, for_machine: MachineChoice):
return comp

def detect_compiler_for(self, lang: str, for_machine: MachineChoice):
self.coredata.add_lang_args(lang, for_machine, self)
comp = self.compiler_from_language(lang, for_machine)
if comp is not None:
assert comp.for_machine == for_machine
Expand Down
12 changes: 0 additions & 12 deletions mesonbuild/linkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,6 @@ def get_allow_undefined_args(self) -> typing.List[str]:
raise mesonlib.EnvironmentException(
'Linker {} does not support allow undefined'.format(self.id))

def invoked_by_compiler(self) -> bool:
"""True if meson uses the compiler to invoke the linker."""
return True

@abc.abstractmethod
def get_output_args(self, outname: str) -> typing.List[str]:
pass
Expand Down Expand Up @@ -463,10 +459,6 @@ def sanitizer_args(self, value: str) -> typing.List[str]:
return []
return ['-fsanitize=' + value]

def invoked_by_compiler(self) -> bool:
"""True if meson uses the compiler to invoke the linker."""
return True

def get_coverage_args(self) -> typing.List[str]:
return ['--coverage']

Expand Down Expand Up @@ -800,12 +792,8 @@ class VisualStudioLikeLinkerMixin:

def __init__(self, *args, direct: bool = True, machine: str = 'x86', **kwargs):
super().__init__(*args, **kwargs)
self.direct = direct
self.machine = machine

def invoked_by_compiler(self) -> bool:
return self.direct

def get_debug_crt_args(self) -> typing.List[str]:
"""Arguments needed to select a debug crt for the linker.
Expand Down

0 comments on commit f6f849d

Please sign in to comment.