From cc5ef6478ffe871eda6ad90f21d8e9d05613101d Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Sun, 11 Sep 2022 23:03:43 -0400 Subject: [PATCH] compilers: perform targeted imports for detect Only import the ones we need for the language we are detecting, once we actually detect that language. This will allow finally dropping the main imports of these files in a followup commit. --- mesonbuild/backend/ninjabackend.py | 2 +- mesonbuild/compilers/detect.py | 189 ++++++++++++++++------------- mesonbuild/dependencies/dev.py | 4 +- mesonbuild/dependencies/dub.py | 2 +- 4 files changed, 107 insertions(+), 90 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 89f3763d4..33f49707f 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -37,7 +37,6 @@ from .. import mlog from .. import compilers from ..arglist import CompilerArgs from ..compilers import Compiler -from ..compilers.c import CCompiler from ..linkers import ArLinker, AppleArLinker, RSPFileSyntax from ..mesonlib import ( File, LibType, MachineChoice, MesonException, OrderedSet, PerMachine, @@ -3042,6 +3041,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) @lru_cache(maxsize=None) def guess_library_absolute_path(self, linker, libname, search_dirs, patterns) -> Path: + from ..compilers.c import CCompiler for d in search_dirs: for p in patterns: trial = CCompiler._get_trials_from_pattern(p, d, libname) diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py index c128a9b35..021ae8e79 100644 --- a/mesonbuild/compilers/detect.py +++ b/mesonbuild/compilers/detect.py @@ -270,6 +270,8 @@ def _handle_exceptions( # =============== def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker: + from . import d + from ..linkers import linkers linker = env.lookup_binary_entry(compiler.for_machine, 'ar') if linker is not None: trials = [linker] @@ -314,41 +316,41 @@ def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker popen_exceptions[join_args(linker + [arg])] = e continue if "xilib: executing 'lib'" in err: - return IntelVisualStudioLinker(linker, getattr(compiler, 'machine', None)) + return linkers.IntelVisualStudioLinker(linker, getattr(compiler, 'machine', None)) if '/OUT:' in out.upper() or '/OUT:' in err.upper(): - return VisualStudioLinker(linker, getattr(compiler, 'machine', None)) + return linkers.VisualStudioLinker(linker, getattr(compiler, 'machine', None)) if 'ar-Error-Unknown switch: --version' in err: - return PGIStaticLinker(linker) + return linkers.PGIStaticLinker(linker) if p.returncode == 0 and 'armar' in linker_name: - return ArmarLinker(linker) + return linkers.ArmarLinker(linker) if 'DMD32 D Compiler' in out or 'DMD64 D Compiler' in out: - assert isinstance(compiler, DCompiler) - return DLinker(linker, compiler.arch) + assert isinstance(compiler, d.DCompiler) + return linkers.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()) + assert isinstance(compiler, d.DCompiler) + return linkers.DLinker(linker, compiler.arch, rsp_syntax=compiler.rsp_file_syntax()) if 'GDC' in out and ' based on D ' in out: - assert isinstance(compiler, DCompiler) - return DLinker(linker, compiler.arch) + assert isinstance(compiler, d.DCompiler) + return linkers.DLinker(linker, compiler.arch) if err.startswith('Renesas') and 'rlink' in linker_name: - return CcrxLinker(linker) + return linkers.CcrxLinker(linker) if out.startswith('GNU ar') and 'xc16-ar' in linker_name: - return Xc16Linker(linker) + return linkers.Xc16Linker(linker) if 'Texas Instruments Incorporated' in out: if 'ar2000' in linker_name: - return C2000Linker(linker) + return linkers.C2000Linker(linker) else: - return TILinker(linker) + return linkers.TILinker(linker) if out.startswith('The CompCert'): - return CompCertLinker(linker) + return linkers.CompCertLinker(linker) if p.returncode == 0: - return ArLinker(compiler.for_machine, linker) + return linkers.ArLinker(compiler.for_machine, linker) if p.returncode == 1 and err.startswith('usage'): # OSX - return AppleArLinker(compiler.for_machine, linker) + return linkers.AppleArLinker(compiler.for_machine, linker) if p.returncode == 1 and err.startswith('Usage'): # AIX - return AIXArLinker(linker) + return linkers.AIXArLinker(linker) if p.returncode == 1 and err.startswith('ar: bad option: --'): # Solaris - return ArLinker(compiler.for_machine, linker) + return linkers.ArLinker(compiler.for_machine, linker) _handle_exceptions(popen_exceptions, trials, 'linker') @@ -363,6 +365,8 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin the compiler (GCC or Clang usually) as their shared linker, to find the linker they need. """ + from . import c, cpp + from ..linkers import linkers popen_exceptions: T.Dict[str, T.Union[Exception, str]] = {} compilers, ccache, exe_wrap = _get_compilers(env, lang, for_machine) if override_compiler is not None: @@ -451,10 +455,10 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin if guess_gcc_or_lcc == 'lcc': version = _get_lcc_version_from_defines(defines) - cls = ElbrusCCompiler if lang == 'c' else ElbrusCPPCompiler + cls = c.ElbrusCCompiler if lang == 'c' else cpp.ElbrusCPPCompiler else: version = _get_gnu_version_from_defines(defines) - cls = GnuCCompiler if lang == 'c' else GnuCPPCompiler + cls = c.GnuCCompiler if lang == 'c' else cpp.GnuCPPCompiler linker = guess_nix_linker(env, compiler, cls, version, for_machine) @@ -464,7 +468,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin linker=linker) if 'Emscripten' in out: - cls = EmscriptenCCompiler if lang == 'c' else EmscriptenCPPCompiler + cls = c.EmscriptenCCompiler if lang == 'c' else cpp.EmscriptenCPPCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) # emcc requires a file input in order to pass arguments to the @@ -475,7 +479,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin cmd = compiler + [cls.LINKER_PREFIX + "--version", f.name] _, o, _ = Popen_safe(cmd) - linker = WASMDynamicLinker( + linker = linkers.WASMDynamicLinker( compiler, for_machine, cls.LINKER_PREFIX, [], version=search_version(o)) return cls( @@ -487,9 +491,9 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin assert arm_ver_match is not None, 'for mypy' # because mypy *should* be complaning that this could be None version = '.'.join([x for x in arm_ver_match.groups() if x is not None]) if lang == 'c': - cls = ArmLtdClangCCompiler + cls = c.ArmLtdClangCCompiler elif lang == 'cpp': - cls = ArmLtdClangCPPCompiler + cls = cpp.ArmLtdClangCPPCompiler linker = guess_nix_linker(env, compiler, cls, version, for_machine) return cls( ccache + compiler, version, for_machine, is_cross, info, @@ -508,8 +512,8 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin # 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) + cls = c.ArmclangCCompiler if lang == 'c' else cpp.ArmclangCPPCompiler + linker = linkers.ArmClangDynamicLinker(for_machine, version=version) env.coredata.add_lang_args(cls.language, cls, for_machine, env) return cls( ccache + compiler, version, for_machine, is_cross, info, @@ -528,7 +532,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin target = match.group(1) else: target = 'unknown target' - cls = ClangClCCompiler if lang == 'c' else ClangClCPPCompiler + cls = c.ClangClCCompiler if lang == 'c' else cpp.ClangClCPPCompiler linker = guess_win_linker(env, ['lld-link'], cls, version, for_machine) return cls( compiler, version, for_machine, is_cross, info, target, @@ -541,9 +545,9 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin # Even if the for_machine is darwin, we could be using vanilla # clang. if 'Apple' in out: - cls = AppleClangCCompiler if lang == 'c' else AppleClangCPPCompiler + cls = c.AppleClangCCompiler if lang == 'c' else cpp.AppleClangCPPCompiler else: - cls = ClangCCompiler if lang == 'c' else ClangCPPCompiler + cls = c.ClangCCompiler if lang == 'c' else cpp.ClangCPPCompiler if 'windows' in out or env.machines[for_machine].is_windows(): # If we're in a MINGW context this actually will use a gnu @@ -563,9 +567,9 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin 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 + cls = c.IntelClCCompiler if lang == 'c' else cpp.IntelClCPPCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) - linker = XilinkDynamicLinker(for_machine, [], version=version) + linker = linkers.XilinkDynamicLinker(for_machine, [], version=version) return cls( compiler, version, for_machine, is_cross, info, target, exe_wrap, linker=linker) @@ -587,7 +591,7 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin 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 + cls = c.VisualStudioCCompiler if lang == 'c' else cpp.VisualStudioCPPCompiler linker = guess_win_linker(env, ['link'], cls, version, for_machine) # As of this writing, CCache does not support MSVC but sccache does. if 'sccache' in ccache: @@ -598,33 +602,33 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin 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 + cls = c.PGICCompiler if lang == 'c' else cpp.PGICPPCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) - linker = PGIDynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version) + linker = linkers.PGIDynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version) return cls( ccache + compiler, version, for_machine, is_cross, info, exe_wrap, linker=linker) if 'NVIDIA Compilers and Tools' in out: - cls = NvidiaHPC_CCompiler if lang == 'c' else NvidiaHPC_CPPCompiler + cls = c.NvidiaHPC_CCompiler if lang == 'c' else cpp.NvidiaHPC_CPPCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) - linker = NvidiaHPC_DynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version) + linker = linkers.NvidiaHPC_DynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version) return cls( ccache + compiler, version, for_machine, is_cross, info, exe_wrap, linker=linker) if '(ICC)' in out: - cls = IntelCCompiler if lang == 'c' else IntelCPPCompiler + cls = c.IntelCCompiler if lang == 'c' else cpp.IntelCPPCompiler l = guess_nix_linker(env, compiler, cls, version, for_machine) return cls( ccache + compiler, version, for_machine, is_cross, info, exe_wrap, full_version=full_version, linker=l) if 'TMS320C2000 C/C++' in out or 'MSP430 C/C++' in out or 'TI ARM C/C++ Compiler' in out: - lnk: T.Union[T.Type[C2000DynamicLinker], T.Type[TIDynamicLinker]] + lnk: T.Union[T.Type[linkers.C2000DynamicLinker], T.Type[linkers.TIDynamicLinker]] if 'TMS320C2000 C/C++' in out: - cls = C2000CCompiler if lang == 'c' else C2000CPPCompiler - lnk = C2000DynamicLinker + cls = c.C2000CCompiler if lang == 'c' else cpp.C2000CPPCompiler + lnk = linkers.C2000DynamicLinker else: - cls = TICCompiler if lang == 'c' else TICPPCompiler - lnk = TIDynamicLinker + cls = c.TICCompiler if lang == 'c' else cpp.TICPPCompiler + lnk = linkers.TIDynamicLinker env.coredata.add_lang_args(cls.language, cls, for_machine, env) linker = lnk(compiler, for_machine, version=version) @@ -632,32 +636,32 @@ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: Machin ccache + compiler, version, for_machine, is_cross, info, exe_wrap, full_version=full_version, linker=linker) if 'ARM' in out: - cls = ArmCCompiler if lang == 'c' else ArmCPPCompiler + cls = c.ArmCCompiler if lang == 'c' else cpp.ArmCPPCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) - linker = ArmDynamicLinker(for_machine, version=version) + linker = linkers.ArmDynamicLinker(for_machine, version=version) return cls( ccache + compiler, version, for_machine, is_cross, info, exe_wrap, full_version=full_version, linker=linker) if 'RX Family' in out: - cls = CcrxCCompiler if lang == 'c' else CcrxCPPCompiler + cls = c.CcrxCCompiler if lang == 'c' else cpp.CcrxCPPCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) - linker = CcrxDynamicLinker(for_machine, version=version) + linker = linkers.CcrxDynamicLinker(for_machine, version=version) return cls( ccache + compiler, version, for_machine, is_cross, info, exe_wrap, full_version=full_version, linker=linker) if 'Microchip Technology' in out: - cls = Xc16CCompiler + cls = c.Xc16CCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) - linker = Xc16DynamicLinker(for_machine, version=version) + linker = linkers.Xc16DynamicLinker(for_machine, version=version) return cls( ccache + compiler, version, for_machine, is_cross, info, exe_wrap, full_version=full_version, linker=linker) if 'CompCert' in out: - cls = CompCertCCompiler + cls = c.CompCertCCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) - linker = CompCertDynamicLinker(for_machine, version=version) + linker = linkers.CompCertDynamicLinker(for_machine, version=version) return cls( ccache + compiler, version, for_machine, is_cross, info, exe_wrap, full_version=full_version, linker=linker) @@ -672,6 +676,8 @@ def detect_cpp_compiler(env: 'Environment', for_machine: MachineChoice) -> Compi return _detect_c_or_cpp_compiler(env, 'cpp', for_machine) def detect_cuda_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler: + from .cuda import CudaCompiler + from ..linkers.linkers import CudaLinker popen_exceptions = {} is_cross = env.is_cross_build(for_machine) compilers, ccache, exe_wrap = _get_compilers(env, 'cuda', for_machine) @@ -707,6 +713,8 @@ def detect_cuda_compiler(env: 'Environment', for_machine: MachineChoice) -> Comp raise EnvironmentException(f'Could not find suitable CUDA compiler: "{"; ".join([" ".join(c) for c in compilers])}"') def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler: + from . import fortran + from ..linkers import linkers popen_exceptions: T.Dict[str, T.Union[Exception, str]] = {} compilers, ccache, exe_wrap = _get_compilers(env, 'fortran', for_machine) is_cross = env.is_cross_build(for_machine) @@ -736,21 +744,21 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C continue if guess_gcc_or_lcc == 'lcc': version = _get_lcc_version_from_defines(defines) - cls = ElbrusFortranCompiler + cls = fortran.ElbrusFortranCompiler linker = guess_nix_linker(env, compiler, cls, version, for_machine) return cls( compiler, version, for_machine, is_cross, info, exe_wrap, defines, full_version=full_version, linker=linker) else: version = _get_gnu_version_from_defines(defines) - cls = GnuFortranCompiler + cls = fortran.GnuFortranCompiler linker = guess_nix_linker(env, compiler, cls, version, for_machine) return cls( compiler, version, for_machine, is_cross, info, exe_wrap, defines, full_version=full_version, linker=linker) if 'Arm C/C++/Fortran Compiler' in out: - cls = ArmLtdFlangFortranCompiler + cls = fortran.ArmLtdFlangFortranCompiler arm_ver_match = re.search(r'version (\d+)\.(\d+)\.?(\d+)? \(build number (\d+)\)', out) assert arm_ver_match is not None, 'for mypy' # because mypy *should* be complaning that this could be None version = '.'.join([x for x in arm_ver_match.groups() if x is not None]) @@ -759,7 +767,7 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C ccache + compiler, version, for_machine, is_cross, info, exe_wrap, linker=linker) if 'G95' in out: - cls = G95FortranCompiler + cls = fortran.G95FortranCompiler linker = guess_nix_linker(env, compiler, cls, version, for_machine) return cls( compiler, version, for_machine, is_cross, info, @@ -767,7 +775,7 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C if 'Sun Fortran' in err: version = search_version(err) - cls = SunFortranCompiler + cls = fortran.SunFortranCompiler linker = guess_nix_linker(env, compiler, cls, version, for_machine) return cls( compiler, version, for_machine, is_cross, info, @@ -776,45 +784,45 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C 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 + cls = fortran.IntelClFortranCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) - linker = XilinkDynamicLinker(for_machine, [], version=version) + linker = linkers.XilinkDynamicLinker(for_machine, [], version=version) return cls( compiler, version, for_machine, is_cross, info, target, exe_wrap, linker=linker) if 'ifort (IFORT)' in out: - cls = IntelFortranCompiler + cls = fortran.IntelFortranCompiler linker = guess_nix_linker(env, compiler, cls, version, for_machine) return cls( compiler, version, for_machine, is_cross, info, exe_wrap, full_version=full_version, linker=linker) if 'PathScale EKOPath(tm)' in err: - return PathScaleFortranCompiler( + return fortran.PathScaleFortranCompiler( compiler, version, for_machine, is_cross, info, exe_wrap, full_version=full_version) if 'PGI Compilers' in out: - cls = PGIFortranCompiler + cls = fortran.PGIFortranCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) - linker = PGIDynamicLinker(compiler, for_machine, - cls.LINKER_PREFIX, [], version=version) + linker = linkers.PGIDynamicLinker(compiler, for_machine, + cls.LINKER_PREFIX, [], version=version) return cls( compiler, version, for_machine, is_cross, info, exe_wrap, full_version=full_version, linker=linker) if 'NVIDIA Compilers and Tools' in out: - cls = NvidiaHPC_FortranCompiler + cls = fortran.NvidiaHPC_FortranCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) - linker = PGIDynamicLinker(compiler, for_machine, - cls.LINKER_PREFIX, [], version=version) + linker = linkers.PGIDynamicLinker(compiler, for_machine, + cls.LINKER_PREFIX, [], version=version) return cls( compiler, version, for_machine, is_cross, info, exe_wrap, full_version=full_version, linker=linker) if 'flang' in out or 'clang' in out: - cls = FlangFortranCompiler + cls = fortran.FlangFortranCompiler linker = guess_nix_linker(env, compiler, cls, version, for_machine) return cls( @@ -822,7 +830,7 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C exe_wrap, full_version=full_version, linker=linker) if 'Open64 Compiler Suite' in err: - cls = Open64FortranCompiler + cls = fortran.Open64FortranCompiler linker = guess_nix_linker(env, compiler, cls, version, for_machine) return cls( @@ -832,9 +840,9 @@ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> C if 'NAG Fortran' in err: full_version = err.split('\n', 1)[0] version = full_version.split()[-1] - cls = NAGFortranCompiler + cls = fortran.NAGFortranCompiler env.coredata.add_lang_args(cls.language, cls, for_machine, env) - linker = NAGDynamicLinker( + linker = linkers.NAGDynamicLinker( compiler, for_machine, cls.LINKER_PREFIX, [], version=version) return cls( @@ -851,11 +859,12 @@ def detect_objcpp_compiler(env: 'Environment', for_machine: MachineChoice) -> 'C return _detect_objc_or_objcpp_compiler(env, 'objcpp', for_machine) def _detect_objc_or_objcpp_compiler(env: 'Environment', lang: str, for_machine: MachineChoice) -> 'Compiler': + from . import objc, objcpp popen_exceptions: T.Dict[str, T.Union[Exception, str]] = {} compilers, ccache, exe_wrap = _get_compilers(env, lang, for_machine) is_cross = env.is_cross_build(for_machine) info = env.machines[for_machine] - comp: T.Union[T.Type[ObjCCompiler], T.Type[ObjCPPCompiler]] + comp: T.Union[T.Type[objc.ObjCCompiler], T.Type[objcpp.ObjCPPCompiler]] for compiler in compilers: arg = ['--version'] @@ -871,7 +880,7 @@ def _detect_objc_or_objcpp_compiler(env: 'Environment', lang: str, for_machine: popen_exceptions[join_args(compiler)] = 'no pre-processor defines' continue version = _get_gnu_version_from_defines(defines) - comp = GnuObjCCompiler if lang == 'objc' else GnuObjCPPCompiler + comp = objc.GnuObjCCompiler if lang == 'objc' else objcpp.GnuObjCPPCompiler linker = guess_nix_linker(env, compiler, comp, version, for_machine) return comp( ccache + compiler, version, for_machine, is_cross, info, @@ -883,9 +892,9 @@ def _detect_objc_or_objcpp_compiler(env: 'Environment', lang: str, for_machine: popen_exceptions[join_args(compiler)] = 'no pre-processor defines' continue if 'Apple' in out: - comp = AppleClangObjCCompiler if lang == 'objc' else AppleClangObjCPPCompiler + comp = objc.AppleClangObjCCompiler if lang == 'objc' else objcpp.AppleClangObjCPPCompiler else: - comp = ClangObjCCompiler if lang == 'objc' else ClangObjCPPCompiler + comp = objc.ClangObjCCompiler if lang == 'objc' else objcpp.ClangObjCPPCompiler if 'windows' in out or env.machines[for_machine].is_windows(): # If we're in a MINGW context this actually will use a gnu style ld try: @@ -902,6 +911,7 @@ def _detect_objc_or_objcpp_compiler(env: 'Environment', lang: str, for_machine: raise EnvironmentException('Unreachable code (exception to make mypy happy)') def detect_java_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler: + from .java import JavaCompiler exelist = env.lookup_binary_entry(for_machine, 'java') info = env.machines[for_machine] if exelist is None: @@ -924,6 +934,7 @@ def detect_java_compiler(env: 'Environment', for_machine: MachineChoice) -> Comp raise EnvironmentException('Unknown compiler: ' + join_args(exelist)) def detect_cs_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler: + from . import cs compilers, ccache, exe_wrap = _get_compilers(env, 'cs', for_machine) popen_exceptions = {} info = env.machines[for_machine] @@ -935,11 +946,11 @@ def detect_cs_compiler(env: 'Environment', for_machine: MachineChoice) -> Compil continue version = search_version(out) - cls: T.Union[T.Type[MonoCompiler], T.Type[VisualStudioCsCompiler]] + cls: T.Union[T.Type[cs.MonoCompiler], T.Type[cs.VisualStudioCsCompiler]] if 'Mono' in out: - cls = MonoCompiler + cls = cs.MonoCompiler elif "Visual C#" in out: - cls = VisualStudioCsCompiler + cls = cs.VisualStudioCsCompiler else: continue env.coredata.add_lang_args(cls.language, cls, for_machine, env) @@ -950,6 +961,7 @@ def detect_cs_compiler(env: 'Environment', for_machine: MachineChoice) -> Compil def detect_cython_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler: """Search for a cython compiler.""" + from .cython import CythonCompiler compilers, _, _ = _get_compilers(env, 'cython', MachineChoice.BUILD) is_cross = env.is_cross_build(for_machine) info = env.machines[for_machine] @@ -971,6 +983,7 @@ def detect_cython_compiler(env: 'Environment', for_machine: MachineChoice) -> Co raise EnvironmentException('Unreachable code (exception to make mypy happy)') def detect_vala_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler: + from .vala import ValaCompiler exelist = env.lookup_binary_entry(MachineChoice.BUILD, 'vala') is_cross = env.is_cross_build(for_machine) info = env.machines[for_machine] @@ -990,13 +1003,15 @@ def detect_vala_compiler(env: 'Environment', for_machine: MachineChoice) -> Comp raise EnvironmentException('Unknown compiler: ' + join_args(exelist)) def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> RustCompiler: + from . import rust + from ..linkers import linkers popen_exceptions = {} # 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) + is_link_exe = isinstance(cc.linker, linkers.VisualStudioLikeLinkerMixin) override = env.lookup_binary_entry(for_machine, 'rust_ld') for compiler in compilers: @@ -1008,13 +1023,13 @@ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> Rust continue version = search_version(out) - cls: T.Type[RustCompiler] = RustCompiler + cls: T.Type[RustCompiler] = rust.RustCompiler # Clippy is a wrapper around rustc, but it doesn't have rustc in it's # output. We can otherwise treat it as rustc. if 'clippy' in out: out = 'rustc' - cls = ClippyRustCompiler + cls = rust.ClippyRustCompiler if 'rustc' in out: # On Linux and mac rustc will invoke gcc (clang for mac @@ -1069,7 +1084,7 @@ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> Rust override, cls, version, for_machine, use_linker_prefix=False) # rustc takes linker arguments without a prefix, and # inserts the correct prefix itself. - assert isinstance(linker, VisualStudioLikeLinkerMixin) + assert isinstance(linker, linkers.VisualStudioLikeLinkerMixin) linker.direct = True compiler.extend(cls.use_linker_args(linker.exelist[0], '')) else: @@ -1094,12 +1109,13 @@ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> Rust raise EnvironmentException('Unreachable code (exception to make mypy happy)') def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler: + from . import c, d info = env.machines[for_machine] # Detect the target architecture, required for proper architecture handling on Windows. # MSVC compiler is required for correct platform detection. c_compiler = {'c': detect_c_compiler(env, for_machine)} - is_msvc = isinstance(c_compiler['c'], VisualStudioCCompiler) + is_msvc = isinstance(c_compiler['c'], c.VisualStudioCCompiler) if not is_msvc: c_compiler = {} @@ -1112,7 +1128,7 @@ def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compile popen_exceptions = {} is_cross = env.is_cross_build(for_machine) compilers, ccache, exe_wrap = _get_compilers(env, 'd', for_machine) - cls: T.Type[DCompiler] + cls: T.Type[d.DCompiler] for exelist in compilers: # Search for a D compiler. # We prefer LDC over GDC unless overridden with the DC @@ -1131,7 +1147,7 @@ def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compile full_version = out.split('\n', 1)[0] if 'LLVM D compiler' in out: - cls = LLVMDCompiler + cls = d.LLVMDCompiler # 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 @@ -1162,14 +1178,14 @@ def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compile exelist, version, for_machine, info, arch, full_version=full_version, linker=linker, version_output=out) elif 'gdc' in out: - cls = GnuDCompiler + cls = d.GnuDCompiler linker = guess_nix_linker(env, exelist, cls, version, for_machine) return cls( exelist, version, for_machine, info, arch, exe_wrapper=exe_wrap, is_cross=is_cross, full_version=full_version, linker=linker) elif 'The D Language Foundation' in out or 'Digital Mars' in out: - cls = DmdDCompiler + cls = d.DmdDCompiler # 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 @@ -1204,6 +1220,7 @@ def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compile raise EnvironmentException('Unreachable code (exception to make mypy happy)') def detect_swift_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler: + from .swift import SwiftCompiler exelist = env.lookup_binary_entry(for_machine, 'swift') is_cross = env.is_cross_build(for_machine) info = env.machines[for_machine] diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py index bf9ba2b9b..e3774c1eb 100644 --- a/mesonbuild/dependencies/dev.py +++ b/mesonbuild/dependencies/dev.py @@ -27,8 +27,6 @@ import typing as T from mesonbuild.interpreterbase.decorators import FeatureDeprecated from .. import mesonlib, mlog -from ..compilers.c import AppleClangCCompiler -from ..compilers.cpp import AppleClangCPPCompiler from ..compilers.detect import detect_compiler_for from ..environment import get_llvm_tool_names from ..mesonlib import version_compare, stringlistify, extract_as_list @@ -486,6 +484,8 @@ class ZlibSystemDependency(SystemDependency): def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]): super().__init__(name, environment, kwargs) + from ..compilers.c import AppleClangCCompiler + from ..compilers.cpp import AppleClangCPPCompiler m = self.env.machines[self.for_machine] diff --git a/mesonbuild/dependencies/dub.py b/mesonbuild/dependencies/dub.py index cad4aadf8..8821e2cef 100644 --- a/mesonbuild/dependencies/dub.py +++ b/mesonbuild/dependencies/dub.py @@ -17,7 +17,6 @@ from .pkgconfig import PkgConfigDependency from ..mesonlib import (Popen_safe, OptionKey) from ..mesonlib.universal import join_args from ..programs import ExternalProgram -from ..compilers.d import DCompiler, d_feature_args from .. import mlog import re import os @@ -33,6 +32,7 @@ class DubDependency(ExternalDependency): def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]): super().__init__(DependencyTypeName('dub'), environment, kwargs, language='d') self.name = name + from ..compilers.d import DCompiler, d_feature_args _temp_comp = super().get_compiler() assert isinstance(_temp_comp, DCompiler)