# SPDX-License-Identifier: Apache-2.0
# Copyright 2012-2022 The Meson development team

from __future__ import annotations

from ..mesonlib import (
    MesonException, EnvironmentException, MachineChoice, join_args,
    search_version, is_windows, Popen_safe, Popen_safe_logged, version_compare, windows_proof_rm,
    unwrap,
)
from ..programs import ExternalProgram
from ..envconfig import BinaryTable, detect_cpu_family
from .. import mlog

from ..linkers import guess_win_linker, guess_nix_linker

import subprocess
import platform
import re
import shutil
import tempfile
import os
import typing as T

if T.TYPE_CHECKING:
    from .compilers import Language, Compiler, CompilerDict
    from .asm import ASMCompiler
    from .c import CCompiler
    from .cpp import CPPCompiler
    from .fortran import FortranCompiler
    from .rust import RustCompiler
    from ..linkers.linkers import StaticLinker, DynamicLinker
    from ..environment import Environment


# Default compilers and linkers
# =============================

defaults: T.Dict[str, T.List[str]] = {}

# List of potential compilers.
if is_windows():
    # Intel C and C++ compiler is icl on Windows, but icc and icpc elsewhere.
    # Search for icl before cl, since Intel "helpfully" provides a
    # cl.exe that returns *exactly the same thing* that Microsoft's
    # cl.exe does, and if icl is present, it's almost certainly what
    # you want.
    defaults['c'] = ['icl', 'cl', 'cc', 'gcc', 'clang', 'clang-cl', 'pgcc']
    # There is currently no pgc++ for Windows, only for  Mac and Linux.
    defaults['cpp'] = ['icl', 'cl', 'c++', 'g++', 'clang++', 'clang-cl']
    # the binary flang-new will be renamed to flang in the foreseeable future
    defaults['fortran'] = ['ifort', 'ifx', 'gfortran', 'flang-new', 'flang', 'pgfortran', 'g95']
    defaults['objc'] = ['clang', 'clang-cl', 'gcc']
    defaults['objcpp'] = ['clang++', 'clang-cl', 'g++']
    defaults['cs'] = ['csc', 'mcs']
else:
    if platform.machine().lower() == 'e2k':
        defaults['c'] = ['cc', 'gcc', 'lcc', 'clang']
        defaults['cpp'] = ['c++', 'g++', 'l++', 'clang++']
        defaults['objc'] = ['clang']
        defaults['objcpp'] = ['clang++']
    else:
        defaults['c'] = ['cc', 'gcc', 'clang', 'nvc', 'pgcc', 'icc', 'icx']
        defaults['cpp'] = ['c++', 'g++', 'clang++', 'nvc++', 'pgc++', 'icpc', 'icpx']
        defaults['objc'] = ['clang', 'gcc']
        defaults['objcpp'] = ['clang++', 'g++']
    # the binary flang-new will be renamed to flang in the foreseeable future
    defaults['fortran'] = ['gfortran', 'flang-new', 'flang', 'nvfortran', 'pgfortran', 'ifort', 'ifx', 'g95']
    defaults['cs'] = ['mcs', 'csc']
defaults['d'] = ['ldc2', 'ldc', 'gdc', 'dmd']
defaults['java'] = ['javac']
defaults['cuda'] = ['nvcc']
defaults['rust'] = ['rustc']
defaults['swift'] = ['swiftc']
defaults['vala'] = ['valac']
defaults['cython'] = ['cython', 'cython3'] # Official name is cython, but Debian renamed it to cython3.
defaults['static_linker'] = ['ar', 'gar']
defaults['strip'] = ['strip']
defaults['vs_static_linker'] = ['lib']
defaults['clang_cl_static_linker'] = ['llvm-lib']
defaults['cuda_static_linker'] = ['nvlink']
defaults['gcc_static_linker'] = ['gcc-ar']
defaults['clang_static_linker'] = ['llvm-ar']
defaults['emxomf_static_linker'] = ['emxomfar']
defaults['nasm'] = ['nasm', 'yasm']


def compiler_from_language(env: 'Environment', lang: str, for_machine: MachineChoice) -> T.Optional[Compiler]:
    lang_map: T.Dict[str, T.Callable[['Environment', MachineChoice], Compiler]] = {
        'c': detect_c_compiler,
        'cpp': detect_cpp_compiler,
        'objc': detect_objc_compiler,
        'cuda': detect_cuda_compiler,
        'objcpp': detect_objcpp_compiler,
        'java': detect_java_compiler,
        'cs': detect_cs_compiler,
        'vala': detect_vala_compiler,
        'd': detect_d_compiler,
        'rust': detect_rust_compiler,
        'fortran': detect_fortran_compiler,
        'swift': detect_swift_compiler,
        'cython': detect_cython_compiler,
        'nasm': detect_nasm_compiler,
        'masm': detect_masm_compiler,
        'linearasm': detect_linearasm_compiler,
    }
    return lang_map[lang](env, for_machine) if lang in lang_map else None

def detect_compiler_for(env: 'Environment', lang: Language, for_machine: MachineChoice, skip_sanity_check: bool, subproject: str) -> T.Optional[Compiler]:
    comp = compiler_from_language(env, lang, for_machine)
    if comp is None:
        return comp
    assert comp.for_machine == for_machine
    env.coredata.process_compiler_options(lang, comp, subproject)
    if not skip_sanity_check:
        comp.sanity_check(env.get_scratch_dir())
    env.coredata.compilers[comp.for_machine][lang] = comp
    return comp


# Helpers
# =======

def _get_compilers(env: 'Environment', lang: str, for_machine: MachineChoice,
                   allow_build_machine: bool = False) -> T.Tuple[T.List[T.List[str]], T.Union[None, ExternalProgram]]:
    '''
    The list of compilers is detected in the exact same way for
    C, C++, ObjC, ObjC++, Fortran, CS so consolidate it here.
    '''
    value = env.lookup_binary_entry(for_machine, lang)
    if value is not None:
        comp, ccache = BinaryTable.parse_entry(value)
        # Return value has to be a list of compiler 'choices'
        compilers = [comp]
    else:
        if not env.machines.matches_build_machine(for_machine):
            if allow_build_machine:
                return _get_compilers(env, lang, MachineChoice.BUILD)
            raise EnvironmentException(f'{lang!r} compiler binary not defined in cross file [binaries] section')
        compilers = [[x] for x in defaults[lang]]
        ccache = BinaryTable.detect_compiler_cache()

    return compilers, ccache

def _handle_exceptions(
        exceptions: T.Mapping[str, T.Union[Exception, str]],
        binaries: T.List[T.List[str]],
        bintype: str = 'compiler') -> T.NoReturn:
    errmsg = f'Unknown {bintype}(s): {binaries}'
    if exceptions:
        errmsg += '\nThe following exception(s) were encountered:'
        for c, e in exceptions.items():
            if isinstance(e, MesonException):
                errmsg += f'\nUsing `{c}` failed: {e}'
            else:
                errmsg += f'\nRunning `{c}` gave "{e}"'
    raise EnvironmentException(errmsg)


# Linker specific
# ===============

