# 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, windows_proof_rm,
)
from ..envconfig import BinaryTable
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 Compiler
    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
    from ..programs import ExternalProgram


# 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 microsofts
    # 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']
    defaults['fortran'] = ['ifort', 'gfortran', 'flang', 'pgfortran', 'g95']
    # Clang and clang++ are valid, but currently unsupported.
    defaults['objc'] = ['cc', 'gcc']
    defaults['objcpp'] = ['c++', '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'] = ['cc', 'gcc', 'clang']
        defaults['objcpp'] = ['c++', 'g++', 'clang++']
    defaults['fortran'] = ['gfortran', '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['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,
    }
    return lang_map[lang](env, for_machine) if lang in lang_map else None

def detect_compiler_for(env: 'Environment', lang: str, 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, env, subproject)
    if not skip_sanity_check:
        comp.sanity_check(env.get_scratch_dir(), env)
    env.coredata.compilers[comp.for_machine][lang] = comp
    return comp


# Helpers
# =======

def _get_compilers(env: 'Environment', lang: str, for_machine: MachineChoice) -> T.Tuple[T.List[T.List[str]], T.List[str], T.Optional['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):
            raise EnvironmentException(f'{lang!r} compiler binary not defined in cross or native file')
        compilers = [[x] for x in defaults[lang]]
        ccache = BinaryTable.detect_compiler_cache()

    if env.machines.matches_build_machine(for_machine):
        exe_wrap: T.Optional[ExternalProgram] = None
    else:
        exe_wrap = env.get_exe_wrapper()

    return compilers, ccache, exe_wrap

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():
            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
    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 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 it's 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', 'armar', 'armar.exe', 'ar6x', 'ar6x.exe'}:
            arg = '?'
        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, getattr(compiler, 'machine', None))
        if '/OUT:' in out.upper() or '/OUT:' in err.upper():
            return linkers.VisualStudioLinker(linker, getattr(compiler, 'machine', None))
        if 'ar-Error-Unknown switch: --version' in err:
            return linkers.PGIStaticLinker(linker)
        if p.returncode == 0 and 'armar' in linker_name:
            return linkers.ArmarLinker(linker)
        if 'DMD32 D Compiler' in out or 'DMD64 D Compiler' in out:
            assert isinstance(compiler, d.DCompiler)
            return linkers.DLinker(linker, compiler.arch)
        if 'LDC - the LLVM D compiler' in out:
            assert isinstance(compiler, d.DCompiler)
            return linkers.DLinker(linker, 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, compiler.arch)
        if err.startswith('Renesas') and 'rlink' in linker_name:
            return linkers.CcrxLinker(linker)
        if out.startswith('GNU ar') and 'xc16-ar' in linker_name:
            return linkers.Xc16Linker(linker)
        if "-->  error: bad option 'e'" in err: # TI
            if 'ar2000' in linker_name:
                return linkers.C2000Linker(linker)
            else:
                return linkers.TILinker(linker)
        if 'Texas Instruments Incorporated' in out:
            if 'ar6000' in linker_name:
                return linkers.C6000Linker(linker)
        if out.startswith('The CompCert'):
            return linkers.CompCertLinker(linker)
        if out.strip().startswith('Metrowerks') or out.strip().startswith('Freescale'):
            if 'ARM' in out:
                return linkers.MetrowerksStaticLinkerARM(linker)
            else:
                return linkers.MetrowerksStaticLinkerEmbeddedPowerPC(linker)
        if p.returncode == 0:
            return linkers.ArLinker(compiler.for_machine, linker)
        if p.returncode == 1 and err.startswith('usage'): # OSX
            return linkers.AppleArLinker(compiler.for_machine, linker)
        if p.returncode == 1 and err.startswith('Usage'): # AIX
            return linkers.AIXArLinker(linker)
        if p.returncode == 1 and err.startswith('ar: bad option: --'): # Solaris
            return linkers.ArLinker(compiler.for_machine, linker)
    _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_compiler: T.Optional[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_wrap = _get_compilers(env, lang, for_machine)
    if override_compiler is not None:
        compilers = [override_compiler]
    is_cross = env.is_cross_build(for_machine)
    info = env.machines[for_machine]
    cls: T.Union[T.Type[CCompiler], T.Type[CPPCompiler]]
    lnk: T.Union[T.Type[StaticLinker], T.Type[DynamicLinker]]

    for compiler in compilers:
        if isinstance(compiler, str):
            compiler = [compiler]
        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 it's 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: str) -> str:
                    return os.path.normcase(os.path.abspath(p))

                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 Technology' 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)
            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, is_cross,
                info, exe_wrap, defines=defines, full_version=full_version,
                linker=linker)

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

            # 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_PREFIX + "--version", f.name]
                _, o, _ = Popen_safe(cmd)

            linker = linkers.WASMDynamicLinker(
                compiler, for_machine, cls.LINKER_PREFIX,
                [], version=search_version(o))
            return cls(
                ccache, compiler, version, for_machine, is_cross, info,
                exe_wrap, linker=linker, full_version=full_version)

        if 'Arm C/C++/Fortran Compiler' in out:
            arm_ver_match = re.search(r'version (\d+)\.(\d+)\.?(\d+)? \(build number (\d+)\)', out)
            assert arm_ver_match is not None, 'for mypy'  # because mypy *should* be complaining that this could be None
            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, is_cross, info,
                exe_wrap, 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(for_machine, version=version)
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            return cls(
                ccache, compiler, version, for_machine, is_cross, info,
                exe_wrap, 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, is_cross, info, target,
                exe_wrap, 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 indentifier, compiler_classes in ti_compilers.items():
            if indentifier in out:
                cls = compiler_classes[0] if lang == 'c' else compiler_classes[1]
                lnk = compiler_classes[2]
                env.coredata.add_lang_args(cls.language, cls, for_machine, env)
                linker = lnk(compiler, for_machine, version=version)
                return cls(
                    ccache, compiler, version, for_machine, is_cross, info,
                    exe_wrap, full_version=full_version, linker=linker)

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

            defines = _get_clang_compiler_defines(compiler)

            # 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, is_cross, info,
                exe_wrap, 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.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
            return cls(
                compiler, version, for_machine, is_cross, info, target,
                exe_wrap, 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.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
            return cls(
                compiler, version, for_machine, is_cross, info, target,
                exe_wrap, 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)
            # As of this writing, CCache does not support MSVC but sccache does.
            if 'sccache' not in ccache:
                ccache = []
            return cls(
                ccache, compiler, version, for_machine, is_cross, info, target,
                exe_wrap, full_version=cl_signature, linker=linker)
        if 'PGI Compilers' in out:
            cls = c.PGICCompiler if lang == 'c' else cpp.PGICPPCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = linkers.PGIDynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version)
            return cls(
                ccache, compiler, version, for_machine, is_cross,
                info, exe_wrap, linker=linker)
        if 'NVIDIA Compilers and Tools' in out:
            cls = c.NvidiaHPC_CCompiler if lang == 'c' else cpp.NvidiaHPC_CPPCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = linkers.NvidiaHPC_DynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version)
            return cls(
                ccache, compiler, version, for_machine, is_cross,
                info, exe_wrap, 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, is_cross, info,
                exe_wrap, 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, is_cross, info,
                exe_wrap, 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.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = linkers.ArmDynamicLinker(for_machine, version=version)
            return cls(
                ccache, compiler, version, for_machine, is_cross,
                info, exe_wrap, full_version=full_version, linker=linker)
        if 'RX Family' in out:
            cls = c.CcrxCCompiler if lang == 'c' else cpp.CcrxCPPCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = linkers.CcrxDynamicLinker(for_machine, version=version)
            return cls(
                ccache, compiler, version, for_machine, is_cross, info,
                exe_wrap, full_version=full_version, linker=linker)

        if 'Microchip Technology' in out:
            cls = c.Xc16CCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = linkers.Xc16DynamicLinker(for_machine, version=version)
            return cls(
                ccache, compiler, version, for_machine, is_cross, info,
                exe_wrap, full_version=full_version, linker=linker)

        if 'CompCert' in out:
            cls = c.CompCertCCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = linkers.CompCertDynamicLinker(for_machine, version=version)
            return cls(
                ccache, compiler, version, for_machine, is_cross, info,
                exe_wrap, 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 = re.search(r'Version (\d+)\.(\d+)\.?(\d+)? build (\d+)', out)
            assert mwcc_ver_match is not None, 'for mypy'  # because mypy *should* be complaning that this could be None
            compiler_version = '.'.join(x for x in mwcc_ver_match.groups() if x is not None)

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

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

                mwld_ver_match = re.search(r'Version (\d+)\.(\d+)\.?(\d+)? build (\d+)', o_ld)
                assert mwld_ver_match is not None, 'for mypy'  # because mypy *should* be complaning that this could be None
                linker_version = '.'.join(x for x in mwld_ver_match.groups() if x is not None)

                linker = lnk(ld, 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, is_cross, info,
                exe_wrap, 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
    from ..linkers.linkers import CudaLinker
    popen_exceptions = {}
    is_cross = env.is_cross_build(for_machine)
    compilers, ccache, exe_wrap = _get_compilers(env, 'cuda', for_machine)
    info = env.machines[for_machine]
    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
        # Luckily, the "V" also makes it very simple to extract
        # the full version:
        version = out.strip().rsplit('V', maxsplit=1)[-1]
        cpp_compiler = detect_cpp_compiler(env, for_machine)
        cls = CudaCompiler
        env.coredata.add_lang_args(cls.language, cls, for_machine, env)
        linker = CudaLinker(compiler, for_machine, CudaCompiler.LINKER_PREFIX, [], version=CudaLinker.parse_version())
        return cls(ccache, compiler, version, for_machine, is_cross, exe_wrap, host_compiler=cpp_compiler, info=info, linker=linker)
    raise EnvironmentException(f'Could not find suitable CUDA compiler: "{"; ".join([" ".join(c) for c in 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, exe_wrap = _get_compilers(env, 'fortran', for_machine)
    is_cross = env.is_cross_build(for_machine)
    info = env.machines[for_machine]
    cls: T.Type[FortranCompiler]
    for compiler in compilers:
        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)
                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, is_cross, info,
                        exe_wrap, 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, is_cross, info,
                        exe_wrap, defines, full_version=full_version, linker=linker)

            if 'Arm C/C++/Fortran Compiler' in out:
                cls = fortran.ArmLtdFlangFortranCompiler
                arm_ver_match = re.search(r'version (\d+)\.(\d+)\.?(\d+)? \(build number (\d+)\)', out)
                assert arm_ver_match is not None, 'for mypy'  # because mypy *should* be complaining that this could be None
                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, is_cross, info,
                    exe_wrap, 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, is_cross, info,
                    exe_wrap, 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, is_cross, info,
                    exe_wrap, 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.coredata.add_lang_args(cls.language, cls, for_machine, env)
                linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
                return cls(
                    compiler, version, for_machine, is_cross, info,
                    target, exe_wrap, 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.coredata.add_lang_args(cls.language, cls, for_machine, env)
                linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
                return cls(
                    compiler, version, for_machine, is_cross, info,
                    target, exe_wrap, 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, is_cross, info,
                    exe_wrap, 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, is_cross, info,
                    exe_wrap, full_version=full_version, linker=linker)

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

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

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

            if 'flang' in out or 'clang' in out:
                cls = fortran.FlangFortranCompiler
                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 cls(
                    compiler, version, for_machine, is_cross, info,
                    exe_wrap, 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, is_cross, info,
                    exe_wrap, 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.coredata.add_lang_args(cls.language, cls, for_machine, env)
                linker = linkers.NAGDynamicLinker(
                    compiler, for_machine, cls.LINKER_PREFIX, [],
                    version=version)
                return cls(
                    compiler, version, for_machine, is_cross, info,
                    exe_wrap, 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_wrap = _get_compilers(env, lang, for_machine)
    is_cross = env.is_cross_build(for_machine)
    info = env.machines[for_machine]
    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)
            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)
            return comp(
                ccache, compiler, version, for_machine, is_cross, info,
                exe_wrap, defines, linker=linker)
        if 'clang' in out:
            linker = None
            defines = _get_clang_compiler_defines(compiler)
            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,
                is_cross, info, exe_wrap, 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')
    info = env.machines[for_machine]
    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.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
        return comp_class(exelist, version, for_machine, info)
    raise EnvironmentException('Unknown compiler: ' + join_args(exelist))

def detect_cs_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    from . import cs
    compilers, ccache, exe_wrap = _get_compilers(env, 'cs', for_machine)
    popen_exceptions = {}
    info = env.machines[for_machine]
    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.coredata.add_lang_args(cls.language, cls, for_machine, env)
        return cls(comp, version, for_machine, info)

    _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)
    is_cross = env.is_cross_build(for_machine)
    info = env.machines[for_machine]

    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.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
            return comp_class([], comp, version, for_machine, info, is_cross=is_cross)
    _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(MachineChoice.BUILD, 'vala')
    is_cross = env.is_cross_build(for_machine)
    info = env.machines[for_machine]
    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.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
        return comp_class(exelist, version, for_machine, is_cross, info)
    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, _, exe_wrap = _get_compilers(env, 'rust', for_machine)
    is_cross = env.is_cross_build(for_machine)
    info = env.machines[for_machine]

    cc = detect_c_compiler(env, for_machine)
    is_link_exe = isinstance(cc.linker, linkers.VisualStudioLikeLinkerMixin)
    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

        version = search_version(out)
        cls: T.Type[RustCompiler] = rust.RustCompiler

        # Clippy is a wrapper around rustc, but it doesn't have rustc in it's
        # 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
            version = search_version(out)

            cls = rust.ClippyRustCompiler

        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 C compiler for dynamic linking.
            # 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

            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:
                extra_args: T.Dict[str, T.Union[str, bool]] = {}
                always_args: T.List[str] = []
                if is_link_exe:
                    compiler.extend(cls.use_linker_args(cc.linker.exelist[0], ''))
                    extra_args['direct'] = True
                    extra_args['machine'] = cc.linker.machine
                else:
                    exelist = cc.linker.exelist + cc.linker.get_always_args()
                    if os.path.basename(exelist[0]) in {'ccache', 'sccache'}:
                        del exelist[0]
                    c = exelist.pop(0)
                    compiler.extend(cls.use_linker_args(c, ''))

                    # Also ensure that we pass any extra arguments to the linker
                    for l in exelist:
                        compiler.extend(['-C', f'link-arg={l}'])

                # This trickery with type() gets us the class of the linker
                # so we can initialize a new copy for the Rust Compiler
                # TODO rewrite this without type: ignore
                assert cc.linker is not None, 'for mypy'
                if is_link_exe:
                    linker = type(cc.linker)(for_machine, always_args, exelist=cc.linker.exelist,   # type: ignore
                                             version=cc.linker.version, **extra_args)               # type: ignore
                else:
                    linker = type(cc.linker)(compiler, for_machine, cc.LINKER_PREFIX,
                                             always_args=always_args, version=cc.linker.version,
                                             **extra_args)
            elif 'link' in override[0]:
                linker = guess_win_linker(env,
                                          override, cls, version, for_machine, use_linker_prefix=False)
                # rustc takes linker arguments without a prefix, and
                # inserts the correct prefix itself.
                assert isinstance(linker, linkers.VisualStudioLikeLinkerMixin)
                linker.direct = True
                compiler.extend(cls.use_linker_args(linker.exelist[0], ''))
            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_compiler=override)
                linker = cc.linker

                # Of course, we're not going to use any of that, we just
                # need it to get the proper arguments to pass to rustc
                c = linker.exelist[1] if linker.exelist[0].endswith('ccache') else linker.exelist[0]
                compiler.extend(cls.use_linker_args(c, ''))

            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            return cls(
                compiler, version, for_machine, is_cross, info, exe_wrap,
                linker=linker)

    _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
    info = env.machines[for_machine]

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

    # Import here to avoid circular imports
    from ..environment import detect_cpu_family
    arch = detect_cpu_family(c_compiler)
    if is_msvc and arch == 'x86':
        arch = 'x86_mscoff'

    popen_exceptions = {}
    is_cross = env.is_cross_build(for_machine)
    compilers, ccache, exe_wrap = _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]

        if 'LLVM 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'
                    linker = guess_win_linker(env,
                                              exelist,
                                              cls, full_version, for_machine,
                                              use_linker_prefix=True, invoked_directly=False,
                                              extra_args=[f])
                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, info, 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, info, arch,
                exe_wrapper=exe_wrap, is_cross=is_cross,
                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, info, 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')
    is_cross = env.is_cross_build(for_machine)
    info = env.machines[for_machine]
    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])
        return cls(
            exelist, version, for_machine, is_cross, info, 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
    compilers, _, _ = _get_compilers(env, 'nasm', for_machine)
    is_cross = env.is_cross_build(for_machine)

    # We need a C compiler to properly detect the machine info and linker
    cc = detect_c_compiler(env, for_machine)
    if not is_cross:
        from ..environment import detect_machine_info
        info = detect_machine_info({'c': cc})
    else:
        info = env.machines[for_machine]

    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)
        if 'NASM' in output:
            comp_class = NasmCompiler
            env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
            return comp_class([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
        elif 'yasm' in output:
            comp_class = YasmCompiler
            env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
            return comp_class([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
        elif 'Metrowerks' in output or 'Freescale' in output:
            if 'ARM' in output:
                comp_class_mwasmarm = MetrowerksAsmCompilerARM
                env.coredata.add_lang_args(comp_class_mwasmarm.language, comp_class_mwasmarm, for_machine, env)
                return comp_class_mwasmarm([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
            else:
                comp_class_mwasmeppc = MetrowerksAsmCompilerEmbeddedPowerPC
                env.coredata.add_lang_args(comp_class_mwasmeppc.language, comp_class_mwasmeppc, for_machine, env)
                return comp_class_mwasmeppc([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)

    _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
    is_cross = env.is_cross_build(for_machine)
    cc = detect_c_compiler(env, for_machine)
    if not is_cross:
        from ..environment import detect_machine_info
        info = detect_machine_info({'c': cc})
    else:
        info = env.machines[for_machine]

    from .asm import MasmCompiler, MasmARMCompiler
    comp_class: T.Type[Compiler]
    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.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
        return comp_class([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
    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]) -> T.Dict[str, str]:
    """
    Detect GNU compiler platform type (Apple, MinGW, Unix)
    """
    # Arguments to output compiler pre-processor defines to stdout
    # gcc, g++, and gfortran all support these arguments
    args = compiler + ['-E', '-dM', '-']
    mlog.debug(f'Running command: {join_args(args)}')
    p, output, error = Popen_safe(args, write='', stdin=subprocess.PIPE)
    if p.returncode != 0:
        raise EnvironmentException('Unable to detect GNU compiler type:\n'
                                   f'Compiler stdout:\n{output}\n-----\n'
                                   f'Compiler stderr:\n{error}\n-----\n')
    # 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]) -> T.Dict[str, str]:
    """
    Get the list of Clang pre-processor defines
    """
    args = compiler + ['-E', '-dM', '-']
    mlog.debug(f'Running command: {join_args(args)}')
    p, output, error = Popen_safe(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')
    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))
