# Copyright 2012-2021 The Meson development team

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from ..mesonlib import (
    MachineChoice, MesonException, EnvironmentException,
    search_version, is_windows, Popen_safe, windows_proof_rm,
)
from ..envconfig import BinaryTable
from .. import mlog

from ..linkers import (
    guess_win_linker,
    guess_nix_linker,
    AIXArLinker,
    ArLinker,
    ArmarLinker,
    ArmClangDynamicLinker,
    ArmDynamicLinker,
    CcrxLinker,
    CcrxDynamicLinker,
    CompCertLinker,
    CompCertDynamicLinker,
    C2000Linker,
    C2000DynamicLinker,
    DLinker,
    NAGDynamicLinker,
    NvidiaHPC_DynamicLinker,
    PGIDynamicLinker,
    PGIStaticLinker,
    StaticLinker,
    Xc16Linker,
    Xc16DynamicLinker,
    XilinkDynamicLinker,
    CudaLinker,
    IntelVisualStudioLinker,
    VisualStudioLinker,
    VisualStudioLikeLinkerMixin,
    WASMDynamicLinker,
)
from .compilers import Compiler
from .c import (
    CCompiler,
    AppleClangCCompiler,
    ArmCCompiler,
    ArmclangCCompiler,
    ClangCCompiler,
    ClangClCCompiler,
    GnuCCompiler,
    ElbrusCCompiler,
    EmscriptenCCompiler,
    IntelCCompiler,
    IntelClCCompiler,
    NvidiaHPC_CCompiler,
    PGICCompiler,
    CcrxCCompiler,
    Xc16CCompiler,
    CompCertCCompiler,
    C2000CCompiler,
    VisualStudioCCompiler,
)
from .cpp import (
    CPPCompiler,
    AppleClangCPPCompiler,
    ArmCPPCompiler,
    ArmclangCPPCompiler,
    ClangCPPCompiler,
    ClangClCPPCompiler,
    GnuCPPCompiler,
    ElbrusCPPCompiler,
    EmscriptenCPPCompiler,
    IntelCPPCompiler,
    IntelClCPPCompiler,
    NvidiaHPC_CPPCompiler,
    PGICPPCompiler,
    CcrxCPPCompiler,
    C2000CPPCompiler,
    VisualStudioCPPCompiler,
)
from .cs import MonoCompiler, VisualStudioCsCompiler
from .d import (
    DCompiler,
    DmdDCompiler,
    GnuDCompiler,
    LLVMDCompiler,
)
from .cuda import CudaCompiler
from .fortran import (
    FortranCompiler,
    G95FortranCompiler,
    GnuFortranCompiler,
    ElbrusFortranCompiler,
    FlangFortranCompiler,
    IntelFortranCompiler,
    IntelClFortranCompiler,
    NAGFortranCompiler,
    Open64FortranCompiler,
    PathScaleFortranCompiler,
    NvidiaHPC_FortranCompiler,
    PGIFortranCompiler,
    SunFortranCompiler,
)
from .java import JavaCompiler
from .objc import (
    ObjCCompiler,
    AppleClangObjCCompiler,
    ClangObjCCompiler,
    GnuObjCCompiler,
)
from .objcpp import (
    ObjCPPCompiler,
    AppleClangObjCPPCompiler,
    ClangObjCPPCompiler,
    GnuObjCPPCompiler,
)
from .cython import CythonCompiler
from .rust import RustCompiler, ClippyRustCompiler
from .swift import SwiftCompiler
from .vala import ValaCompiler
from .mixins.visualstudio import VisualStudioLikeCompiler
from .mixins.gnu import GnuCompiler
from .mixins.clang import ClangCompiler

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