def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker:
    from . import d
    from ..linkers import linkers
    from ..options import OptionKey
    linker = env.lookup_binary_entry(compiler.for_machine, 'ar')
    if linker is not None:
        trials = [linker]
    else:
        default_linkers = [[l] for l in defaults['static_linker']]
        if compiler.language == 'cuda':
            trials = [defaults['cuda_static_linker']] + default_linkers
        elif compiler.get_argument_syntax() == 'msvc':
            trials = [defaults['vs_static_linker'], defaults['clang_cl_static_linker']]
        elif env.machines[compiler.for_machine].is_os2() and env.coredata.optstore.get_value_for(OptionKey('os2_emxomf')):
            trials = [defaults['emxomf_static_linker']] + default_linkers
        elif compiler.id == 'gcc':
            # Use gcc-ar if available; needed for LTO
            trials = [defaults['gcc_static_linker']] + default_linkers
        elif compiler.id == 'clang':
            # Use llvm-ar if available; needed for LTO
            llvm_ar = defaults['clang_static_linker']
            # Extract the version major of the compiler to use as a suffix
            suffix = compiler.version.split('.')[0]
            # Prefer suffixed llvm-ar first, then unsuffixed then the defaults
            trials = [[f'{llvm_ar[0]}-{suffix}'], llvm_ar] + default_linkers
        elif compiler.language == 'd':
            # Prefer static linkers over linkers used by D compilers
            if is_windows():
                trials = [defaults['vs_static_linker'], defaults['clang_cl_static_linker'], compiler.get_linker_exelist()]
            else:
                trials = default_linkers
        elif compiler.id == 'intel-cl' and compiler.language == 'c': # why not cpp? Is this a bug?
            # Intel has its own linker that acts like Microsoft's lib
            trials = [['xilib']]
        elif is_windows() and compiler.id == 'pgi': # this handles cpp / nvidia HPC, in addition to just c/fortran
            trials = [['ar']]  # For PGI on Windows, "ar" is just a wrapper calling link/lib.
        elif is_windows() and compiler.id == 'nasm':
            # This may well be LINK.EXE if it's under a MSVC environment
            trials = [defaults['vs_static_linker'], defaults['clang_cl_static_linker']] + default_linkers
        else:
            trials = default_linkers
    popen_exceptions = {}
    for linker in trials:
        linker_name = os.path.basename(linker[0])

        if any(os.path.basename(x) in {'lib', 'lib.exe', 'llvm-lib', 'llvm-lib.exe', 'xilib', 'xilib.exe'} for x in linker):
            arg = '/?'
        elif linker_name in {'ar2000', 'ar2000.exe', 'ar430', 'ar430.exe', 'ar6x', 'ar6x.exe'}:
            arg = '?'
        elif linker_name in {'armar', 'armar.exe'}:
            arg = '-h'
        else:
            arg = '--version'
        try:
            p, out, err = Popen_safe_logged(linker + [arg], msg='Detecting archiver via')
        except OSError as e:
            popen_exceptions[join_args(linker + [arg])] = e
            continue
        if "xilib: executing 'lib'" in err:
            return linkers.IntelVisualStudioLinker(linker, env, getattr(compiler, 'machine', None))
        if '/OUT:' in out.upper() or '/OUT:' in err.upper():
            return linkers.VisualStudioLinker(linker, env, getattr(compiler, 'machine', None))
        if 'ar-Error-Unknown switch: --version' in err:
            return linkers.PGIStaticLinker(linker, env)
        if p.returncode == 0 and 'armar' in linker_name:
            return linkers.ArmarLinker(linker, env)
        if 'DMD32 D Compiler' in out or 'DMD64 D Compiler' in out:
            assert isinstance(compiler, d.DCompiler)
            return linkers.DLinker(linker, env, compiler.arch)
        if 'LDC - the LLVM D compiler' in out:
            assert isinstance(compiler, d.DCompiler)
            return linkers.DLinker(linker, env, compiler.arch, rsp_syntax=compiler.rsp_file_syntax())
        if 'GDC' in out and ' based on D ' in out:
            assert isinstance(compiler, d.DCompiler)
            return linkers.DLinker(linker, env, compiler.arch)
        if err.startswith('Renesas') and 'rlink' in linker_name:
            return linkers.CcrxLinker(linker, env)
        if out.startswith('GNU ar'):
            if 'xc16-ar' in linker_name:
                return linkers.Xc16Linker(linker, env)
            elif 'xc32-ar' in linker_name:
                return linkers.Xc32ArLinker(compiler.for_machine, linker, env)
        if 'Texas Instruments Incorporated' in out:
            if 'ar2000' in linker_name:
                return linkers.C2000Linker(linker, env)
            elif 'ar6000' in linker_name:
                return linkers.C6000Linker(linker, env)
            else:
                return linkers.TILinker(linker, env)
        if out.startswith('The CompCert'):
            return linkers.CompCertLinker(linker, env)
        if out.strip().startswith('Metrowerks') or out.strip().startswith('Freescale'):
            if 'ARM' in out:
                return linkers.MetrowerksStaticLinkerARM(linker, env)
            else:
                return linkers.MetrowerksStaticLinkerEmbeddedPowerPC(linker, env)
        if 'TASKING VX-toolset' in err:
            return linkers.TaskingStaticLinker(linker, env)
        if p.returncode == 0:
            return linkers.ArLinker(compiler.for_machine, linker, env)
        if p.returncode == 1 and err.startswith('usage'): # OSX
            return linkers.AppleArLinker(compiler.for_machine, linker, env)
        if p.returncode == 1 and err.startswith('Usage'): # AIX
            return linkers.AIXArLinker(linker, env)
        if p.returncode == 1 and err.startswith('ar: bad option: --'): # Solaris
            return linkers.ArLinker(compiler.for_machine, linker, env)
        if p.returncode == 1 and err.startswith('emxomfar'):
            return linkers.EmxomfArLinker(compiler.for_machine, linker, env)
    _handle_exceptions(popen_exceptions, trials, 'linker')
    raise EnvironmentException('Unreachable code (exception to make mypy happy)')


# Compilers
# =========


