From 47dfe34c8517747d51ef063474e3594c487fde82 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 25 Nov 2019 14:20:58 -0800 Subject: Consider compiler arguments in linker detection logic 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 #6057 --- mesonbuild/compilers/compilers.py | 6 ++++-- mesonbuild/compilers/mixins/visualstudio.py | 2 ++ mesonbuild/coredata.py | 7 ++++--- mesonbuild/environment.py | 16 +++++++++++++--- mesonbuild/linkers.py | 9 --------- 5 files changed, 23 insertions(+), 17 deletions(-) (limited to 'mesonbuild') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 9631bd2..20b339b 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -681,6 +681,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): @@ -1175,7 +1176,8 @@ def get_args_from_envvars(lang: str, use_linker_args: bool) -> typing.Tuple[typi 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 = { @@ -1190,7 +1192,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 = [] diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py index 4798bdc..8e18144 100644 --- a/mesonbuild/compilers/mixins/visualstudio.py +++ b/mesonbuild/compilers/mixins/visualstudio.py @@ -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 diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 58ccae0..140950d 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -35,7 +35,7 @@ import shlex if TYPE_CHECKING: from . import dependencies - from .compilers import Compiler + from .compilers import Compiler # noqa: F401 from .environment import Environment OptionDictType = Dict[str, 'UserOption[Any]'] @@ -744,12 +744,13 @@ class CoreData: 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: 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 diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index dc269d2..26727ad 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -735,6 +735,8 @@ class Environment: 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'] @@ -743,6 +745,8 @@ class Environment: 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: @@ -797,7 +801,9 @@ class Environment: :for_machine: which machine this linker targets :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 @@ -1287,7 +1293,9 @@ class Environment: parts = (err if 'javac' in err else out).split() if len(parts) > 1: version = parts[1] - return JavaCompiler(exelist, version, for_machine, info) + comp_class = JavaCompiler + self.coredata.add_lang_args(comp_class.language, comp_class, for_machine, self) + return comp_class(exelist, version, for_machine, info) raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"') def detect_cs_compiler(self, for_machine): @@ -1308,6 +1316,7 @@ class Environment: cls = MonoCompiler elif "Visual C#" in out: cls = VisualStudioCsCompiler + self.coredata.add_lang_args(cls.language, cls, for_machine, self) return cls(comp, version, for_machine, info) self._handle_exceptions(popen_exceptions, compilers) @@ -1326,7 +1335,9 @@ class Environment: raise EnvironmentException('Could not execute Vala compiler "%s"' % ' '.join(exelist)) version = search_version(out) if 'Vala' in out: - return ValaCompiler(exelist, version, for_machine, info, is_cross) + comp_class = ValaCompiler + self.coredata.add_lang_args(comp_class.language, comp_class, for_machine, self) + return comp_class(exelist, version, for_machine, info, is_cross) raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"') def detect_rust_compiler(self, for_machine): @@ -1538,7 +1549,6 @@ class Environment: 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 diff --git a/mesonbuild/linkers.py b/mesonbuild/linkers.py index ab532a4..4dae5eb 100644 --- a/mesonbuild/linkers.py +++ b/mesonbuild/linkers.py @@ -344,10 +344,6 @@ class DynamicLinker(metaclass=abc.ABCMeta): 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 @@ -468,10 +464,6 @@ class GnuLikeDynamicLinkerMixin: 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'] @@ -787,7 +779,6 @@ 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: -- cgit v1.1