interpreter: detect and pass compiler to be used for linker tests

Allow using the links method to test that the C++ driver (e.g. g++) can be used to
link C objects.  One usecase is that the C compiler's libsanitizer might not be
compatible with the one included by the C++ driver.

This is theoretically backwards-incompatible, but it should be treated as a
bugfix in my opinion. There is no way in Meson to compile a .c file with the
C++ driver as part of a build target, therefore there would be no reason to
do something like meson.get_compiler(meson.get_compiler('cpp').links(files('main.c')).

Fixes: #7703
pull/9014/head
Paolo Bonzini 4 years ago
parent 90ee43463f
commit 8596b3bcd1
  1. 2
      mesonbuild/compilers/__init__.py
  2. 2
      mesonbuild/compilers/compilers.py
  3. 15
      mesonbuild/interpreter/compiler.py
  4. 4
      mesonbuild/mesonlib/universal.py

@ -34,6 +34,7 @@ __all__ = [
'is_known_suffix',
'lang_suffixes',
'sort_clink',
'SUFFIX_TO_LANG',
'compiler_from_language',
'detect_compiler_for',
@ -148,6 +149,7 @@ from .compilers import (
lang_suffixes,
LANGUAGES_USING_LDFLAGS,
sort_clink,
SUFFIX_TO_LANG,
)
from .detect import (
compiler_from_language,

@ -84,6 +84,8 @@ for _l in clink_langs + ('vala',):
clink_suffixes += lang_suffixes[_l]
clink_suffixes += ('h', 'll', 's')
all_suffixes = set(itertools.chain(*lang_suffixes.values(), clink_suffixes)) # type: T.Set[str]
SUFFIX_TO_LANG = dict(itertools.chain(*(
[(suffix, lang) for suffix in v] for lang, v in lang_suffixes.items()))) # type: T.Dict[str, str]
# Languages that should use LDFLAGS arguments when linking.
LANGUAGES_USING_LDFLAGS = {'objcpp', 'cpp', 'objc', 'c', 'fortran', 'd', 'cuda'} # type: T.Set[str]

@ -11,6 +11,7 @@ from .. import coredata
from .. import dependencies
from .. import mesonlib
from .. import mlog
from ..compilers import SUFFIX_TO_LANG
from ..compilers.compilers import CompileCheckMode
from ..interpreterbase import (ObjectHolder, noPosargs, noKwargs,
FeatureNew, disablerIfNotFound,
@ -454,13 +455,27 @@ class CompilerHolder(ObjectHolder['Compiler']):
@typed_kwargs('compiler.links', *_COMPILES_KWS)
def links_method(self, args: T.Tuple['mesonlib.FileOrString'], kwargs: 'CompileKW') -> bool:
code = args[0]
compiler = None
if isinstance(code, mesonlib.File):
code = mesonlib.File.from_absolute_file(
code.rel_to_builddir(self.environment.source_dir))
suffix = code.suffix
if suffix not in self.compiler.file_suffixes:
for_machine = self.compiler.for_machine
clist = self.interpreter.coredata.compilers[for_machine]
if suffix not in SUFFIX_TO_LANG:
# just pass it to the compiler driver
mlog.warning(f'Unknown suffix for test file {code}')
elif SUFFIX_TO_LANG[suffix] not in clist:
mlog.warning(f'Passed {SUFFIX_TO_LANG[suffix]} source to links method, not specified for {for_machine.get_lower_case_name()} machine.')
else:
compiler = clist[SUFFIX_TO_LANG[suffix]]
testname = kwargs['name']
extra_args = functools.partial(self._determine_args, kwargs['no_builtin_args'], kwargs['include_directories'], kwargs['args'])
deps, msg = self._determine_dependencies(kwargs['dependencies'])
result, cached = self.compiler.links(code, self.environment,
compiler=compiler,
extra_args=extra_args,
dependencies=deps)
cached_msg = mlog.blue('(cached)') if cached else ''

@ -421,6 +421,10 @@ class File(HoldableObject):
absdir = builddir
return os.path.join(absdir, self.relative_name())
@property
def suffix(self) -> str:
return os.path.splitext(self.fname)[1][1:].lower()
def endswith(self, ending: str) -> bool:
return self.fname.endswith(ending)

Loading…
Cancel
Save