def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: MachineChoice, *, override_compilers: T.Optional[T.List[T.List[str]]] = None) -> Compiler:
    """Shared implementation for finding the C or C++ compiler to use.

    the override_compiler option is provided to allow compilers which use
    the compiler (GCC or Clang usually) as their shared linker, to find
    the linker they need.
    """
    from . import c, cpp
    from ..linkers import linkers
    popen_exceptions: T.Dict[str, T.Union[Exception, str]] = {}
    compilers, ccache_exe = _get_compilers(env, lang, for_machine)
    ccache = ccache_exe.get_command() if (ccache_exe and ccache_exe.found()) else []
    if override_compilers is not None:
        compilers = override_compilers
    cls: T.Union[T.Type[CCompiler], T.Type[CPPCompiler]]
    lnk: T.Union[T.Type[StaticLinker], T.Type[DynamicLinker]]

    for compiler in compilers:
        compiler_name = os.path.basename(compiler[0])

        if any(os.path.basename(x) in {'cl', 'cl.exe', 'clang-cl', 'clang-cl.exe'} for x in compiler):
            # Watcom C provides its own cl.exe clone that mimics an older
            # version of Microsoft's compiler. Since Watcom's cl.exe is
            # just a wrapper, we skip using it if we detect its presence
            # so as not to confuse Meson when configuring for MSVC.
            #
            # Additionally the help text of Watcom's cl.exe is paged, and
            # the binary will not exit without human intervention. In
            # practice, Meson will block waiting for Watcom's cl.exe to
            # exit, which requires user input and thus will never exit.
            if 'WATCOM' in os.environ:
                def sanitize(p: T.Optional[str]) -> T.Optional[str]:
                    return os.path.normcase(os.path.abspath(p)) if p else None

                watcom_cls = [sanitize(os.path.join(os.environ['WATCOM'], 'BINNT', 'cl')),
                              sanitize(os.path.join(os.environ['WATCOM'], 'BINNT', 'cl.exe')),
                              sanitize(os.path.join(os.environ['WATCOM'], 'BINNT64', 'cl')),
                              sanitize(os.path.join(os.environ['WATCOM'], 'BINNT64', 'cl.exe'))]
                found_cl = sanitize(shutil.which('cl'))
                if found_cl in watcom_cls:
                    mlog.debug('Skipping unsupported cl.exe clone at:', found_cl)
                    continue
            arg = '/?'
        elif 'armcc' in compiler_name:
            arg = '--vsn'
        elif 'ccrx' in compiler_name:
            arg = '-v'
        elif 'xc16' in compiler_name:
            arg = '--version'
        elif 'ccomp' in compiler_name:
            arg = '-version'
        elif compiler_name in {'cl2000', 'cl2000.exe', 'cl430', 'cl430.exe', 'armcl', 'armcl.exe', 'cl6x', 'cl6x.exe'}:
            # TI compiler
            arg = '-version'
        elif compiler_name in {'icl', 'icl.exe'}:
            # if you pass anything to icl you get stuck in a pager
            arg = ''
        else:
            arg = '--version'

        cmd = compiler + [arg]
        try:
            p, out, err = Popen_safe_logged(cmd, msg='Detecting compiler via')
        except OSError as e:
            popen_exceptions[join_args(cmd)] = e
            continue

        if 'ccrx' in compiler_name:
            out = err

        full_version = out.split('\n', 1)[0]
        version = search_version(out)

        guess_gcc_or_lcc: T.Optional[str] = None
        if 'Free Software Foundation' in out or out.startswith('xt-'):
            guess_gcc_or_lcc = 'gcc'
        if 'e2k' in out and 'lcc' in out:
            guess_gcc_or_lcc = 'lcc'
        if 'Microchip' in out:
            # this output has "Free Software Foundation" in its version
            guess_gcc_or_lcc = None

        if guess_gcc_or_lcc:
            defines = _get_gnu_compiler_defines(compiler, lang)
            if not defines:
                popen_exceptions[join_args(compiler)] = 'no pre-processor defines'
                continue

            if guess_gcc_or_lcc == 'lcc':
                version = _get_lcc_version_from_defines(defines)
                cls = c.ElbrusCCompiler if lang == 'c' else cpp.ElbrusCPPCompiler
            else:
                version = _get_gnu_version_from_defines(defines)
                cls = c.GnuCCompiler if lang == 'c' else cpp.GnuCPPCompiler

            linker = guess_nix_linker(env, compiler, cls, version, for_machine)

            return cls(
                ccache, compiler, version, for_machine,
                env, defines=defines, full_version=full_version,
                linker=linker)

        if 'Emscripten' in out:
            cls = c.EmscriptenCCompiler if lang == 'c' else cpp.EmscriptenCPPCompiler
            env.add_lang_args(cls.language, cls, for_machine)

            # emcc requires a file input in order to pass arguments to the
            # linker. It'll exit with an error code, but still print the
            # linker version.
            with tempfile.NamedTemporaryFile(suffix='.c') as f:
                cmd = [*compiler, *cls.LINKER_OPTION_STYLE.wrap(['--version']), f.name]
                _, o, _ = Popen_safe(cmd)

            linker = linkers.WASMDynamicLinker(
                compiler, env, for_machine, cls.LINKER_OPTION_STYLE,
                [], version=search_version(o))
            return cls(
                ccache, compiler, version, for_machine, env,
                linker=linker, full_version=full_version)

        if 'Arm C/C++/Fortran Compiler' in out:
            arm_ver_match = unwrap(re.search(r'version (\d+)\.(\d+)\.?(\d+)? \(build number (\d+)\)', out))
            version = '.'.join([x for x in arm_ver_match.groups() if x is not None])
            if lang == 'c':
                cls = c.ArmLtdClangCCompiler
            elif lang == 'cpp':
                cls = cpp.ArmLtdClangCPPCompiler
            linker = guess_nix_linker(env, compiler, cls, version, for_machine)
            return cls(
                ccache, compiler, version, for_machine, env,
                linker=linker)
        if 'armclang' in out:
            # The compiler version is not present in the first line of output,
            # instead it is present in second line, startswith 'Component:'.
            # So, searching for the 'Component' in out although we know it is
            # present in second line, as we are not sure about the
            # output format in future versions
            arm_ver_match = re.search('.*Component.*', out)
            if arm_ver_match is None:
                popen_exceptions[join_args(compiler)] = 'version string not found'
                continue
            arm_ver_str = arm_ver_match.group(0)
            # Override previous values
            version = search_version(arm_ver_str)
            full_version = arm_ver_str
            cls = c.ArmclangCCompiler if lang == 'c' else cpp.ArmclangCPPCompiler
            linker = linkers.ArmClangDynamicLinker(env, for_machine, version=version)
            env.add_lang_args(cls.language, cls, for_machine)
            return cls(
                ccache, compiler, version, for_machine, env,
                full_version=full_version, linker=linker)
        if 'CL.EXE COMPATIBILITY' in out:
            # if this is clang-cl masquerading as cl, detect it as cl, not
            # clang
            arg = '--version'
            try:
                p, out, err = Popen_safe(compiler + [arg])
            except OSError as e:
                popen_exceptions[join_args(compiler + [arg])] = e
            version = search_version(out)
            match = re.search('^Target: (.*?)-', out, re.MULTILINE)
            if match:
                target = match.group(1)
            else:
                target = 'unknown target'
            cls = c.ClangClCCompiler if lang == 'c' else cpp.ClangClCPPCompiler
            linker = guess_win_linker(env, ['lld-link'], cls, version, for_machine)
            return cls(
                compiler, version, for_machine, env, target,
                linker=linker)

        # must be detected here before clang because TI compilers contain 'clang' in their output and so that they can be detected as 'clang'
        ti_compilers = {
           'TMS320C2000 C/C++': (c.C2000CCompiler, cpp.C2000CPPCompiler, linkers.C2000DynamicLinker),
           'TMS320C6x C/C++': (c.C6000CCompiler, cpp.C6000CPPCompiler, linkers.C6000DynamicLinker),
           'TI ARM C/C++ Compiler': (c.TICCompiler, cpp.TICPPCompiler, linkers.TIDynamicLinker),
           'MSP430 C/C++': (c.TICCompiler, cpp.TICPPCompiler, linkers.TIDynamicLinker)
        }
        for identifier, compiler_classes in ti_compilers.items():
            if identifier in out:
                cls = compiler_classes[0] if lang == 'c' else compiler_classes[1]
                lnk = compiler_classes[2]
                env.add_lang_args(cls.language, cls, for_machine)
                linker = lnk(compiler, env, for_machine, version=version)
                return cls(
                    ccache, compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

        if 'clang' in out or 'Clang' in out:
            linker = None

            defines = _get_clang_compiler_defines(compiler, lang)

            # Even if the for_machine is darwin, we could be using vanilla
            # clang.
            if 'Apple' in out:
                cls = c.AppleClangCCompiler if lang == 'c' else cpp.AppleClangCPPCompiler
            else:
                cls = c.ClangCCompiler if lang == 'c' else cpp.ClangCPPCompiler

            if 'windows' in out or env.machines[for_machine].is_windows():
                # If we're in a MINGW context this actually will use a gnu
                # style ld, but for clang on "real" windows we'll use
                # either link.exe or lld-link.exe
                try:
                    linker = guess_win_linker(env, compiler, cls, version, for_machine, invoked_directly=False)
                except MesonException:
                    pass
            if linker is None:
                linker = guess_nix_linker(env, compiler, cls, version, for_machine)

            return cls(
                ccache, compiler, version, for_machine, env,
                defines=defines, full_version=full_version, linker=linker)

        if 'Intel(R) C++ Intel(R)' in err:
            version = search_version(err)
            target = 'x86' if 'IA-32' in err else 'x86_64'
            cls = c.IntelClCCompiler if lang == 'c' else cpp.IntelClCPPCompiler
            env.add_lang_args(cls.language, cls, for_machine)
            linker = linkers.XilinkDynamicLinker(env, for_machine, [], version=version)
            return cls(
                compiler, version, for_machine, env, target,
                linker=linker)
        if 'Intel(R) oneAPI DPC++/C++ Compiler for applications' in err:
            version = search_version(err)
            target = 'x86' if 'IA-32' in err else 'x86_64'
            cls = c.IntelLLVMClCCompiler if lang == 'c' else cpp.IntelLLVMClCPPCompiler
            env.add_lang_args(cls.language, cls, for_machine)
            linker = linker = guess_win_linker(
                    env, ['link'], cls, version,
                    for_machine)
            return cls(
                compiler, version, for_machine, env, target,
                linker=linker)
        if 'Microsoft' in out or 'Microsoft' in err:
            # Latest versions of Visual Studio print version
            # number to stderr but earlier ones print version
            # on stdout.  Why? Lord only knows.
            # Check both outputs to figure out version.
            for lookat in [err, out]:
                version = search_version(lookat)
                if version != 'unknown version':
                    break
            else:
                raise EnvironmentException(f'Failed to detect MSVC compiler version: stderr was\n{err!r}')
            cl_signature = lookat.split('\n', maxsplit=1)[0]
            match = re.search(r'.*(x86|x64|ARM|ARM64)([^_A-Za-z0-9]|$)', cl_signature)
            if match:
                target = match.group(1)
            else:
                m = f'Failed to detect MSVC compiler target architecture: \'cl /?\' output is\n{cl_signature}'
                raise EnvironmentException(m)
            cls = c.VisualStudioCCompiler if lang == 'c' else cpp.VisualStudioCPPCompiler
            linker = guess_win_linker(env, ['link'], cls, version, for_machine)
            if ccache_exe and ccache_exe.found():
                if ccache_exe.get_name() == 'ccache' and version_compare(ccache_exe.get_version(), '< 4.6'):
                    mlog.warning('Visual Studio support requires ccache 4.6 or higher. You have ccache {}. '.format(ccache_exe.get_version()), once=True)
                    ccache = []
            return cls(
                ccache, compiler, version, for_machine, env, target,
                full_version=cl_signature, linker=linker)
        if 'PGI Compilers' in out:
            cls = c.PGICCompiler if lang == 'c' else cpp.PGICPPCompiler
            env.add_lang_args(cls.language, cls, for_machine)
            linker = linkers.PGIDynamicLinker(compiler, env, for_machine, cls.LINKER_OPTION_STYLE, [], version=version)
            return cls(
                ccache, compiler, version, for_machine,
                env, linker=linker)
        if 'NVIDIA Compilers and Tools' in out:
            cls = c.NvidiaHPC_CCompiler if lang == 'c' else cpp.NvidiaHPC_CPPCompiler
            env.add_lang_args(cls.language, cls, for_machine)
            linker = linkers.NvidiaHPC_DynamicLinker(compiler, env, for_machine, cls.LINKER_OPTION_STYLE, [], version=version)
            return cls(
                ccache, compiler, version, for_machine,
                env, linker=linker)
        if '(ICC)' in out:
            cls = c.IntelCCompiler if lang == 'c' else cpp.IntelCPPCompiler
            l = guess_nix_linker(env, compiler, cls, version, for_machine)
            return cls(
                ccache, compiler, version, for_machine, env,
                full_version=full_version, linker=l)
        if 'Intel(R) oneAPI' in out:
            cls = c.IntelLLVMCCompiler if lang == 'c' else cpp.IntelLLVMCPPCompiler
            l = guess_nix_linker(env, compiler, cls, version, for_machine)
            return cls(
                ccache, compiler, version, for_machine, env,
                full_version=full_version, linker=l)
        if 'ARM' in out and not ('Metrowerks' in out or 'Freescale' in out):
            cls = c.ArmCCompiler if lang == 'c' else cpp.ArmCPPCompiler
            env.add_lang_args(cls.language, cls, for_machine)
            linker = linkers.ArmDynamicLinker(env, for_machine, version=version)
            return cls(
                ccache, compiler, version, for_machine,
                env, full_version=full_version, linker=linker)
        if 'RX Family' in out:
            cls = c.CcrxCCompiler if lang == 'c' else cpp.CcrxCPPCompiler
            env.add_lang_args(cls.language, cls, for_machine)
            linker = linkers.CcrxDynamicLinker(env, for_machine, version=version)
            return cls(
                ccache, compiler, version, for_machine, env,
                full_version=full_version, linker=linker)

        if 'Microchip' in out:
            if 'XC32' in out:
                # XC32 versions always have the form 'vMAJOR.MINOR'
                match = re.search(r'XC32.*v(\d+\.\d+)', out)
                if match:
                    version = match.group(1)
                else:
                    raise EnvironmentException(f'Failed to detect XC32 compiler version: full version was\n{full_version}')

                cls = c.Xc32CCompiler if lang == 'c' else cpp.Xc32CPPCompiler
                defines = _get_gnu_compiler_defines(compiler, lang)
                cls.gcc_version = _get_gnu_version_from_defines(defines)

                env.add_lang_args(cls.language, cls, for_machine)
                linker = linkers.Xc32DynamicLinker(compiler, env, for_machine, cls.LINKER_OPTION_STYLE, [], version=version)

                return cls(
                    ccache, compiler, version, for_machine,
                    env, defines=defines, full_version=full_version,
                    linker=linker)
            else:
                cls = c.Xc16CCompiler
                env.add_lang_args(cls.language, cls, for_machine)
                linker = linkers.Xc16DynamicLinker(env, for_machine, version=version)

                return cls(
                    ccache, compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

        if 'CompCert' in out:
            cls = c.CompCertCCompiler
            env.add_lang_args(cls.language, cls, for_machine)
            linker = linkers.CompCertDynamicLinker(env, for_machine, version=version)
            return cls(
                ccache, compiler, version, for_machine, env,
                full_version=full_version, linker=linker)

        if 'Metrowerks C/C++' in out or 'Freescale C/C++' in out:
            if 'ARM' in out:
                cls = c.MetrowerksCCompilerARM if lang == 'c' else cpp.MetrowerksCPPCompilerARM
                lnk = linkers.MetrowerksLinkerARM
            else:
                cls = c.MetrowerksCCompilerEmbeddedPowerPC if lang == 'c' else cpp.MetrowerksCPPCompilerEmbeddedPowerPC
                lnk = linkers.MetrowerksLinkerEmbeddedPowerPC

            mwcc_ver_match = unwrap(re.search(r'Version (\d+)\.(\d+)\.?(\d+)? build (\d+)', out))
            compiler_version = '.'.join(x for x in mwcc_ver_match.groups() if x is not None)

            env.add_lang_args(cls.language, cls, for_machine)
            ld = env.lookup_binary_entry(for_machine, cls.language + '_ld')

            if ld is not None:
                _, o_ld, _ = Popen_safe(ld + ['--version'])

                mwld_ver_match = unwrap(re.search(r'Version (\d+)\.(\d+)\.?(\d+)? build (\d+)', o_ld))
                linker_version = '.'.join(x for x in mwld_ver_match.groups() if x is not None)

                linker = lnk(ld, env, for_machine, version=linker_version)
            else:
                raise EnvironmentException(f'Failed to detect linker for {cls.id!r} compiler. Please update your cross file(s).')

            return cls(
                ccache, compiler, compiler_version, for_machine, env,
                full_version=full_version, linker=linker)
        if 'TASKING VX-toolset' in err:
            cls = c.TaskingCCompiler
            lnk = linkers.TaskingLinker

            tasking_ver_match = unwrap(re.search(r'v([0-9]+)\.([0-9]+)r([0-9]+) Build ([0-9]+)', err))
            tasking_version = '.'.join(x for x in tasking_ver_match.groups() if x is not None)

            env.add_lang_args(cls.language, cls, for_machine)
            ld = env.lookup_binary_entry(for_machine, cls.language + '_ld')
            if ld is None:
                raise MesonException(f'{cls.language}_ld was not properly defined in your cross file')

            linker = lnk(ld, env, for_machine, version=tasking_version)
            return cls(
                ccache, compiler, tasking_version, for_machine, env,
                full_version=full_version, linker=linker)

    _handle_exceptions(popen_exceptions, compilers)
    raise EnvironmentException(f'Unknown compiler {compilers}')

def detect_c_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    return _detect_c_or_cpp_compiler(env, 'c', for_machine)

def detect_cpp_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    return _detect_c_or_cpp_compiler(env, 'cpp', for_machine)

def detect_cuda_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    from .cuda import CudaCompiler, Phase
    from ..options import OptionKey
    from ..linkers.linkers import CudaLinker
    popen_exceptions = {}
    compilers, ccache_exe = _get_compilers(env, 'cuda', for_machine)
    ccache = ccache_exe.get_command() if (ccache_exe and ccache_exe.found()) else []

    try:
        cpp_compiler = env.coredata.compilers[for_machine]['cpp']
    except KeyError:
        raise MesonException('Cuda requires a working C++ compiler for the same machine, but one could not be found')

    for compiler in compilers:
        arg = '--version'
        try:
            p, out, err = Popen_safe_logged(compiler + [arg], msg='Detecting compiler via')
        except OSError as e:
            popen_exceptions[join_args(compiler + [arg])] = e
            continue
        # Example nvcc printout:
        #
        #     nvcc: NVIDIA (R) Cuda compiler driver
        #     Copyright (c) 2005-2018 NVIDIA Corporation
        #     Built on Sat_Aug_25_21:08:01_CDT_2018
        #     Cuda compilation tools, release 10.0, V10.0.130
        #
        # search_version() first finds the "10.0" after "release",
        # rather than the more precise "10.0.130" after "V".
        # The patch version number is occasionally important; For
        # instance, on Linux,
        #    - CUDA Toolkit 8.0.44 requires NVIDIA Driver 367.48
        #    - CUDA Toolkit 8.0.61 requires NVIDIA Driver 375.26
        # Split on the `V` to get the version, then strip additional lines after
        # that.
        version = out.strip().rsplit('V', maxsplit=1)[-1].split(maxsplit=1)[0]
        cls = CudaCompiler
        env.add_lang_args(cls.language, cls, for_machine)
        key = OptionKey('cuda_link_args', machine=for_machine)
        if not env.is_cross_build(for_machine):
            key = key.as_host()
        if key in env.options:
            # To fix LDFLAGS issue
            val = env.options[key]
            assert isinstance(val, list)
            env.coredata.optstore.set_option(key, cls.to_host_flags_base(val, Phase.LINKER))
        linker = CudaLinker(compiler, env, for_machine, CudaCompiler.LINKER_OPTION_STYLE, [], version=CudaLinker.parse_version())
        return cls(ccache, compiler, version, for_machine, cpp_compiler, env, linker=linker)

    _handle_exceptions(popen_exceptions, compilers)
    raise EnvironmentException(f'Unknown compiler {compilers}')

def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    from . import fortran
    from ..linkers import linkers
    popen_exceptions: T.Dict[str, T.Union[Exception, str]] = {}
    compilers, ccache = _get_compilers(env, 'fortran', for_machine)
    cls: T.Type[FortranCompiler]
    for compiler in compilers:
        # capture help text for possible fallback
        try:
            _, help_out, _ = Popen_safe_logged(compiler + ['--help'], msg='Detecting compiler via')
        except OSError as e:
            popen_exceptions[join_args(compiler + ['--help'])] = e
            help_out = ''

        for arg in ['--version', '-V']:
            try:
                p, out, err = Popen_safe_logged(compiler + [arg], msg='Detecting compiler via')
            except OSError as e:
                popen_exceptions[join_args(compiler + [arg])] = e
                continue

            version = search_version(out)
            full_version = out.split('\n', 1)[0]

            guess_gcc_or_lcc: T.Optional[str] = None
            if 'GNU Fortran' in out:
                guess_gcc_or_lcc = 'gcc'
            if 'e2k' in out and 'lcc' in out:
                guess_gcc_or_lcc = 'lcc'

            if guess_gcc_or_lcc:
                defines = _get_gnu_compiler_defines(compiler, 'fortran')
                if not defines:
                    popen_exceptions[join_args(compiler)] = 'no pre-processor defines'
                    continue
                if guess_gcc_or_lcc == 'lcc':
                    version = _get_lcc_version_from_defines(defines)
                    cls = fortran.ElbrusFortranCompiler
                    linker = guess_nix_linker(env, compiler, cls, version, for_machine)
                    return cls(
                        compiler, version, for_machine, env,
                        defines, full_version=full_version, linker=linker)
                else:
                    version = _get_gnu_version_from_defines(defines)
                    cls = fortran.GnuFortranCompiler
                    linker = guess_nix_linker(env, compiler, cls, version, for_machine)
                    return cls(
                        compiler, version, for_machine, env,
                        defines, full_version=full_version, linker=linker)

            if 'Arm C/C++/Fortran Compiler' in out:
                cls = fortran.ArmLtdFlangFortranCompiler
                arm_ver_match = unwrap(re.search(r'version (\d+)\.(\d+)\.?(\d+)? \(build number (\d+)\)', out))
                version = '.'.join([x for x in arm_ver_match.groups() if x is not None])
                linker = guess_nix_linker(env, compiler, cls, version, for_machine)
                return cls(
                    compiler, version, for_machine, env,
                    linker=linker)
            if 'G95' in out:
                cls = fortran.G95FortranCompiler
                linker = guess_nix_linker(env, compiler, cls, version, for_machine)
                return cls(
                    compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

            if 'Sun Fortran' in err:
                version = search_version(err)
                cls = fortran.SunFortranCompiler
                linker = guess_nix_linker(env, compiler, cls, version, for_machine)
                return cls(
                    compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

            if 'Intel(R) Fortran Compiler for applications' in err:
                version = search_version(err)
                target = 'x86' if 'IA-32' in err else 'x86_64'
                cls = fortran.IntelLLVMClFortranCompiler
                env.add_lang_args(cls.language, cls, for_machine)
                linker = guess_win_linker(
                    env, ['link'], cls, version,
                    for_machine)
                return cls(
                    compiler, version, for_machine, env,
                    target, linker=linker)

            if 'Intel(R) Visual Fortran' in err or 'Intel(R) Fortran' in err:
                version = search_version(err)
                target = 'x86' if 'IA-32' in err else 'x86_64'
                cls = fortran.IntelClFortranCompiler
                env.add_lang_args(cls.language, cls, for_machine)
                linker = linkers.XilinkDynamicLinker(env, for_machine, [], version=version)
                return cls(
                    compiler, version, for_machine, env,
                    target, linker=linker)

            if 'ifort (IFORT)' in out:
                cls = fortran.IntelFortranCompiler
                linker = guess_nix_linker(env, compiler, cls, version, for_machine)
                return cls(
                    compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

            if 'ifx (IFORT)' in out or 'ifx (IFX)' in out:
                cls = fortran.IntelLLVMFortranCompiler
                linker = guess_nix_linker(env, compiler, cls, version, for_machine)
                return cls(
                    compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

            if 'PathScale EKOPath(tm)' in err:
                return fortran.PathScaleFortranCompiler(
                    compiler, version, for_machine, env,
                    full_version=full_version)

            if 'PGI Compilers' in out:
                cls = fortran.PGIFortranCompiler
                env.add_lang_args(cls.language, cls, for_machine)
                linker = linkers.PGIDynamicLinker(compiler, env, for_machine,
                                                  cls.LINKER_OPTION_STYLE, [], version=version)
                return cls(
                    compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

            if 'NVIDIA Compilers and Tools' in out:
                cls = fortran.NvidiaHPC_FortranCompiler
                env.add_lang_args(cls.language, cls, for_machine)
                linker = linkers.PGIDynamicLinker(compiler, env, for_machine,
                                                  cls.LINKER_OPTION_STYLE, [], version=version)
                return cls(
                    compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

            def _get_linker_try_windows(cls: T.Type['Compiler']) -> T.Optional['DynamicLinker']:
                linker = None
                if 'windows' in out or env.machines[for_machine].is_windows():
                    # If we're in a MINGW context this actually will use a gnu
                    # style ld, but for flang on "real" windows we'll use
                    # either link.exe or lld-link.exe
                    try:
                        linker = guess_win_linker(
                            env, compiler, cls, version,
                            for_machine, invoked_directly=False
                        )
                    except MesonException:
                        pass
                if linker is None:
                    linker = guess_nix_linker(env, compiler, cls,
                                              version, for_machine)
                return linker

            if 'flang-new' in out or 'flang LLVM compiler' in help_out:
                cls = fortran.LlvmFlangFortranCompiler
                linker = _get_linker_try_windows(cls)
                return cls(
                    compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

            if 'flang' in out or 'clang' in out:
                cls = fortran.ClassicFlangFortranCompiler
                linker = _get_linker_try_windows(cls)
                return cls(
                    compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

            if 'Open64 Compiler Suite' in err:
                cls = fortran.Open64FortranCompiler
                linker = guess_nix_linker(env,
                                          compiler, cls, version, for_machine)
                return cls(
                    compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

            if 'NAG Fortran' in err:
                full_version = err.split('\n', 1)[0]
                version = full_version.split()[-1]
                cls = fortran.NAGFortranCompiler
                env.add_lang_args(cls.language, cls, for_machine)
                linker = linkers.NAGDynamicLinker(
                    compiler, env, for_machine, cls.LINKER_OPTION_STYLE, [],
                    version=version)
                return cls(
                    compiler, version, for_machine, env,
                    full_version=full_version, linker=linker)

    _handle_exceptions(popen_exceptions, compilers)
    raise EnvironmentException('Unreachable code (exception to make mypy happy)')

def detect_objc_compiler(env: 'Environment', for_machine: MachineChoice) -> 'Compiler':
    return _detect_objc_or_objcpp_compiler(env, 'objc', for_machine)

def detect_objcpp_compiler(env: 'Environment', for_machine: MachineChoice) -> 'Compiler':
    return _detect_objc_or_objcpp_compiler(env, 'objcpp', for_machine)

def _detect_objc_or_objcpp_compiler(env: 'Environment', lang: str, for_machine: MachineChoice) -> 'Compiler':
    from . import objc, objcpp
    popen_exceptions: T.Dict[str, T.Union[Exception, str]] = {}
    compilers, ccache_exe = _get_compilers(env, lang, for_machine)
    ccache = ccache_exe.get_command() if (ccache_exe and ccache_exe.found()) else []
    comp: T.Union[T.Type[objc.ObjCCompiler], T.Type[objcpp.ObjCPPCompiler]]

    for compiler in compilers:
        arg = ['--version']
        try:
            p, out, err = Popen_safe_logged(compiler + arg, msg='Detecting compiler via')
        except OSError as e:
            popen_exceptions[join_args(compiler + arg)] = e
            continue
        version = search_version(out)
        if 'Free Software Foundation' in out:
            defines = _get_gnu_compiler_defines(compiler, lang)
            if not defines:
                popen_exceptions[join_args(compiler)] = 'no pre-processor defines'
                continue
            version = _get_gnu_version_from_defines(defines)
            comp = objc.GnuObjCCompiler if lang == 'objc' else objcpp.GnuObjCPPCompiler
            linker = guess_nix_linker(env, compiler, comp, version, for_machine)
            c = comp(
                ccache, compiler, version, for_machine, env,
                defines, linker=linker)
            if not c.compiles('int main(void) { return 0; }')[0]:
                popen_exceptions[join_args(compiler)] = f'GCC was not built with support for {"objective-c" if lang == "objc" else "objective-c++"}'
                continue
            return c
        if 'clang' in out:
            linker = None
            defines = _get_clang_compiler_defines(compiler, lang)
            if not defines:
                popen_exceptions[join_args(compiler)] = 'no pre-processor defines'
                continue
            if 'Apple' in out:
                comp = objc.AppleClangObjCCompiler if lang == 'objc' else objcpp.AppleClangObjCPPCompiler
            else:
                comp = objc.ClangObjCCompiler if lang == 'objc' else objcpp.ClangObjCPPCompiler
            if 'windows' in out or env.machines[for_machine].is_windows():
                # If we're in a MINGW context this actually will use a gnu style ld
                try:
                    linker = guess_win_linker(env, compiler, comp, version, for_machine)
                except MesonException:
                    pass

            if not linker:
                linker = guess_nix_linker(env, compiler, comp, version, for_machine)
            return comp(
                ccache, compiler, version, for_machine,
                env, linker=linker, defines=defines)
    _handle_exceptions(popen_exceptions, compilers)
    raise EnvironmentException('Unreachable code (exception to make mypy happy)')

def detect_java_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    from .java import JavaCompiler
    exelist = env.lookup_binary_entry(for_machine, 'java')
    if exelist is None:
        # TODO support fallback
        exelist = [defaults['java'][0]]

    try:
        p, out, err = Popen_safe_logged(exelist + ['-version'], msg='Detecting compiler via')
    except OSError:
        raise EnvironmentException('Could not execute Java compiler: {}'.format(join_args(exelist)))
    if 'javac' in out or 'javac' in err:
        version = search_version(err if 'javac' in err else out)
        if not version or version == 'unknown version':
            parts = (err if 'javac' in err else out).split()
            if len(parts) > 1:
                version = parts[1]
        comp_class = JavaCompiler
        env.add_lang_args(comp_class.language, comp_class, for_machine)
        return comp_class(exelist, version, for_machine, env)
    raise EnvironmentException('Unknown compiler: ' + join_args(exelist))

def detect_cs_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    from . import cs
    compilers, ccache = _get_compilers(env, 'cs', for_machine)
    popen_exceptions = {}
    for comp in compilers:
        try:
            p, out, err = Popen_safe_logged(comp + ['--version'], msg='Detecting compiler via')
        except OSError as e:
            popen_exceptions[join_args(comp + ['--version'])] = e
            continue

        version = search_version(out)
        cls: T.Type[cs.CsCompiler]
        if 'Mono' in out:
            cls = cs.MonoCompiler
        elif "Visual C#" in out:
            cls = cs.VisualStudioCsCompiler
        else:
            continue
        env.add_lang_args(cls.language, cls, for_machine)
        return cls(comp, version, for_machine, env)

    _handle_exceptions(popen_exceptions, compilers)
    raise EnvironmentException('Unreachable code (exception to make mypy happy)')

def detect_cython_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    """Search for a cython compiler."""
    from .cython import CythonCompiler
    compilers, _ = _get_compilers(env, 'cython', MachineChoice.BUILD)

    popen_exceptions: T.Dict[str, Exception] = {}
    for comp in compilers:
        try:
            _, out, err = Popen_safe_logged(comp + ['-V'], msg='Detecting compiler via')
        except OSError as e:
            popen_exceptions[join_args(comp + ['-V'])] = e
            continue

        version: T.Optional[str] = None
        # 3.0
        if 'Cython' in out:
            version = search_version(out)
        # older
        elif 'Cython' in err:
            version = search_version(err)
        if version is not None:
            comp_class = CythonCompiler
            env.add_lang_args(comp_class.language, comp_class, for_machine)
            return comp_class([], comp, version, for_machine, env)
    _handle_exceptions(popen_exceptions, compilers)
    raise EnvironmentException('Unreachable code (exception to make mypy happy)')

def detect_vala_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    from .vala import ValaCompiler
    exelist = env.lookup_binary_entry(for_machine, 'vala')
    if exelist is None:
        # TODO support fallback
        exelist = [defaults['vala'][0]]

    try:
        p, out = Popen_safe_logged(exelist + ['--version'], msg='Detecting compiler via')[0:2]
    except OSError:
        raise EnvironmentException('Could not execute Vala compiler: {}'.format(join_args(exelist)))
    version = search_version(out)
    if 'Vala' in out:
        comp_class = ValaCompiler
        env.add_lang_args(comp_class.language, comp_class, for_machine)
        return comp_class(exelist, version, for_machine, env)
    raise EnvironmentException('Unknown compiler: ' + join_args(exelist))

def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> RustCompiler:
    from . import rust
    from ..linkers import linkers
    popen_exceptions: T.Dict[str, Exception] = {}
    compilers, _ = _get_compilers(env, 'rust', for_machine)
    override = env.lookup_binary_entry(for_machine, 'rust_ld')

    for compiler in compilers:
        arg = ['--version']
        try:
            out = Popen_safe_logged(compiler + arg, msg='Detecting compiler via')[1]
        except OSError as e:
            popen_exceptions[join_args(compiler + arg)] = e
            continue

        # Full version contains the "-nightly" or "-beta" suffixes, but version
        # should just be X.Y.Z
        full_version = search_version(out)
        version = full_version.split('-', 1)[0]

        cls: T.Type[RustCompiler] = rust.RustCompiler

        # Clippy is a wrapper around rustc, but it doesn't have rustc in its
        # output. We can otherwise treat it as rustc.
        if 'clippy' in out:
            # clippy returns its own version and not the rustc version by
            # default so try harder here to get the correct version.
            # Also replace the whole output with the rustc output in
            # case this is later used for other purposes.
            arg = ['--rustc', '--version']
            try:
                out = Popen_safe(compiler + arg)[1]
            except OSError as e:
                popen_exceptions[join_args(compiler + arg)] = e
                continue
            full_version = search_version(out)
            version = full_version.split('-', 1)[0]

            cls = rust.ClippyRustCompiler
            mlog.deprecation(
                'clippy-driver is not intended as a general purpose compiler. '
                'You can use "ninja clippy" in order to run clippy on a '
                'meson project.')

        if 'rustc' in out:
            # On Linux and mac rustc will invoke gcc (clang for mac
            # presumably) and it can do this windows, for dynamic linking.
            # this means the easiest way to figure out what linker to use
            # is to just get the value of the C compiler and use that as
            # the basis of the rust linker.
            #
            # However, there are two things we need to change, if CC is not
            # the default use that, and second add the necessary arguments
            # to rust to use -fuse-ld
            #
            # For MSVC targets, require an MSVC-compatible C compiler to get
            # the corresponding linker
            rust_target = rust.parse_target(compiler)
            if rust_target and rust_target.endswith('-msvc'):
                try:
                    cc = _detect_c_or_cpp_compiler(env, 'c', for_machine,
                                                   override_compilers=[['cl'], ['clang-cl']])
                except EnvironmentException:
                    popen_exceptions[join_args(compiler)] = \
                        EnvironmentException('No MSVC-compatible C compiler found for MSVC Rust target')
                    continue
            else:
                try:
                    cc = detect_c_compiler(env, for_machine)
                except EnvironmentException as e:
                    popen_exceptions[join_args(compiler)] = e
                    continue

            is_link_exe = isinstance(cc.linker, linkers.VisualStudioLikeLinkerMixin)

            if any(a.startswith('linker=') for a in compiler):
                mlog.warning(
                    'Please do not put -C linker= in your compiler '
                    'command, set rust_ld=command in your cross file '
                    'or use the RUSTC_LD environment variable, otherwise meson '
                    'will override your selection.')

            compiler = compiler.copy()  # avoid mutating the original list

            if override is None:
                assert cc.linker is not None, 'for mypy'
                linker: DynamicLinker
                exelist = cc.get_linker_exelist()
                if is_link_exe:
                    # This trickery with type() gets us the class of the linker
                    # so we can initialize a new copy for the Rust Compiler
                    # Due to initializer mismatch we can't use the VisualStudioLikeMixin here
                    # But all of these have the same API so we can just pick one.
                    linker = T.cast('T.Type[linkers.MSVCDynamicLinker]', type(cc.linker))(
                        env, for_machine, always_args=[],
                        exelist=exelist, version=cc.linker.version,
                        direct=True, machine=cc.linker.machine)
                else:
                    linker = type(cc.linker)(exelist, env, for_machine, cc.LINKER_OPTION_STYLE,
                                             always_args=[], system=cc.linker.system,
                                             version=cc.linker.version)
                    exelist += cc.linker.get_always_args()
            elif 'link' in override[0]:
                linker = guess_win_linker(env,
                                          override, cls, version, for_machine, wrap_linker_args=False)
                # rustc takes linker arguments without a prefix, and
                # inserts the correct prefix itself.
                assert isinstance(linker, linkers.VisualStudioLikeLinkerMixin)
                linker.direct = True
                exelist = linker.get_exelist()
            else:
                # On linux and macos rust will invoke the c compiler for
                # linking, on windows it will use lld-link or link.exe.
                # we will simply ask for the C compiler that corresponds to
                # it, and use that.
                cc = _detect_c_or_cpp_compiler(env, 'c', for_machine, override_compilers=[override])
                linker = cc.linker
                exelist = cc.get_linker_exelist()

            c = exelist.pop(0)
            compiler.extend(cls.use_linker_args(c, ''))
            compiler.extend(rust.rustc_link_args(exelist))

            env.add_lang_args(cls.language, cls, for_machine)
            return cls(
                compiler, version, for_machine, env,
                linker=linker, full_version=full_version)

    _handle_exceptions(popen_exceptions, compilers)
    raise EnvironmentException('Unreachable code (exception to make mypy happy)')

def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    from . import c, d

    # Detect the target architecture, required for proper architecture handling on Windows.
    # MSVC compiler is required for correct platform detection.
    c_compiler: CompilerDict = {'c': detect_c_compiler(env, for_machine)}
    is_msvc = isinstance(c_compiler['c'], c.VisualStudioCCompiler)
    if not is_msvc:
        c_compiler = {}

    arch = detect_cpu_family(c_compiler)
    if is_msvc and arch == 'x86':
        arch = 'x86_mscoff'

    popen_exceptions = {}
    info = env.machines[for_machine]
    compilers, ccache = _get_compilers(env, 'd', for_machine)
    cls: T.Type[d.DCompiler]
    for exelist in compilers:
        # Search for a D compiler.
        # We prefer LDC over GDC unless overridden with the DC
        # environment variable because LDC has a much more
        # up to date language version at time (2016).
        if os.path.basename(exelist[-1]).startswith(('ldmd', 'gdmd')):
            raise EnvironmentException(
                f'Meson does not support {exelist[-1]} as it is only a DMD frontend for another compiler.'
                'Please provide a valid value for DC or unset it so that Meson can resolve the compiler by itself.')
        try:
            p, out = Popen_safe(exelist + ['--version'])[0:2]
        except OSError as e:
            popen_exceptions[join_args(exelist + ['--version'])] = e
            continue
        version = search_version(out)
        full_version = out.split('\n', 1)[0]

        # The OpenD fork should stay close enough to upstream D (in
        # the areas that interest us) to allow supporting them both
        # without much hassle.
        # See: https://github.com/orgs/opendlang/discussions/56
        if 'LLVM D compiler' in out or 'LLVM Open D compiler' in out:
            cls = d.LLVMDCompiler
            # LDC seems to require a file
            # We cannot use NamedTemporaryFile on windows, its documented
            # to not work for our uses. So, just use mkstemp and only have
            # one path for simplicity.
            o, f = tempfile.mkstemp('.d')
            os.close(o)

            try:
                if info.is_windows() or info.is_cygwin():
                    objfile = os.path.basename(f)[:-1] + 'obj'
                    extra_args = [f]
                    if env.is_cross_build(for_machine):
                        extra_args.append(f'-mtriple={info.cpu}-windows')

                    linker = guess_win_linker(env,
                                              exelist,
                                              cls, full_version, for_machine,
                                              wrap_linker_args=True, invoked_directly=False,
                                              extra_args=extra_args)
                else:
                    # LDC writes an object file to the current working directory.
                    # Clean it up.
                    objfile = os.path.basename(f)[:-1] + 'o'
                    linker = guess_nix_linker(env,
                                              exelist, cls, full_version, for_machine,
                                              extra_args=[f])
            finally:
                windows_proof_rm(f)
                windows_proof_rm(objfile)

            return cls(
                exelist, version, for_machine, env, arch,
                full_version=full_version, linker=linker,
                version_output=out)
        elif 'gdc' in out:
            cls = d.GnuDCompiler
            linker = guess_nix_linker(env, exelist, cls, version, for_machine)
            return cls(
                exelist, version, for_machine, env, arch,
                full_version=full_version, linker=linker)
        elif 'The D Language Foundation' in out or 'Digital Mars' in out:
            cls = d.DmdDCompiler
            # DMD seems to require a file
            # We cannot use NamedTemporaryFile on windows, its documented
            # to not work for our uses. So, just use mkstemp and only have
            # one path for simplicity.
            o, f = tempfile.mkstemp('.d')
            os.close(o)

            # DMD as different detection logic for x86 and x86_64
            arch_arg = '-m64' if arch == 'x86_64' else '-m32'

            try:
                if info.is_windows() or info.is_cygwin():
                    objfile = os.path.basename(f)[:-1] + 'obj'
                    linker = guess_win_linker(env,
                                              exelist, cls, full_version, for_machine,
                                              invoked_directly=False, extra_args=[f, arch_arg])
                else:
                    objfile = os.path.basename(f)[:-1] + 'o'
                    linker = guess_nix_linker(env,
                                              exelist, cls, full_version, for_machine,
                                              extra_args=[f, arch_arg])
            finally:
                windows_proof_rm(f)
                windows_proof_rm(objfile)

            return cls(
                exelist, version, for_machine, env, arch,
                full_version=full_version, linker=linker)
        raise EnvironmentException('Unknown compiler: ' + join_args(exelist))

    _handle_exceptions(popen_exceptions, compilers)
    raise EnvironmentException('Unreachable code (exception to make mypy happy)')

def detect_swift_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    from .swift import SwiftCompiler
    exelist = env.lookup_binary_entry(for_machine, 'swift')
    if exelist is None:
        # TODO support fallback
        exelist = [defaults['swift'][0]]

    try:
        p, _, err = Popen_safe_logged(exelist + ['-v'], msg='Detecting compiler via')
    except OSError:
        raise EnvironmentException('Could not execute Swift compiler: {}'.format(join_args(exelist)))
    version = search_version(err)
    if 'Swift' in err:
        # As for 5.0.1 swiftc *requires* a file to check the linker:
        with tempfile.NamedTemporaryFile(suffix='.swift') as f:
            cls = SwiftCompiler
            linker = guess_nix_linker(env,
                                      exelist, cls, version, for_machine,
                                      extra_args=[f.name, '-o', '/dev/null'])
        return cls(
            exelist, version, for_machine, env, linker=linker)

    raise EnvironmentException('Unknown compiler: ' + join_args(exelist))

def detect_nasm_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    from .asm import NasmCompiler, YasmCompiler, MetrowerksAsmCompilerARM, MetrowerksAsmCompilerEmbeddedPowerPC

    # When cross compiling and nasm is not defined in the cross file we can
    # fallback to the build machine nasm.
    compilers, _ = _get_compilers(env, 'nasm', for_machine, allow_build_machine=True)

    # We need a C compiler to properly detect the machine info and linker
    cc = detect_c_compiler(env, for_machine)
    if not env.is_cross_build(for_machine):
        env.update_build_machine({'c': cc})

    popen_exceptions: T.Dict[str, Exception] = {}
    for comp in compilers:
        if comp == ['nasm'] and is_windows() and not shutil.which(comp[0]):
            # nasm is not in PATH on Windows by default
            default_path = os.path.join(os.environ['ProgramFiles'], 'NASM')
            comp[0] = shutil.which(comp[0], path=default_path) or comp[0]
        try:
            output = Popen_safe_logged(comp + ['--version'], msg='Detecting compiler via')[1]
        except OSError as e:
            popen_exceptions[' '.join(comp + ['--version'])] = e
            continue

        version = search_version(output)
        comp_class: T.Type[ASMCompiler]
        if 'NASM' in output:
            comp_class = NasmCompiler
            env.add_lang_args(comp_class.language, comp_class, for_machine)
            return comp_class([], comp, version, for_machine, env, cc.linker)
        elif 'yasm' in output:
            comp_class = YasmCompiler
            env.add_lang_args(comp_class.language, comp_class, for_machine)
            return comp_class([], comp, version, for_machine, env, cc.linker)
        elif 'Metrowerks' in output or 'Freescale' in output:
            if 'ARM' in output:
                comp_class_mwasmarm = MetrowerksAsmCompilerARM
                env.add_lang_args(comp_class_mwasmarm.language, comp_class_mwasmarm, for_machine)
                return comp_class_mwasmarm([], comp, version, for_machine, env, cc.linker)
            else:
                comp_class_mwasmeppc = MetrowerksAsmCompilerEmbeddedPowerPC
                env.add_lang_args(comp_class_mwasmeppc.language, comp_class_mwasmeppc, for_machine)
                return comp_class_mwasmeppc([], comp, version, for_machine, env, cc.linker)

    _handle_exceptions(popen_exceptions, compilers)
    raise EnvironmentException('Unreachable code (exception to make mypy happy)')

def detect_masm_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    # We need a C compiler to properly detect the machine info and linker
    cc = detect_c_compiler(env, for_machine)
    if not env.is_cross_build(for_machine):
        env.update_build_machine({'c': cc})

    info = env.machines[for_machine]

    from .asm import MasmCompiler, MasmARMCompiler
    comp_class: T.Type[ASMCompiler]
    if info.cpu_family == 'x86':
        comp = ['ml']
        comp_class = MasmCompiler
        arg = '/?'
    elif info.cpu_family == 'x86_64':
        comp = ['ml64']
        comp_class = MasmCompiler
        arg = '/?'
    elif info.cpu_family == 'arm':
        comp = ['armasm']
        comp_class = MasmARMCompiler
        arg = '-h'
    elif info.cpu_family == 'aarch64':
        comp = ['armasm64']
        comp_class = MasmARMCompiler
        arg = '-h'
    else:
        raise EnvironmentException(f'Platform {info.cpu_family} not supported by MASM')

    popen_exceptions: T.Dict[str, Exception] = {}
    try:
        output = Popen_safe(comp + [arg])[2]
        version = search_version(output)
        env.add_lang_args(comp_class.language, comp_class, for_machine)
        return comp_class([], comp, version, for_machine, env, cc.linker)
    except OSError as e:
        popen_exceptions[' '.join(comp + [arg])] = e
    _handle_exceptions(popen_exceptions, [comp])
    raise EnvironmentException('Unreachable code (exception to make mypy happy)')

def detect_linearasm_compiler(env: Environment, for_machine: MachineChoice) -> Compiler:
    from .asm import TILinearAsmCompiler
    comp = ['cl6x']
    comp_class: T.Type[ASMCompiler] = TILinearAsmCompiler
    arg = '-h'
    cc = detect_c_compiler(env, for_machine)
    if not env.is_cross_build(for_machine):
        env.update_build_machine({'c': cc})

    popen_exceptions: T.Dict[str, Exception] = {}
    try:
        output = Popen_safe(comp + [arg])[2]
        version = search_version(output)
        env.add_lang_args(comp_class.language, comp_class, for_machine)
        return comp_class([], comp, version, for_machine, env, cc.linker)
    except OSError as e:
        popen_exceptions[' '.join(comp + [arg])] = e
    _handle_exceptions(popen_exceptions, [comp])
    raise EnvironmentException('Unreachable code (exception to make mypy happy)')

# GNU/Clang defines and version
# =============================

def _get_gnu_compiler_defines(compiler: T.List[str], lang: str) -> T.Dict[str, str]:
    """
    Get the list of GCC pre-processor defines
    """
    from .mixins.gnu import gnu_lang_map

    def _try_obtain_compiler_defines(args: T.List[str]) -> str:
        mlog.debug(f'Running command: {join_args(args)}')
        p, output, error = Popen_safe(compiler + args, write='', stdin=subprocess.PIPE)
        if p.returncode != 0:
            raise EnvironmentException('Unable to get gcc pre-processor defines:\n'
                                       f'Compiler stdout:\n{output}\n-----\n'
                                       f'Compiler stderr:\n{error}\n-----\n')
        return output

    # Arguments to output compiler pre-processor defines to stdout
    # gcc, g++, and gfortran all support these arguments
    baseline_test_args = ['-E', '-dM', '-']
    try:
        # We assume that when _get_gnu_compiler_defines is called, it's
        # close enough to a GCCish compiler so we reuse the _LANG_MAP
        # from the GCC mixin. This isn't a dangerous assumption because
        # we fallback if the detection fails anyway.

        # We might not have a match for Fortran, so fallback to detection
        # based on the driver.
        lang = gnu_lang_map[lang]

        # The compiler may not infer the target language based on the driver name
        # so first, try with '-cpp -x lang', then fallback without given it's less
        # portable. We try with '-cpp' as GCC needs it for Fortran at least, and
        # it seems to do no harm.
        output = _try_obtain_compiler_defines(['-cpp', '-x', lang] + baseline_test_args)
    except (EnvironmentException, KeyError):
        mlog.debug(f'pre-processor extraction using -cpp -x {lang} failed, falling back w/o lang')
        output = _try_obtain_compiler_defines(baseline_test_args)

    # Parse several lines of the type:
    # `#define ___SOME_DEF some_value`
    # and extract `___SOME_DEF`
    defines: T.Dict[str, str] = {}
    for line in output.split('\n'):
        if not line:
            continue
        d, *rest = line.split(' ', 2)
        if d != '#define':
            continue
        if len(rest) == 1:
            defines[rest[0]] = ''
        if len(rest) == 2:
            defines[rest[0]] = rest[1]
    return defines

def _get_clang_compiler_defines(compiler: T.List[str], lang: str) -> T.Dict[str, str]:
    """
    Get the list of Clang pre-processor defines
    """
    from .mixins.clang import clang_lang_map

    def _try_obtain_compiler_defines(args: T.List[str]) -> str:
        mlog.debug(f'Running command: {join_args(args)}')
        p, output, error = Popen_safe(compiler + args, write='', stdin=subprocess.PIPE)
        if p.returncode != 0:
            raise EnvironmentException('Unable to get clang pre-processor defines:\n'
                                       f'Compiler stdout:\n{output}\n-----\n'
                                       f'Compiler stderr:\n{error}\n-----\n')
        return output

    # Arguments to output compiler pre-processor defines to stdout
    baseline_test_args = ['-E', '-dM', '-']
    try:
        # We assume that when _get_clang_compiler_defines is called, it's
        # close enough to a Clangish compiler so we reuse the _LANG_MAP
        # from the Clang mixin. This isn't a dangerous assumption because
        # we fallback if the detection fails anyway.

        # We might not have a match for Fortran, so fallback to detection
        # based on the driver.
        lang = clang_lang_map[lang]

        # The compiler may not infer the target language based on the driver name.
        # Try first with '-x lang' to supported systemwide language level overrides,
        # then fallback to without since it's a more recent option.
        output = _try_obtain_compiler_defines(['-x', lang] + baseline_test_args)
    except (EnvironmentException, KeyError):
        mlog.debug(f'pre-processor extraction using -x {lang} failed, falling back w/o lang')
        output = _try_obtain_compiler_defines(baseline_test_args)

    defines: T.Dict[str, str] = {}
    for line in output.split('\n'):
        if not line:
            continue
        d, *rest = line.split(' ', 2)
        if d != '#define':
            continue
        if len(rest) == 1:
            defines[rest[0]] = ''
        if len(rest) == 2:
            defines[rest[0]] = rest[1]
    return defines

def _get_gnu_version_from_defines(defines: T.Dict[str, str]) -> str:
    dot = '.'
    major = defines.get('__GNUC__', '0')
    minor = defines.get('__GNUC_MINOR__', '0')
    patch = defines.get('__GNUC_PATCHLEVEL__', '0')
    return dot.join((major, minor, patch))

def _get_lcc_version_from_defines(defines: T.Dict[str, str]) -> str:
    dot = '.'
    generation_and_major = defines.get('__LCC__', '100')
    generation = generation_and_major[:1]
    major = generation_and_major[1:]
    minor = defines.get('__LCC_MINOR__', '0')
    return dot.join((generation, major, minor))