if T.TYPE_CHECKING:
    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']
        defaults['cpp'] = ['c++', 'g++', 'clang++', 'nvc++', 'pgc++', 'icpc']
        defaults['objc'] = ['cc', 'gcc', 'clang']
        defaults['objcpp'] = ['c++', 'g++', 'clang++']
    defaults['fortran'] = ['gfortran', 'flang', 'nvfortran', 'pgfortran', 'ifort', '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']
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']


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,
    }
    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) -> T.Optional[Compiler]:
    comp = compiler_from_language(env, lang, for_machine)
    if comp is not None:
        assert comp.for_machine == for_machine
        env.coredata.process_new_compiler(lang, comp, env)
    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:
    linker = env.lookup_binary_entry(compiler.for_machine, 'ar')
    if linker is not None:
        linkers = [linker]
    else:
        default_linkers = [[l] for l in defaults['static_linker']]
        if isinstance(compiler, CudaCompiler):
            linkers = [defaults['cuda_static_linker']] + default_linkers
        elif isinstance(compiler, VisualStudioLikeCompiler):
            linkers = [defaults['vs_static_linker'], defaults['clang_cl_static_linker']]
        elif isinstance(compiler, GnuCompiler):
            # Use gcc-ar if available; needed for LTO
            linkers = [defaults['gcc_static_linker']] + default_linkers
        elif isinstance(compiler, ClangCompiler):
            # Use llvm-ar if available; needed for LTO
            linkers = [defaults['clang_static_linker']] + default_linkers
        elif isinstance(compiler, DCompiler):
            # Prefer static linkers over linkers used by D compilers
            if is_windows():
                linkers = [defaults['vs_static_linker'], defaults['clang_cl_static_linker'], compiler.get_linker_exelist()]
            else:
                linkers = default_linkers
        elif isinstance(compiler, IntelClCCompiler):
            # Intel has it's own linker that acts like microsoft's lib
            linkers = [['xilib']]
        elif isinstance(compiler, (PGICCompiler, PGIFortranCompiler)) and is_windows():
            linkers = [['ar']]  # For PGI on Windows, "ar" is just a wrapper calling link/lib.
        else:
            linkers = default_linkers
    popen_exceptions = {}
    for linker in linkers:
        if not {'lib', 'lib.exe', 'llvm-lib', 'llvm-lib.exe', 'xilib', 'xilib.exe'}.isdisjoint(linker):
            arg = '/?'
        elif not {'ar2000', 'ar2000.exe'}.isdisjoint(linker):
            arg = '?'
        else:
            arg = '--version'
        try:
            p, out, err = Popen_safe(linker + [arg])
        except OSError as e:
            popen_exceptions[' '.join(linker + [arg])] = e
            continue
        if "xilib: executing 'lib'" in err:
            return IntelVisualStudioLinker(linker, getattr(compiler, 'machine', None))
        if '/OUT:' in out.upper() or '/OUT:' in err.upper():
            return VisualStudioLinker(linker, getattr(compiler, 'machine', None))
        if 'ar-Error-Unknown switch: --version' in err:
            return PGIStaticLinker(linker)
        if p.returncode == 0 and ('armar' in linker or 'armar.exe' in linker):
            return ArmarLinker(linker)
        if 'DMD32 D Compiler' in out or 'DMD64 D Compiler' in out:
            assert isinstance(compiler, DCompiler)
            return DLinker(linker, compiler.arch)
        if 'LDC - the LLVM D compiler' in out:
            assert isinstance(compiler, DCompiler)
            return DLinker(linker, compiler.arch, rsp_syntax=compiler.rsp_file_syntax())
        if 'GDC' in out and ' based on D ' in out:
            assert isinstance(compiler, DCompiler)
            return DLinker(linker, compiler.arch)
        if err.startswith('Renesas') and ('rlink' in linker or 'rlink.exe' in linker):
            return CcrxLinker(linker)
        if out.startswith('GNU ar') and ('xc16-ar' in linker or 'xc16-ar.exe' in linker):
            return Xc16Linker(linker)
        if out.startswith('TMS320C2000') and ('ar2000' in linker or 'ar2000.exe' in linker):
            return C2000Linker(linker)
        if out.startswith('The CompCert'):
            return CompCertLinker(linker)
        if p.returncode == 0:
            return ArLinker(linker)
        if p.returncode == 1 and err.startswith('usage'): # OSX
            return ArLinker(linker)
        if p.returncode == 1 and err.startswith('Usage'): # AIX
            return AIXArLinker(linker)
        if p.returncode == 1 and err.startswith('ar: bad option: --'): # Solaris
            return ArLinker(linker)
    _handle_exceptions(popen_exceptions, linkers, 'linker')


