# 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_ccache()

    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 not {'cl', 'cl.exe', 'clang-cl', 'clang-cl.exe'}.isdisjoint(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'))]
                found_cl = sanitize(shutil.which('cl'))
                if found_cl in watcom_cls:
                    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)
            return cls(
                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))