# 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.
    """
    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]]

    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 'cl2000' in compiler_name:
            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'

        try:
            p, out, err = Popen_safe(compiler + [arg])
        except OSError as e:
            popen_exceptions[' '.join(compiler + [arg])] = 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 'xt-' in out:
            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(compiler)] = 'no pre-processor defines'
                continue

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

            linker = guess_nix_linker(env, compiler, cls, 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 = EmscriptenCCompiler if lang == 'c' else 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. Old emcc versions ignore -Wl,--version completely,
            # however. We'll report "unknown version" in that case.
            with tempfile.NamedTemporaryFile(suffix='.c') as f:
                cmd = compiler + [cls.LINKER_PREFIX + "--version", f.name]
                _, o, _ = Popen_safe(cmd)

            linker = 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 '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(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 = ArmclangCCompiler if lang == 'c' else ArmclangCPPCompiler
            linker = 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(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 = ClangClCCompiler if lang == 'c' else ClangClCPPCompiler
            linker = guess_win_linker(env, ['lld-link'], cls, for_machine)
            return cls(
                compiler, version, for_machine, is_cross, info, target,
                exe_wrap, 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 = AppleClangCCompiler if lang == 'c' else AppleClangCPPCompiler
            else:
                cls = ClangCCompiler if lang == 'c' else 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, for_machine, invoked_directly=False)
                except MesonException:
                    pass
            if linker is None:
                linker = guess_nix_linker(env, compiler, cls, 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 = IntelClCCompiler if lang == 'c' else IntelClCPPCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = 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')[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 = VisualStudioCCompiler if lang == 'c' else VisualStudioCPPCompiler
            linker = guess_win_linker(env, ['link'], cls, for_machine)
            # As of this writing, CCache does not support MSVC but sccache does.
            if 'sccache' in ccache:
                final_compiler = ccache + compiler
            else:
                final_compiler = compiler
            return cls(
                final_compiler, version, for_machine, is_cross, info, target,
                exe_wrap, full_version=cl_signature, linker=linker)
        if 'PGI Compilers' in out:
            cls = PGICCompiler if lang == 'c' else PGICPPCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = 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 = NvidiaHPC_CCompiler if lang == 'c' else NvidiaHPC_CPPCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = 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 = IntelCCompiler if lang == 'c' else IntelCPPCompiler
            l = guess_nix_linker(env, compiler, cls, for_machine)
            return cls(
                ccache + compiler, version, for_machine, is_cross, info,
                exe_wrap, full_version=full_version, linker=l)
        if 'ARM' in out:
            cls = ArmCCompiler if lang == 'c' else ArmCPPCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = 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 = CcrxCCompiler if lang == 'c' else CcrxCPPCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = 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 = Xc16CCompiler if lang == 'c' else Xc16CCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = 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 = CompCertCCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = CompCertDynamicLinker(for_machine, version=version)
            return cls(
                ccache + compiler, version, for_machine, is_cross, info,
                exe_wrap, full_version=full_version, linker=linker)

        if 'TMS320C2000 C/C++' in out:
            cls = C2000CCompiler if lang == 'c' else C2000CPPCompiler
            env.coredata.add_lang_args(cls.language, cls, for_machine, env)
            linker = C2000DynamicLinker(compiler, for_machine, version=version)
            return cls(
                ccache + 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:
    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(compiler + [arg])
        except OSError as e:
            popen_exceptions[' '.join(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().split('V')[-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:
    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(compiler + [arg])
            except OSError as e:
                popen_exceptions[' '.join(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(compiler)] = 'no pre-processor defines'
                    continue
                if guess_gcc_or_lcc == 'lcc':
                    version = _get_lcc_version_from_defines(defines)
                    cls = ElbrusFortranCompiler
                    linker = guess_nix_linker(env, compiler, cls, 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 = GnuFortranCompiler
                    linker = guess_nix_linker(env, compiler, cls, for_machine)
                    return cls(
                        compiler, version, for_machine, is_cross, info,
                        exe_wrap, defines, full_version=full_version, linker=linker)

            if 'G95' in out:
                cls = G95FortranCompiler
                linker = guess_nix_linker(env, compiler, cls, for_machine)
                return G95FortranCompiler(
                    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 = SunFortranCompiler
                linker = guess_nix_linker(env, compiler, cls, for_machine)
                return SunFortranCompiler(
                    compiler, version, for_machine, is_cross, info,
                    exe_wrap, full_version=full_version, 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 = IntelClFortranCompiler
                env.coredata.add_lang_args(cls.language, cls, for_machine, env)
                linker = XilinkDynamicLinker(for_machine, [], version=version)
                return cls(
                    compiler, version, for_machine, is_cross, info,
                    target, exe_wrap, linker=linker)

            if 'ifort (IFORT)' in out:
                linker = guess_nix_linker(env, compiler, IntelFortranCompiler, for_machine)
                return IntelFortranCompiler(
                    compiler, version, for_machine, is_cross, info,
                    exe_wrap, full_version=full_version, linker=linker)

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

            if 'PGI Compilers' in out:
                cls = PGIFortranCompiler
                env.coredata.add_lang_args(cls.language, cls, for_machine, env)
                linker = 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 = NvidiaHPC_FortranCompiler
                env.coredata.add_lang_args(cls.language, cls, for_machine, env)
                linker = 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:
                linker = guess_nix_linker(env,
                    compiler, FlangFortranCompiler, for_machine)
                return FlangFortranCompiler(
                    compiler, version, for_machine, is_cross, info,
                    exe_wrap, full_version=full_version, linker=linker)

            if 'Open64 Compiler Suite' in err:
                linker = guess_nix_linker(env,
                    compiler, Open64FortranCompiler, for_machine)
                return Open64FortranCompiler(
                    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 = NAGFortranCompiler
                env.coredata.add_lang_args(cls.language, cls, for_machine, env)
                linker = 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, for_machine, True)

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

def _detect_objc_or_objcpp_compiler(env: 'Environment', for_machine: MachineChoice, objc: bool) -> 'Compiler':
    popen_exceptions: T.Dict[str, T.Union[Exception, str]] = {}
    compilers, ccache, exe_wrap = _get_compilers(env, 'objc' if objc else 'objcpp', for_machine)
    is_cross = env.is_cross_build(for_machine)
    info = env.machines[for_machine]
    comp: T.Union[T.Type[ObjCCompiler], T.Type[ObjCPPCompiler]]

    for compiler in compilers:
        arg = ['--version']
        try:
            p, out, err = Popen_safe(compiler + arg)
        except OSError as e:
            popen_exceptions[' '.join(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(compiler)] = 'no pre-processor defines'
                continue
            version = _get_gnu_version_from_defines(defines)
            comp = GnuObjCCompiler if objc else GnuObjCPPCompiler
            linker = guess_nix_linker(env, compiler, comp, 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(compiler)] = 'no pre-processor defines'
                continue
            if 'Apple' in out:
                comp = AppleClangObjCCompiler if objc else AppleClangObjCPPCompiler
            else:
                comp = ClangObjCCompiler if objc else 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, for_machine)
                except MesonException:
                    pass

            if not linker:
                linker = guess_nix_linker(env, compiler, comp, 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:
    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(exelist + ['-version'])
    except OSError:
        raise EnvironmentException('Could not execute Java compiler "{}"'.format(' '.join(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(exelist) + '"')

def detect_cs_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
    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(comp + ['--version'])
        except OSError as e:
            popen_exceptions[' '.join(comp + ['--version'])] = e
            continue

        version = search_version(out)
        cls: T.Union[T.Type[MonoCompiler], T.Type[VisualStudioCsCompiler]]
        if 'Mono' in out:
            cls = MonoCompiler
        elif "Visual C#" in out:
            cls = 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."""
    compilers, _, _ = _get_compilers(env, 'cython', for_machine)
    is_cross = env.is_cross_build(for_machine)
    info = env.machines[for_machine]

    popen_exceptions: T.Dict[str, Exception] = {}
    for comp in compilers:
        try:
            err = Popen_safe(comp + ['-V'])[2]
        except OSError as e:
            popen_exceptions[' '.join(comp + ['-V'])] = e
            continue

        version = search_version(err)
        if 'Cython' in err:
            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:
    exelist = env.lookup_binary_entry(for_machine, '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(exelist + ['--version'])[0:2]
    except OSError:
        raise EnvironmentException('Could not execute Vala compiler "{}"'.format(' '.join(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(exelist) + '"')

def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> RustCompiler:
    popen_exceptions = {}  # type: 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, VisualStudioLikeLinkerMixin)
    override = env.lookup_binary_entry(for_machine, 'rust_ld')

    for compiler in compilers:
        arg = ['--version']
        try:
            out = Popen_safe(compiler + arg)[1]
        except OSError as e:
            popen_exceptions[' '.join(compiler + arg)] = e
            continue

        version = search_version(out)
        cls: T.Type[RustCompiler] = 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:
            out = 'rustc'
            cls = 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 RUST_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 'ccache' in exelist[0]:
                        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
                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) # type: ignore
            elif 'link' in override[0]:
                linker = guess_win_linker(env,
                    override, cls, for_machine, use_linker_prefix=False)
                # rustc takes linker arguments without a prefix, and
                # inserts the correct prefix itself.
                assert isinstance(linker, 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:
    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'], 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)
    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(exelist + ['--version'])] = e
            continue
        version = search_version(out)
        full_version = out.split('\n', 1)[0]

        if 'LLVM D compiler' in out:
            # LDC seems to require a file
            # We cannot use NamedTemproraryFile 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,
                        LLVMDCompiler, 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, LLVMDCompiler, for_machine,
                        extra_args=[f])
            finally:
                windows_proof_rm(f)
                windows_proof_rm(objfile)

            return LLVMDCompiler(
                exelist, version, for_machine, info, arch,
                full_version=full_version, linker=linker, version_output=out)
        elif 'gdc' in out:
            linker = guess_nix_linker(env, exelist, GnuDCompiler, for_machine)
            return GnuDCompiler(
                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:
            # DMD seems to require a file
            # We cannot use NamedTemproraryFile 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, DmdDCompiler, for_machine,
                        invoked_directly=False, extra_args=[f, arch_arg])
                else:
                    objfile = os.path.basename(f)[:-1] + 'o'
                    linker = guess_nix_linker(env,
                        exelist, DmdDCompiler, for_machine,
                        extra_args=[f, arch_arg])
            finally:
                windows_proof_rm(f)
                windows_proof_rm(objfile)

            return DmdDCompiler(
                exelist, version, for_machine, info, arch,
                full_version=full_version, linker=linker)
        raise EnvironmentException('Unknown compiler "' + ' '.join(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:
    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(exelist + ['-v'])
    except OSError:
        raise EnvironmentException('Could not execute Swift compiler "{}"'.format(' '.join(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:
            linker = guess_nix_linker(env,
                exelist, SwiftCompiler, for_machine,
                extra_args=[f.name])
        return SwiftCompiler(
            exelist, version, for_machine, is_cross, info, linker=linker)

    raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')


# 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', '-']
    p, output, error = Popen_safe(args, write='', stdin=subprocess.PIPE)
    if p.returncode != 0:
        raise EnvironmentException('Unable to detect GNU compiler type:\n' + output + error)
    # 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', '-']
    p, output, error = Popen_safe(args, write='', stdin=subprocess.PIPE)
    if p.returncode != 0:
        raise EnvironmentException('Unable to get clang pre-processor defines:\n' + output + error)
    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))
