From 96a1ae6dfe9209d907803b9f2ecca29d2047a47f Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 21 Sep 2020 15:35:53 -0700 Subject: compilers: fully type annotate the C compilers --- mesonbuild/compilers/c.py | 316 ++++++++++++++++++++------------ mesonbuild/compilers/compilers.py | 1 + mesonbuild/compilers/mixins/arm.py | 2 +- mesonbuild/compilers/mixins/c2000.py | 2 +- mesonbuild/compilers/mixins/ccrx.py | 2 +- mesonbuild/compilers/mixins/compcert.py | 2 +- mesonbuild/compilers/mixins/pgi.py | 3 +- mesonbuild/compilers/mixins/xc16.py | 2 +- 8 files changed, 204 insertions(+), 126 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 091a000..95c4698 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -39,13 +39,22 @@ from .compilers import ( ) if T.TYPE_CHECKING: + from ..coredata import OptionDictType + from ..dependencies import Dependency, ExternalProgram from ..envconfig import MachineInfo + from ..environment import Environment + from ..linkers import DynamicLinker + + CompilerMixinBase = Compiler +else: + CompilerMixinBase = object + class CCompiler(CLikeCompiler, Compiler): @staticmethod - def attribute_check_func(name): + def attribute_check_func(name: str) -> str: try: return C_FUNC_ATTRIBUTES[name] except KeyError: @@ -53,20 +62,26 @@ class CCompiler(CLikeCompiler, Compiler): language = 'c' - def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', exe_wrapper: T.Optional[str] = None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): # If a child ObjC or CPP class has already set it, don't set it ourselves - Compiler.__init__(self, exelist, version, for_machine, info, is_cross=is_cross, **kwargs) + Compiler.__init__(self, exelist, version, for_machine, info, + is_cross=is_cross, full_version=full_version, linker=linker) CLikeCompiler.__init__(self, exe_wrapper) - def get_no_stdinc_args(self): + def get_no_stdinc_args(self) -> T.List[str]: return ['-nostdinc'] - def sanity_check(self, work_dir, environment): + def sanity_check(self, work_dir: str, environment: 'Environment') -> None: code = 'int main(void) { int class=0; return class; }\n' return self._sanity_check_impl(work_dir, environment, 'sanitycheckc.c', code) - def has_header_symbol(self, hname, symbol, prefix, env, *, extra_args=None, dependencies=None): + def has_header_symbol(self, hname: str, symbol: str, prefix: str, + env: 'Environment', *, + extra_args: T.Optional[T.List[str]] = None, + dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: fargs = {'prefix': prefix, 'header': hname, 'symbol': symbol} t = '''{prefix} #include <{header}> @@ -87,10 +102,12 @@ class ClangCCompiler(ClangCompiler, CCompiler): _C18_VERSION = '>=8.0.0' _C2X_VERSION = '>=9.0.0' - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - defines: T.Optional[T.List[str]] = None, **kwargs): - CCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): + CCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, linker=linker, full_version=full_version) ClangCompiler.__init__(self, defines) default_warn_args = ['-Wall', '-Winvalid-pch'] self.warn_args = {'0': [], @@ -98,7 +115,7 @@ class ClangCCompiler(ClangCompiler, CCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) c_stds = ['c89', 'c99', 'c11'] g_stds = ['gnu89', 'gnu99', 'gnu11'] @@ -129,16 +146,21 @@ class ClangCCompiler(ClangCompiler, CCompiler): }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': args.append('-std=' + std.value) return args - def get_option_link_args(self, options): + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: if self.info.is_windows() or self.info.is_cygwin(): - return options['winlibs'].value[:] + # without a typedict mypy can't understand this. + libs = options['winlibs'].value.copy() + assert isinstance(libs, list) + for l in libs: + assert isinstance(l, str) + return libs return [] @@ -156,21 +178,26 @@ class AppleClangCCompiler(ClangCCompiler): class EmscriptenCCompiler(EmscriptenMixin, LinkerEnvVarsMixin, ClangCCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross: bool, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): if not is_cross: raise MesonException('Emscripten compiler can only be used for cross compilation.') - ClangCCompiler.__init__(self, exelist=exelist, version=version, - for_machine=for_machine, is_cross=is_cross, - info=info, exe_wrapper=exe_wrapper, **kwargs) + ClangCCompiler.__init__(self, exelist, version, for_machine, is_cross, + info, exe_wrapper=exe_wrapper, linker=linker, + defines=defines, full_version=full_version) self.id = 'emscripten' class ArmclangCCompiler(ArmclangCompiler, CCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) ArmclangCompiler.__init__(self) default_warn_args = ['-Wall', '-Winvalid-pch'] self.warn_args = {'0': [], @@ -178,7 +205,7 @@ class ArmclangCCompiler(ArmclangCompiler, CCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) opts.update({ 'std': coredata.UserComboOption( @@ -189,14 +216,14 @@ class ArmclangCCompiler(ArmclangCompiler, CCompiler): }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': args.append('-std=' + std.value) return args - def get_option_link_args(self, options): + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] @@ -205,11 +232,12 @@ class GnuCCompiler(GnuCompiler, CCompiler): _C18_VERSION = '>=8.0.0' _C2X_VERSION = '>=9.0.0' - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - defines=None, **kwargs): - CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): + CCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, linker=linker, full_version=full_version) GnuCompiler.__init__(self, defines) default_warn_args = ['-Wall', '-Winvalid-pch'] self.warn_args = {'0': [], @@ -217,7 +245,7 @@ class GnuCCompiler(GnuCompiler, CCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) c_stds = ['c89', 'c99', 'c11'] g_stds = ['gnu89', 'gnu99', 'gnu11'] @@ -243,49 +271,61 @@ class GnuCCompiler(GnuCompiler, CCompiler): }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': args.append('-std=' + std.value) return args - def get_option_link_args(self, options): + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: if self.info.is_windows() or self.info.is_cygwin(): - return options['winlibs'].value[:] + # without a typeddict mypy can't figure this out + libs = options['winlibs'].value.copy() + assert isinstance(libs, list) + for l in libs: + assert isinstance(l, str) + return libs return [] - def get_pch_use_args(self, pch_dir, header): + def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: return ['-fpch-preprocess', '-include', os.path.basename(header)] class PGICCompiler(PGICompiler, CCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) PGICompiler.__init__(self) class NvidiaHPC_CCompiler(PGICompiler, CCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) PGICompiler.__init__(self) self.id = 'nvidia_hpc' class ElbrusCCompiler(GnuCCompiler, ElbrusCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - defines=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): GnuCCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, defines, **kwargs) + info, exe_wrapper, defines=defines, + linker=linker, full_version=full_version) ElbrusCompiler.__init__(self) # It does support some various ISO standards and c/gnu 90, 9x, 1x in addition to those which GNU CC supports. - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) opts.update({ 'std': coredata.UserComboOption( @@ -302,7 +342,9 @@ class ElbrusCCompiler(GnuCCompiler, ElbrusCompiler): # Elbrus C compiler does not have lchmod, but there is only linker warning, not compiler error. # So we should explicitly fail at this case. - def has_function(self, funcname, prefix, env, *, extra_args=None, dependencies=None): + def has_function(self, funcname: str, prefix: str, env: 'Environment', *, + extra_args: T.Optional[T.List[str]] = None, + dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: if funcname == 'lchmod': return False, False else: @@ -312,10 +354,12 @@ class ElbrusCCompiler(GnuCCompiler, ElbrusCompiler): class IntelCCompiler(IntelGnuLikeCompiler, CCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) IntelGnuLikeCompiler.__init__(self) self.lang_header = 'c-header' default_warn_args = ['-Wall', '-w3', '-diag-disable:remark'] @@ -324,7 +368,7 @@ class IntelCCompiler(IntelGnuLikeCompiler, CCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra']} - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) c_stds = ['c89', 'c99'] g_stds = ['gnu89', 'gnu99'] @@ -339,7 +383,7 @@ class IntelCCompiler(IntelGnuLikeCompiler, CCompiler): }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': @@ -347,11 +391,11 @@ class IntelCCompiler(IntelGnuLikeCompiler, CCompiler): return args -class VisualStudioLikeCCompilerMixin: +class VisualStudioLikeCCompilerMixin(CompilerMixinBase): """Shared methods that apply to MSVC-like C compilers.""" - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = super().get_options() opts.update({ 'winlibs': coredata.UserArrayOption( @@ -361,20 +405,28 @@ class VisualStudioLikeCCompilerMixin: }) return opts - def get_option_link_args(self, options): - return options['winlibs'].value[:] + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + # need a TypeDict to make this work + libs = options['winlibs'].value.copy() + assert isinstance(libs, list) + for l in libs: + assert isinstance(l, str) + return libs class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrap, target: str, - **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', target: str, + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrap, **kwargs) + info, exe_wrapper, linker=linker, + full_version=full_version) MSVCCompiler.__init__(self, target) - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = super().get_options() c_stds = ['none', 'c89', 'c99', 'c11'] opts.update({ @@ -386,7 +438,7 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] # As of MVSC 16.7, /std:c11 is the only valid C standard option. @@ -396,10 +448,14 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi class ClangClCCompiler(ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrap, target, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', target: str, + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrap, **kwargs) + info, exe_wrapper, linker=linker, + full_version=full_version) ClangClCompiler.__init__(self, target) @@ -407,13 +463,17 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM """Intel "ICL" compiler abstraction.""" - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrap, target, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', target: str, + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrap, **kwargs) + info, exe_wrapper, linker=linker, + full_version=full_version) IntelVisualStudioLikeCompiler.__init__(self, target) - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = super().get_options() c_stds = ['none', 'c89', 'c99', 'c11'] opts.update({ @@ -425,7 +485,7 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value == 'c89': @@ -436,13 +496,17 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM class ArmCCompiler(ArmCompiler, CCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, **kwargs) + info, exe_wrapper, linker=linker, + full_version=full_version) ArmCompiler.__init__(self) - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) opts.update({ 'std': coredata.UserComboOption( @@ -453,7 +517,7 @@ class ArmCCompiler(ArmCompiler, CCompiler): }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': @@ -462,17 +526,20 @@ class ArmCCompiler(ArmCompiler, CCompiler): class CcrxCCompiler(CcrxCompiler, CCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) CcrxCompiler.__init__(self) # Override CCompiler.get_always_args - def get_always_args(self): + def get_always_args(self) -> T.List[str]: return ['-nologo'] - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) opts.update({ 'std': coredata.UserComboOption( @@ -483,10 +550,10 @@ class CcrxCCompiler(CcrxCompiler, CCompiler): }) return opts - def get_no_stdinc_args(self): + def get_no_stdinc_args(self) -> T.List[str]: return [] - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value == 'c89': @@ -495,42 +562,45 @@ class CcrxCCompiler(CcrxCompiler, CCompiler): args.append('-lang=c99') return args - def get_compile_only_args(self): + def get_compile_only_args(self) -> T.List[str]: return [] - def get_no_optimization_args(self): + def get_no_optimization_args(self) -> T.List[str]: return ['-optimize=0'] - def get_output_args(self, target): + def get_output_args(self, target: str) -> T.List[str]: return ['-output=obj=%s' % target] - def get_werror_args(self): + def get_werror_args(self) -> T.List[str]: return ['-change_message=error'] - def get_include_args(self, path, is_system): + def get_include_args(self, path: str, is_system: bool) -> T.List[str]: if path == '': path = '.' return ['-include=' + path] class Xc16CCompiler(Xc16Compiler, CCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) Xc16Compiler.__init__(self) - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) opts.update({'c_std': coredata.UserComboOption('C language standard to use', ['none', 'c89', 'c99', 'gnu89', 'gnu99'], 'none')}) return opts - def get_no_stdinc_args(self): + def get_no_stdinc_args(self) -> T.List[str]: return [] - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['c_std'] if std.value != 'none': @@ -538,95 +608,101 @@ class Xc16CCompiler(Xc16Compiler, CCompiler): args.append('-std=' + std.value) return args - def get_compile_only_args(self): + def get_compile_only_args(self) -> T.List[str]: return [] - def get_no_optimization_args(self): + def get_no_optimization_args(self) -> T.List[str]: return ['-O0'] - def get_output_args(self, target): + def get_output_args(self, target: str) -> T.List[str]: return ['-o%s' % target] - def get_werror_args(self): + def get_werror_args(self) -> T.List[str]: return ['-change_message=error'] - def get_include_args(self, path, is_system): + def get_include_args(self, path: str, is_system: bool) -> T.List[str]: if path == '': path = '.' return ['-I' + path] class CompCertCCompiler(CompCertCompiler, CCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) CompCertCompiler.__init__(self) - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) opts.update({'c_std': coredata.UserComboOption('C language standard to use', ['none', 'c89', 'c99'], 'none')}) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_no_optimization_args(self): + def get_no_optimization_args(self) -> T.List[str]: return ['-O0'] - def get_output_args(self, target): + def get_output_args(self, target: str) -> T.List[str]: return ['-o{}'.format(target)] - def get_werror_args(self): + def get_werror_args(self) -> T.List[str]: return ['-Werror'] - def get_include_args(self, path, is_system): + def get_include_args(self, path: str, is_system: bool) -> T.List[str]: if path == '': path = '.' return ['-I' + path] class C2000CCompiler(C2000Compiler, CCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) C2000Compiler.__init__(self) # Override CCompiler.get_always_args - def get_always_args(self): + def get_always_args(self) -> T.List[str]: return [] - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CCompiler.get_options(self) opts.update({'c_std': coredata.UserComboOption('C language standard to use', ['none', 'c89', 'c99', 'c11'], 'none')}) return opts - def get_no_stdinc_args(self): + def get_no_stdinc_args(self) -> T.List[str]: return [] - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['c_std'] if std.value != 'none': args.append('--' + std.value) return args - def get_compile_only_args(self): + def get_compile_only_args(self) -> T.List[str]: return [] - def get_no_optimization_args(self): + def get_no_optimization_args(self) -> T.List[str]: return ['-Ooff'] - def get_output_args(self, target): + def get_output_args(self, target: str) -> T.List[str]: return ['--output_file=%s' % target] - def get_werror_args(self): + def get_werror_args(self) -> T.List[str]: return ['-change_message=error'] - def get_include_args(self, path, is_system): + def get_include_args(self, path: str, is_system: bool) -> T.List[str]: if path == '': path = '.' return ['--include_path=' + path] diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 12643b0..ea5c2c5 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -452,6 +452,7 @@ class Compiler(metaclass=abc.ABCMeta): if T.TYPE_CHECKING: language = 'unset' id = '' + warn_args = {} # type: T.Dict[str, T.List[str]] def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, info: 'MachineInfo', diff --git a/mesonbuild/compilers/mixins/arm.py b/mesonbuild/compilers/mixins/arm.py index 25fb545..f21e9de 100644 --- a/mesonbuild/compilers/mixins/arm.py +++ b/mesonbuild/compilers/mixins/arm.py @@ -81,7 +81,7 @@ class ArmCompiler(Compiler): self.warn_args = {'0': [], '1': default_warn_args, '2': default_warn_args + [], - '3': default_warn_args + []} + '3': default_warn_args + []} # type: T.Dict[str, T.List[str]] # Assembly self.can_compile_suffixes.add('s') diff --git a/mesonbuild/compilers/mixins/c2000.py b/mesonbuild/compilers/mixins/c2000.py index aca1ee8..34a1cd8 100644 --- a/mesonbuild/compilers/mixins/c2000.py +++ b/mesonbuild/compilers/mixins/c2000.py @@ -65,7 +65,7 @@ class C2000Compiler(Compiler): self.warn_args = {'0': [], '1': default_warn_args, '2': default_warn_args + [], - '3': default_warn_args + []} + '3': default_warn_args + []} # type: T.Dict[str, T.List[str]] def get_pic_args(self) -> T.List[str]: # PIC support is not enabled by default for c2000, diff --git a/mesonbuild/compilers/mixins/ccrx.py b/mesonbuild/compilers/mixins/ccrx.py index fb82797..7e92b35 100644 --- a/mesonbuild/compilers/mixins/ccrx.py +++ b/mesonbuild/compilers/mixins/ccrx.py @@ -69,7 +69,7 @@ class CcrxCompiler(Compiler): self.warn_args = {'0': [], '1': default_warn_args, '2': default_warn_args + [], - '3': default_warn_args + []} + '3': default_warn_args + []} # type: T.Dict[str, T.List[str]] def get_pic_args(self) -> T.List[str]: # PIC support is not enabled by default for CCRX, diff --git a/mesonbuild/compilers/mixins/compcert.py b/mesonbuild/compilers/mixins/compcert.py index 0f816a8..9e8c650 100644 --- a/mesonbuild/compilers/mixins/compcert.py +++ b/mesonbuild/compilers/mixins/compcert.py @@ -68,7 +68,7 @@ class CompCertCompiler(Compiler): self.warn_args = {'0': [], '1': default_warn_args, '2': default_warn_args + [], - '3': default_warn_args + []} + '3': default_warn_args + []} # type: T.Dict[str, T.List[str]] def get_always_args(self) -> T.List[str]: return [] diff --git a/mesonbuild/compilers/mixins/pgi.py b/mesonbuild/compilers/mixins/pgi.py index f6ad279..6c202ba 100644 --- a/mesonbuild/compilers/mixins/pgi.py +++ b/mesonbuild/compilers/mixins/pgi.py @@ -50,7 +50,8 @@ class PGICompiler(Compiler): self.warn_args = {'0': [], '1': default_warn_args, '2': default_warn_args, - '3': default_warn_args} + '3': default_warn_args + } # type: T.Dict[str, T.List[str]] def get_module_incdir_args(self) -> T.Tuple[str]: return ('-module', ) diff --git a/mesonbuild/compilers/mixins/xc16.py b/mesonbuild/compilers/mixins/xc16.py index edc5f2c..1f9f520 100644 --- a/mesonbuild/compilers/mixins/xc16.py +++ b/mesonbuild/compilers/mixins/xc16.py @@ -65,7 +65,7 @@ class Xc16Compiler(Compiler): self.warn_args = {'0': [], '1': default_warn_args, '2': default_warn_args + [], - '3': default_warn_args + []} + '3': default_warn_args + []} # type: T.Dict[str, T.List[str]] def get_always_args(self) -> T.List[str]: return [] -- cgit v1.1 From fe97977b00e2b3c0fec9bc85aa0bf3e11559802a Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 21 Sep 2020 18:17:16 -0700 Subject: compilers/cpp: Add type annotations --- mesonbuild/compilers/compilers.py | 11 ++ mesonbuild/compilers/cpp.py | 291 +++++++++++++++++++++++--------------- mesonbuild/compilers/cuda.py | 2 +- 3 files changed, 189 insertions(+), 115 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index ea5c2c5..01c087a 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1048,6 +1048,17 @@ class Compiler(metaclass=abc.ABCMeta): def name_string(self) -> str: return ' '.join(self.exelist) + @abc.abstractmethod + def sanity_check(self, work_dir: str, environment: 'Environment') -> None: + """Check that this compiler actually works. + + This should provide a simple compile/link test. Somthing as simple as: + ```python + main(): return 0 + ``` + is good enough here. + """ + def get_args_from_envvars(lang: str, for_machine: MachineChoice, diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index b5dbdda..4ef13e8 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -41,10 +41,17 @@ from .mixins.pgi import PGICompiler from .mixins.emscripten import EmscriptenMixin if T.TYPE_CHECKING: + from ..coredata import OptionDictType + from ..dependencies import Dependency, ExternalProgram from ..envconfig import MachineInfo + from ..environment import Environment + from ..linkers import DynamicLinker + from .mixins.clike import CLikeCompiler as CompilerMixinBase +else: + CompilerMixinBase = object -def non_msvc_eh_options(eh, args): +def non_msvc_eh_options(eh: str, args: T.List[str]) -> None: if eh == 'none': args.append('-fno-exceptions') elif eh == 's' or eh == 'c': @@ -54,7 +61,7 @@ def non_msvc_eh_options(eh, args): class CPPCompiler(CLikeCompiler, Compiler): @classmethod - def attribute_check_func(cls, name): + def attribute_check_func(cls, name: str) -> str: try: return CXX_FUNC_ATTRIBUTES.get(name, C_FUNC_ATTRIBUTES[name]) except KeyError: @@ -62,30 +69,37 @@ class CPPCompiler(CLikeCompiler, Compiler): language = 'cpp' - def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool, - info: 'MachineInfo', exe_wrap: T.Optional[str] = None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): # If a child ObjCPP class has already set it, don't set it ourselves - Compiler.__init__(self, exelist, version, for_machine, info, is_cross=is_cross, **kwargs) - CLikeCompiler.__init__(self, exe_wrap) + Compiler.__init__(self, exelist, version, for_machine, info, + is_cross=is_cross, linker=linker, + full_version=full_version) + CLikeCompiler.__init__(self, exe_wrapper) @staticmethod - def get_display_language(): + def get_display_language() -> str: return 'C++' - def get_no_stdinc_args(self): + def get_no_stdinc_args(self) -> T.List[str]: return ['-nostdinc++'] - def sanity_check(self, work_dir, environment): + def sanity_check(self, work_dir: str, environment: 'Environment') -> None: code = 'class breakCCompiler;int main(void) { return 0; }\n' return self._sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code) - def get_compiler_check_args(self): + def get_compiler_check_args(self) -> T.List[str]: # -fpermissive allows non-conforming code to compile which is necessary # for many C++ checks. Particularly, the has_header_symbol check is # too strict without this and always fails. return super().get_compiler_check_args() + ['-fpermissive'] - def has_header_symbol(self, hname, symbol, prefix, env, *, extra_args=None, dependencies=None): + def has_header_symbol(self, hname: str, symbol: str, prefix: str, + env: 'Environment', *, + extra_args: T.Optional[T.List[str]] = None, + dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: # Check if it's a C-like symbol found, cached = super().has_header_symbol(hname, symbol, prefix, env, extra_args=extra_args, @@ -103,7 +117,7 @@ class CPPCompiler(CLikeCompiler, Compiler): return self.compiles(t.format(**fargs), env, extra_args=extra_args, dependencies=dependencies) - def _test_cpp_std_arg(self, cpp_std_value): + def _test_cpp_std_arg(self, cpp_std_value: str) -> bool: # Test whether the compiler understands a -std=XY argument assert(cpp_std_value.startswith('-std=')) @@ -122,7 +136,7 @@ class CPPCompiler(CLikeCompiler, Compiler): return False @functools.lru_cache() - def _find_best_cpp_std(self, cpp_std): + def _find_best_cpp_std(self, cpp_std: str) -> str: # The initial version mapping approach to make falling back # from '-std=c++14' to '-std=c++1y' was too brittle. For instance, # Apple's Clang uses a different versioning scheme to upstream LLVM, @@ -154,11 +168,13 @@ class CPPCompiler(CLikeCompiler, Compiler): class ClangCPPCompiler(ClangCompiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - defines: T.Optional[T.List[str]] = None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrapper, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) ClangCompiler.__init__(self, defines) default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'] self.warn_args = {'0': [], @@ -166,7 +182,7 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CPPCompiler.get_options(self) opts.update({ 'eh': coredata.UserComboOption( @@ -191,7 +207,7 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler): }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': @@ -204,31 +220,39 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler): return args - def get_option_link_args(self, options): + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: if self.info.is_windows() or self.info.is_cygwin(): - return options['winlibs'].value[:] + # without a typedict mypy can't understand this. + libs = options['winlibs'].value.copy() + assert isinstance(libs, list) + for l in libs: + assert isinstance(l, str) + return libs return [] - def language_stdlib_only_link_flags(self): + def language_stdlib_only_link_flags(self) -> T.List[str]: return ['-lstdc++'] class AppleClangCPPCompiler(ClangCPPCompiler): - def language_stdlib_only_link_flags(self): + def language_stdlib_only_link_flags(self) -> T.List[str]: return ['-lc++'] class EmscriptenCPPCompiler(EmscriptenMixin, LinkerEnvVarsMixin, ClangCPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross: bool, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): if not is_cross: raise MesonException('Emscripten compiler can only be used for cross compilation.') - ClangCPPCompiler.__init__(self, exelist=exelist, version=version, - for_machine=for_machine, is_cross=is_cross, - info=info, exe_wrapper=exe_wrapper, **kwargs) + ClangCPPCompiler.__init__(self, exelist, version, for_machine, is_cross, + info, exe_wrapper=exe_wrapper, linker=linker, + defines=defines, full_version=full_version) self.id = 'emscripten' - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': @@ -237,11 +261,12 @@ class EmscriptenCPPCompiler(EmscriptenMixin, LinkerEnvVarsMixin, ClangCPPCompile class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): - CPPCompiler.__init__(self, exelist=exelist, version=version, - for_machine=for_machine, is_cross=is_cross, - info=info, exe_wrapper=exe_wrapper, **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): + CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, + info, exe_wrapper, linker=linker, full_version=full_version) ArmclangCompiler.__init__(self) default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'] self.warn_args = {'0': [], @@ -249,7 +274,7 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CPPCompiler.get_options(self) opts.update({ 'eh': coredata.UserComboOption( @@ -268,7 +293,7 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler): }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': @@ -278,14 +303,18 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler): return args - def get_option_link_args(self, options): + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] class GnuCPPCompiler(GnuCompiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrap, defines, **kwargs): - CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrap, **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): + CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, + info, exe_wrapper, linker=linker, full_version=full_version) GnuCompiler.__init__(self, defines) default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'] self.warn_args = {'0': [], @@ -293,7 +322,7 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic']} - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CPPCompiler.get_options(self) opts.update({ 'eh': coredata.UserComboOption( @@ -322,7 +351,7 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler): }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': @@ -337,44 +366,57 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler): args.append('-D_GLIBCXX_DEBUG=1') return args - def get_option_link_args(self, options): + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: if self.info.is_windows() or self.info.is_cygwin(): - return options['winlibs'].value[:] + # without a typedict mypy can't understand this. + libs = options['winlibs'].value.copy() + assert isinstance(libs, list) + for l in libs: + assert isinstance(l, str) + return libs return [] - def get_pch_use_args(self, pch_dir, header): + def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: return ['-fpch-preprocess', '-include', os.path.basename(header)] - def language_stdlib_only_link_flags(self): + def language_stdlib_only_link_flags(self) -> T.List[str]: return ['-lstdc++'] class PGICPPCompiler(PGICompiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): - CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): + CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, + info, exe_wrapper, linker=linker, full_version=full_version) PGICompiler.__init__(self) class NvidiaHPC_CPPCompiler(PGICompiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): - CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): + CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, + info, exe_wrapper, linker=linker, full_version=full_version) PGICompiler.__init__(self) self.id = 'nvidia_hpc' class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - defines=None, **kwargs): - GnuCPPCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, defines, - **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + defines: T.Optional[T.Dict[str, str]] = None, + full_version: T.Optional[str] = None): + GnuCPPCompiler.__init__(self, exelist, version, for_machine, is_cross, + info, exe_wrapper, linker=linker, + full_version=full_version, defines=defines) ElbrusCompiler.__init__(self) - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CPPCompiler.get_options(self) cpp_stds = [ @@ -408,7 +450,9 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler): # Elbrus C++ compiler does not have lchmod, but there is only linker warning, not compiler error. # So we should explicitly fail at this case. - def has_function(self, funcname, prefix, env, *, extra_args=None, dependencies=None): + def has_function(self, funcname: str, prefix: str, env: 'Environment', *, + extra_args: T.Optional[T.List[str]] = None, + dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: if funcname == 'lchmod': return False, False else: @@ -417,7 +461,7 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler): dependencies=dependencies) # Elbrus C++ compiler does not support RTTI, so don't check for it. - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': @@ -431,10 +475,12 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler): class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrap, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrap, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) IntelGnuLikeCompiler.__init__(self) self.lang_header = 'c++-header' default_warn_args = ['-Wall', '-w3', '-diag-disable:remark', @@ -444,7 +490,7 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra']} - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CPPCompiler.get_options(self) # Every Unix compiler under the sun seems to accept -std=c++03, # with the exception of ICC. Instead of preventing the user from @@ -474,7 +520,7 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': @@ -491,11 +537,11 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): args.append('-D_GLIBCXX_DEBUG=1') return args - def get_option_link_args(self, options): + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] -class VisualStudioLikeCPPCompilerMixin: +class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase): """Mixin for C++ specific method overrides in MSVC-like compilers.""" @@ -511,10 +557,11 @@ class VisualStudioLikeCPPCompilerMixin: 'c++latest': (False, "latest"), } - def get_option_link_args(self, options): - return options['winlibs'].value[:] + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: + # need a typeddict for this + return T.cast(T.List[str], options['winlibs'].value[:]) - def _get_options_impl(self, opts, cpp_stds: T.List[str]): + def _get_options_impl(self, opts: 'OptionDictType', cpp_stds: T.List[str]) -> 'OptionDictType': opts.update({ 'eh': coredata.UserComboOption( 'C++ exception handling type.', @@ -534,7 +581,7 @@ class VisualStudioLikeCPPCompilerMixin: }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] eh = options['eh'] @@ -558,19 +605,19 @@ class VisualStudioLikeCPPCompilerMixin: return args - def get_compiler_check_args(self): + def get_compiler_check_args(self) -> T.List[str]: # XXX: this is a hack because so much GnuLike stuff is in the base CPPCompiler class. return CLikeCompiler.get_compiler_check_args(self) -class CPP11AsCPP14Mixin: +class CPP11AsCPP14Mixin(CompilerMixinBase): """Mixin class for VisualStudio and ClangCl to replace C++11 std with C++14. This is a limitation of Clang and MSVC that ICL doesn't share. """ - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: # Note: there is no explicit flag for supporting C++11; we attempt to do the best we can # which means setting the C++ standard version to C++14, in compilers that support it # (i.e., after VS2015U3) @@ -590,14 +637,18 @@ class CPP11AsCPP14Mixin: class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, MSVCCompiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross: bool, info: 'MachineInfo', exe_wrap, target, **kwargs): - CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrap, **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', target: str, + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): + CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, + info, exe_wrapper, linker=linker, full_version=full_version) MSVCCompiler.__init__(self, target) self.base_options = ['b_pch', 'b_vscrt', 'b_ndebug'] # FIXME add lto, pgo and the like self.id = 'msvc' - def get_options(self): + def get_options(self) -> 'OptionDictType': cpp_stds = ['none', 'c++11', 'vc++11'] # Visual Studio 2015 and later if version_compare(self.version, '>=19'): @@ -607,7 +658,7 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi cpp_stds.extend(['vc++14', 'c++17', 'vc++17']) return self._get_options_impl(super().get_options(), cpp_stds) - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: if options['std'].value != 'none' and version_compare(self.version, '<19.00.24210'): mlog.warning('This version of MSVC does not support cpp_std arguments') options = copy.copy(options) @@ -624,40 +675,48 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi return args class ClangClCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, ClangClCompiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrap, target, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', target: str, + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrap, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) ClangClCompiler.__init__(self, target) self.id = 'clang-cl' - def get_options(self): + def get_options(self) -> 'OptionDictType': cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest'] return self._get_options_impl(super().get_options(), cpp_stds) class IntelClCPPCompiler(VisualStudioLikeCPPCompilerMixin, IntelVisualStudioLikeCompiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrap, target, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', target: str, + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrap, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) IntelVisualStudioLikeCompiler.__init__(self, target) - def get_options(self): + def get_options(self) -> 'OptionDictType': # This has only been tested with version 19.0, cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest'] return self._get_options_impl(super().get_options(), cpp_stds) class ArmCPPCompiler(ArmCompiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrap=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrap, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) ArmCompiler.__init__(self) - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CPPCompiler.get_options(self) opts.update({ 'std': coredata.UserComboOption( @@ -668,7 +727,7 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler): }) return opts - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value == 'c++11': @@ -677,67 +736,71 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler): args.append('--cpp') return args - def get_option_link_args(self, options): + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_compiler_check_args(self): + def get_compiler_check_args(self) -> T.List[str]: return [] class CcrxCPPCompiler(CcrxCompiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrap=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrap, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) CcrxCompiler.__init__(self) # Override CCompiler.get_always_args - def get_always_args(self): + def get_always_args(self) -> T.List[str]: return ['-nologo', '-lang=cpp'] - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_compile_only_args(self): + def get_compile_only_args(self) -> T.List[str]: return [] - def get_output_args(self, target): + def get_output_args(self, target: str) -> T.List[str]: return ['-output=obj=%s' % target] - def get_option_link_args(self, options): + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_compiler_check_args(self): + def get_compiler_check_args(self) -> T.List[str]: return [] class C2000CPPCompiler(C2000Compiler, CPPCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrap=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, - info, exe_wrap, **kwargs) + info, exe_wrapper, linker=linker, full_version=full_version) C2000Compiler.__init__(self) - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = CPPCompiler.get_options(self) opts.update({'cpp_std': coredata.UserComboOption('C++ language standard to use', ['none', 'c++03'], 'none')}) return opts - def get_always_args(self): + def get_always_args(self) -> T.List[str]: return ['-nologo', '-lang=cpp'] - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_compile_only_args(self): + def get_compile_only_args(self) -> T.List[str]: return [] - def get_output_args(self, target): + def get_output_args(self, target: str) -> T.List[str]: return ['-output=obj=%s' % target] - def get_option_link_args(self, options): + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_compiler_check_args(self): + def get_compiler_check_args(self) -> T.List[str]: return [] diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 482d504..b227ad3 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -184,7 +184,7 @@ class CudaCompiler(Compiler): overrides = {name: opt.value for name, opt in options.copy().items()} return OptionOverrideProxy(overrides, self.host_compiler.get_options()) - def get_option_compile_args(self, options): + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] # On Windows, the version of the C++ standard used by nvcc is dictated by # the combination of CUDA version and MSVC version; the --std= is thus ignored -- cgit v1.1 From 1513aa437dd397934eff176c81d742a78e54ddb9 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 22 Sep 2020 10:49:46 -0700 Subject: compilers: move split_shlib_to_parts to the base compiler Only the GnuLikeCompiler overrides this, and it's implemented multiple places --- mesonbuild/compilers/compilers.py | 3 +++ mesonbuild/compilers/cs.py | 3 --- mesonbuild/compilers/java.py | 3 --- mesonbuild/compilers/mixins/clike.py | 3 --- 4 files changed, 3 insertions(+), 9 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 01c087a..578f654 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1059,6 +1059,9 @@ class Compiler(metaclass=abc.ABCMeta): is good enough here. """ + def split_shlib_to_parts(self, fname: str) -> T.Tuple[T.Optional[str], str]: + return None, fname + def get_args_from_envvars(lang: str, for_machine: MachineChoice, diff --git a/mesonbuild/compilers/cs.py b/mesonbuild/compilers/cs.py index b269aec..b8e673e 100644 --- a/mesonbuild/compilers/cs.py +++ b/mesonbuild/compilers/cs.py @@ -61,9 +61,6 @@ class CsCompiler(BasicLinkerIsCompilerMixin, Compiler): def get_werror_args(self): return ['-warnaserror'] - def split_shlib_to_parts(self, fname): - return None, fname - def get_dependency_gen_args(self, outtarget, outfile): return [] diff --git a/mesonbuild/compilers/java.py b/mesonbuild/compilers/java.py index 8405b43..e353950 100644 --- a/mesonbuild/compilers/java.py +++ b/mesonbuild/compilers/java.py @@ -37,9 +37,6 @@ class JavaCompiler(BasicLinkerIsCompilerMixin, Compiler): def get_werror_args(self): return ['-Werror'] - def split_shlib_to_parts(self, fname): - return None, fname - def get_dependency_gen_args(self, outtarget, outfile): return [] diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index e146f5f..2802aaf 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -169,9 +169,6 @@ class CLikeCompiler(Compiler): # Almost every compiler uses this for disabling warnings return ['-w'] - def split_shlib_to_parts(self, fname: str) -> T.Tuple[T.Optional[str], str]: - return None, fname - def depfile_for_object(self, objfile: str) -> str: return objfile + '.' + self.get_depfile_suffix() -- cgit v1.1 From e7f0890cb9a26e2e64e79739c80fddb609d484cf Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 22 Sep 2020 10:54:16 -0700 Subject: compilers: move get_dependency_gen_args to base Compiler So that every subclass doesn't have to reimplement it. Especially since the Gnu implementation moved out of the CCompiler and into the GnuLikeCompiler mixin --- mesonbuild/compilers/compilers.py | 3 +++ mesonbuild/compilers/cs.py | 3 --- mesonbuild/compilers/cuda.py | 3 --- mesonbuild/compilers/d.py | 4 ---- mesonbuild/compilers/fortran.py | 3 --- mesonbuild/compilers/java.py | 3 --- mesonbuild/compilers/mixins/arm.py | 2 -- mesonbuild/compilers/mixins/c2000.py | 4 ---- mesonbuild/compilers/mixins/ccrx.py | 4 ---- mesonbuild/compilers/mixins/compcert.py | 4 ---- mesonbuild/compilers/mixins/pgi.py | 3 --- mesonbuild/compilers/mixins/visualstudio.py | 3 --- mesonbuild/compilers/mixins/xc16.py | 4 ---- 13 files changed, 3 insertions(+), 40 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 578f654..a66ecdc 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1062,6 +1062,9 @@ class Compiler(metaclass=abc.ABCMeta): def split_shlib_to_parts(self, fname: str) -> T.Tuple[T.Optional[str], str]: return None, fname + def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: + return [] + def get_args_from_envvars(lang: str, for_machine: MachineChoice, diff --git a/mesonbuild/compilers/cs.py b/mesonbuild/compilers/cs.py index b8e673e..01d2adb 100644 --- a/mesonbuild/compilers/cs.py +++ b/mesonbuild/compilers/cs.py @@ -61,9 +61,6 @@ class CsCompiler(BasicLinkerIsCompilerMixin, Compiler): def get_werror_args(self): return ['-warnaserror'] - def get_dependency_gen_args(self, outtarget, outfile): - return [] - def get_linker_exelist(self): return self.exelist[:] diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index b227ad3..e6b4d04 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -213,9 +213,6 @@ class CudaCompiler(Compiler): def get_soname_args(self, *args): return self._cook_link_args(self.host_compiler.get_soname_args(*args)) - def get_dependency_gen_args(self, outtarget, outfile): - return [] - def get_compile_only_args(self): return ['-c'] diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index ca7f80d..2be19f7 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -99,10 +99,6 @@ class DmdLikeCompilerMixin: def get_werror_args(self): return ['-w'] - def get_dependency_gen_args(self, outtarget, outfile): - # DMD and LDC does not currently return Makefile-compatible dependency info. - return [] - def get_coverage_args(self): return ['-cov'] diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index 9c2f5bf..8d17d13 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -108,9 +108,6 @@ class FortranCompiler(CLikeCompiler, Compiler): def get_debug_args(self, is_debug): return clike_debug_args[is_debug] - def get_dependency_gen_args(self, outtarget, outfile): - return [] - def get_preprocess_only_args(self): return ['-cpp'] + super().get_preprocess_only_args() diff --git a/mesonbuild/compilers/java.py b/mesonbuild/compilers/java.py index e353950..fb4ff7c 100644 --- a/mesonbuild/compilers/java.py +++ b/mesonbuild/compilers/java.py @@ -37,9 +37,6 @@ class JavaCompiler(BasicLinkerIsCompilerMixin, Compiler): def get_werror_args(self): return ['-Werror'] - def get_dependency_gen_args(self, outtarget, outfile): - return [] - def get_compile_only_args(self): return [] diff --git a/mesonbuild/compilers/mixins/arm.py b/mesonbuild/compilers/mixins/arm.py index f21e9de..ee7d337 100644 --- a/mesonbuild/compilers/mixins/arm.py +++ b/mesonbuild/compilers/mixins/arm.py @@ -96,7 +96,6 @@ class ArmCompiler(Compiler): def get_always_args(self) -> T.List[str]: return [] - # Override CCompiler.get_dependency_gen_args def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: return ['--depend_target', outtarget, '--depend', outfile, '--depend_single_line'] @@ -171,7 +170,6 @@ class ArmclangCompiler(Compiler): # so it might change semantics at any time. return ['-include-pch', os.path.join(pch_dir, self.get_pch_name(header))] - # Override CCompiler.get_dependency_gen_args def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: return ['-MD', '-MT', outtarget, '-MF', outfile] diff --git a/mesonbuild/compilers/mixins/c2000.py b/mesonbuild/compilers/mixins/c2000.py index 34a1cd8..287aaa8 100644 --- a/mesonbuild/compilers/mixins/c2000.py +++ b/mesonbuild/compilers/mixins/c2000.py @@ -81,10 +81,6 @@ class C2000Compiler(Compiler): def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: return [] - # Override CCompiler.get_dependency_gen_args - def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: - return [] - def thread_flags(self, env: 'Environment') -> T.List[str]: return [] diff --git a/mesonbuild/compilers/mixins/ccrx.py b/mesonbuild/compilers/mixins/ccrx.py index 7e92b35..eba4c45 100644 --- a/mesonbuild/compilers/mixins/ccrx.py +++ b/mesonbuild/compilers/mixins/ccrx.py @@ -85,10 +85,6 @@ class CcrxCompiler(Compiler): def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: return [] - # Override CCompiler.get_dependency_gen_args - def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: - return [] - def thread_flags(self, env: 'Environment') -> T.List[str]: return [] diff --git a/mesonbuild/compilers/mixins/compcert.py b/mesonbuild/compilers/mixins/compcert.py index 9e8c650..3211f6a 100644 --- a/mesonbuild/compilers/mixins/compcert.py +++ b/mesonbuild/compilers/mixins/compcert.py @@ -99,10 +99,6 @@ class CompCertCompiler(Compiler): patched_args.append(arg) return patched_args - # Override CCompiler.get_dependency_gen_args - def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: - return [] - def thread_flags(self, env: 'Environment') -> T.List[str]: return [] diff --git a/mesonbuild/compilers/mixins/pgi.py b/mesonbuild/compilers/mixins/pgi.py index 6c202ba..61dee8d 100644 --- a/mesonbuild/compilers/mixins/pgi.py +++ b/mesonbuild/compilers/mixins/pgi.py @@ -86,9 +86,6 @@ class PGICompiler(Compiler): parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) return parameter_list - def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: - return [] - def get_always_args(self) -> T.List[str]: return [] diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py index 77f8dfc..3494bee 100644 --- a/mesonbuild/compilers/mixins/visualstudio.py +++ b/mesonbuild/compilers/mixins/visualstudio.py @@ -194,9 +194,6 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta): args = [arg for arg in args if arg != '/Gw'] return args - def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: - return [] - def linker_to_compiler_args(self, args: T.List[str]) -> T.List[str]: return ['/link'] + args diff --git a/mesonbuild/compilers/mixins/xc16.py b/mesonbuild/compilers/mixins/xc16.py index 1f9f520..77c4690 100644 --- a/mesonbuild/compilers/mixins/xc16.py +++ b/mesonbuild/compilers/mixins/xc16.py @@ -84,10 +84,6 @@ class Xc16Compiler(Compiler): def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: return [] - # Override CCompiler.get_dependency_gen_args - def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: - return [] - def thread_flags(self, env: 'Environment') -> T.List[str]: return [] -- cgit v1.1 From 413f4d87e96905dcfcd082af9b59b9396d19f4b8 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 22 Sep 2020 11:15:01 -0700 Subject: compilers/cs: Add type annotations --- mesonbuild/compilers/compilers.py | 8 ++++ mesonbuild/compilers/cs.py | 73 ++++++++++++++------------------- mesonbuild/compilers/mixins/islinker.py | 3 +- 3 files changed, 40 insertions(+), 44 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index a66ecdc..6f15e48 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1065,6 +1065,14 @@ class Compiler(metaclass=abc.ABCMeta): def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: return [] + def get_std_exe_link_args(self) -> T.List[str]: + # TODO: is this a linker property? + return [] + + def get_include_args(self, path: str, is_system: bool) -> T.List[str]: + return [] + + def get_args_from_envvars(lang: str, for_machine: MachineChoice, diff --git a/mesonbuild/compilers/cs.py b/mesonbuild/compilers/cs.py index 01d2adb..ba65d07 100644 --- a/mesonbuild/compilers/cs.py +++ b/mesonbuild/compilers/cs.py @@ -13,6 +13,7 @@ # limitations under the License. import os.path, subprocess +import textwrap import typing as T from ..mesonlib import EnvironmentException @@ -22,6 +23,7 @@ from .mixins.islinker import BasicLinkerIsCompilerMixin if T.TYPE_CHECKING: from ..envconfig import MachineInfo + from ..environment import Environment cs_optimization_args = {'0': [], 'g': [], @@ -29,57 +31,43 @@ cs_optimization_args = {'0': [], '2': ['-optimize+'], '3': ['-optimize+'], 's': ['-optimize+'], - } + } # type: T.Dict[str, T.List[str]] class CsCompiler(BasicLinkerIsCompilerMixin, Compiler): language = 'cs' - def __init__(self, exelist, version, for_machine: MachineChoice, - info: 'MachineInfo', comp_id, runner=None): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + info: 'MachineInfo', comp_id: str, runner: T.Optional[str] = None): super().__init__(exelist, version, for_machine, info) self.id = comp_id self.runner = runner @classmethod - def get_display_language(cls): + def get_display_language(cls) -> str: return 'C sharp' - def get_always_args(self): + def get_always_args(self) -> T.List[str]: return ['/nologo'] - def get_linker_always_args(self): + def get_linker_always_args(self) -> T.List[str]: return ['/nologo'] - def get_output_args(self, fname): + def get_output_args(self, fname: str) -> T.List[str]: return ['-out:' + fname] - def get_link_args(self, fname): + def get_link_args(self, fname: str) -> T.List[str]: return ['-r:' + fname] - def get_werror_args(self): + def get_werror_args(self) -> T.List[str]: return ['-warnaserror'] - def get_linker_exelist(self): - return self.exelist[:] - - def get_compile_only_args(self): - return [] - - def get_coverage_args(self): - return [] - - def get_std_exe_link_args(self): - return [] - - def get_include_args(self, path): - return [] - - def get_pic_args(self): + def get_pic_args(self) -> T.List[str]: return [] - def compute_parameters_with_absolute_paths(self, parameter_list, build_dir): + def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], + build_dir: str) -> T.List[str]: for idx, i in enumerate(parameter_list): if i[:2] == '-L': parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) @@ -88,26 +76,27 @@ class CsCompiler(BasicLinkerIsCompilerMixin, Compiler): return parameter_list - def get_pch_use_args(self, pch_dir, header): + def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: return [] - def get_pch_name(self, header_name): + def get_pch_name(self, header_name: str) -> str: return '' - def sanity_check(self, work_dir, environment): + def sanity_check(self, work_dir: str, environment: 'Environment') -> None: src = 'sanity.cs' obj = 'sanity.exe' source_name = os.path.join(work_dir, src) with open(source_name, 'w') as ofile: - ofile.write('''public class Sanity { - static public void Main () { - } -} -''') + ofile.write(textwrap.dedent(''' + public class Sanity { + static public void Main () { + } + } + ''')) pc = subprocess.Popen(self.exelist + self.get_always_args() + [src], cwd=work_dir) pc.wait() if pc.returncode != 0: - raise EnvironmentException('Mono compiler %s can not compile programs.' % self.name_string()) + raise EnvironmentException('C# compiler %s can not compile programs.' % self.name_string()) if self.runner: cmdlist = [self.runner, obj] else: @@ -117,32 +106,32 @@ class CsCompiler(BasicLinkerIsCompilerMixin, Compiler): if pe.returncode != 0: raise EnvironmentException('Executables created by Mono compiler %s are not runnable.' % self.name_string()) - def needs_static_linker(self): + def needs_static_linker(self) -> bool: return False - def get_buildtype_args(self, buildtype): + def get_buildtype_args(self, buildtype: str) -> T.List[str]: return mono_buildtype_args[buildtype] - def get_debug_args(self, is_debug): + def get_debug_args(self, is_debug: bool) -> T.List[str]: return ['-debug'] if is_debug else [] - def get_optimization_args(self, optimization_level): + def get_optimization_args(self, optimization_level: str) -> T.List[str]: return cs_optimization_args[optimization_level] class MonoCompiler(CsCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, info: 'MachineInfo'): super().__init__(exelist, version, for_machine, info, 'mono', runner='mono') class VisualStudioCsCompiler(CsCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, info: 'MachineInfo'): super().__init__(exelist, version, for_machine, info, 'csc') - def get_buildtype_args(self, buildtype): + def get_buildtype_args(self, buildtype: str) -> T.List[str]: res = mono_buildtype_args[buildtype] if not self.info.is_windows(): tmp = [] diff --git a/mesonbuild/compilers/mixins/islinker.py b/mesonbuild/compilers/mixins/islinker.py index ce7a8af..2445eec 100644 --- a/mesonbuild/compilers/mixins/islinker.py +++ b/mesonbuild/compilers/mixins/islinker.py @@ -97,8 +97,7 @@ class BasicLinkerIsCompilerMixin(Compiler): return [] def get_coverage_link_args(self) -> T.List[str]: - m = "Linker {} doesn't implement coverage data generation.".format(self.id) - raise mesonlib.EnvironmentException(m) + return [] def no_undefined_link_args(self) -> T.List[str]: return [] -- cgit v1.1 From 224a75248918e35e0cb55487c558ef6fa7e84553 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 23 Sep 2020 14:33:20 -0700 Subject: compilres: move depfile_for_object to compiler --- mesonbuild/compilers/compilers.py | 5 +++++ mesonbuild/compilers/cuda.py | 5 +---- mesonbuild/compilers/d.py | 6 ------ mesonbuild/compilers/mixins/clike.py | 3 --- 4 files changed, 6 insertions(+), 13 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 6f15e48..0b52b8b 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1072,6 +1072,11 @@ class Compiler(metaclass=abc.ABCMeta): def get_include_args(self, path: str, is_system: bool) -> T.List[str]: return [] + def depfile_for_object(self, objfile: str) -> str: + return objfile + '.' + self.get_depfile_suffix() + + def get_depfile_suffix(self) -> str: + raise EnvironmentError('{} does not implement get_depfile_suffix'.format(self.id)) def get_args_from_envvars(lang: str, diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index e6b4d04..5fdf024 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -251,10 +251,7 @@ class CudaCompiler(Compiler): def get_link_debugfile_args(self, targetfile): return self._cook_link_args(self.host_compiler.get_link_debugfile_args(targetfile)) - def depfile_for_object(self, objfile): - return objfile + '.' + self.get_depfile_suffix() - - def get_depfile_suffix(self): + def get_depfile_suffix(self) -> str: return 'd' def get_buildtype_linker_args(self, buildtype): diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index 2be19f7..5f5f7d4 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -111,9 +111,6 @@ class DmdLikeCompilerMixin: def get_compile_only_args(self): return ['-c'] - def depfile_for_object(self, objfile): - return objfile + '.' + self.get_depfile_suffix() - def get_depfile_suffix(self): return 'deps' @@ -469,9 +466,6 @@ class DCompiler(Compiler): def needs_static_linker(self): return True - def depfile_for_object(self, objfile): - return objfile + '.' + self.get_depfile_suffix() - def get_depfile_suffix(self): return 'deps' diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 2802aaf..840dc30 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -169,9 +169,6 @@ class CLikeCompiler(Compiler): # Almost every compiler uses this for disabling warnings return ['-w'] - def depfile_for_object(self, objfile: str) -> str: - return objfile + '.' + self.get_depfile_suffix() - def get_depfile_suffix(self) -> str: return 'd' -- cgit v1.1 From d3a059b55fac4e9cc3c7c306b2e6a4cf5e424aad Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 22 Sep 2020 15:18:24 -0700 Subject: compilers/cuda: make type safe --- mesonbuild/compilers/compilers.py | 10 +++ mesonbuild/compilers/cuda.py | 114 ++++++++++++++++++++--------------- mesonbuild/compilers/d.py | 6 -- mesonbuild/compilers/java.py | 6 -- mesonbuild/compilers/mixins/clike.py | 7 --- mesonbuild/compilers/rust.py | 3 - 6 files changed, 75 insertions(+), 71 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 0b52b8b..fbb3eae 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -863,6 +863,9 @@ class Compiler(metaclass=abc.ABCMeta): def thread_flags(self, env: 'Environment') -> T.List[str]: return [] + def thread_link_flags(self, env: 'Environment') -> T.List[str]: + return self.linker.thread_flags(env) + def openmp_flags(self) -> T.List[str]: raise EnvironmentException('Language %s does not support OpenMP flags.' % self.get_display_language()) @@ -954,6 +957,9 @@ class Compiler(metaclass=abc.ABCMeta): def bitcode_args(self) -> T.List[str]: return self.linker.bitcode_args() + def get_buildtype_args(self, buildtype: str) -> T.List[str]: + raise EnvironmentException('{} does not implement get_buildtype_args'.format(self.id)) + def get_buildtype_linker_args(self, buildtype: str) -> T.List[str]: return self.linker.get_buildtype_args(buildtype) @@ -1078,6 +1084,10 @@ class Compiler(metaclass=abc.ABCMeta): def get_depfile_suffix(self) -> str: raise EnvironmentError('{} does not implement get_depfile_suffix'.format(self.id)) + def get_no_stdinc_args(self) -> T.List[str]: + """Arguments to turn off default inclusion of standard libraries.""" + return [] + def get_args_from_envvars(lang: str, for_machine: MachineChoice, diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 5fdf024..bf46a7d 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -12,9 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +import enum import os.path import typing as T -from functools import partial from .. import coredata from .. import mlog @@ -23,8 +23,18 @@ from .compilers import (Compiler, cuda_buildtype_args, cuda_optimization_args, cuda_debug_args) if T.TYPE_CHECKING: + from ..build import BuildTarget + from ..coredata import OptionDictType + from ..dependencies import Dependency, ExternalProgram from ..environment import Environment # noqa: F401 from ..envconfig import MachineInfo + from ..linkers import DynamicLinker + + +class _Phase(enum.Enum): + + COMPILER = 'compiler' + LINKER = 'linker' class CudaCompiler(Compiler): @@ -32,12 +42,14 @@ class CudaCompiler(Compiler): LINKER_PREFIX = '-Xlinker=' language = 'cuda' - _universal_flags = {'compiler': ['-I', '-D', '-U', '-E'], 'linker': ['-l', '-L']} + _universal_flags = {_Phase.COMPILER: ['-I', '-D', '-U', '-E'], _Phase.LINKER: ['-l', '-L']} # type: T.Dict[_Phase, T.List[str]] - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, exe_wrapper, host_compiler, info: 'MachineInfo', **kwargs): - super().__init__(exelist, version, for_machine, info, **kwargs) - self.is_cross = is_cross + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, exe_wrapper: T.Optional['ExternalProgram'], + host_compiler: Compiler, info: 'MachineInfo', + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): + super().__init__(exelist, version, for_machine, info, linker=linker, full_version=full_version, is_cross=is_cross) self.exe_wrapper = exe_wrapper self.host_compiler = host_compiler self.base_options = host_compiler.base_options @@ -45,29 +57,23 @@ class CudaCompiler(Compiler): self.warn_args = {level: self._to_host_flags(flags) for level, flags in host_compiler.warn_args.items()} @classmethod - def _to_host_flags(cls, flags, phase='compiler'): - return list(map(partial(cls._to_host_flag, phase=phase), flags)) + def _to_host_flags(cls, flags: T.List[str], phase: _Phase = _Phase.COMPILER) -> T.List[str]: + return [cls._to_host_flag(f, phase=phase) for f in flags] @classmethod - def _to_host_flag(cls, flag, phase): + def _to_host_flag(cls, flag: str, phase: _Phase) -> str: if not flag[0] in ['-', '/'] or flag[:2] in cls._universal_flags[phase]: return flag - return '-X{}={}'.format(phase, flag) + return '-X{}={}'.format(phase.value, flag) - def needs_static_linker(self): + def needs_static_linker(self) -> bool: return False - def get_always_args(self): - return [] - - def get_no_stdinc_args(self): - return [] - - def thread_link_flags(self, environment): + def thread_link_flags(self, environment: 'Environment') -> T.List[str]: return self._to_host_flags(self.host_compiler.thread_link_flags(environment)) - def sanity_check(self, work_dir, environment): + def sanity_check(self, work_dir: str, environment: 'Environment') -> None: mlog.debug('Sanity testing ' + self.get_display_language() + ' compiler:', ' '.join(self.exelist)) mlog.debug('Is cross compiler: %s.' % str(self.is_cross)) @@ -138,7 +144,7 @@ class CudaCompiler(Compiler): if self.exe_wrapper is None: return else: - cmdlist = self.exe_wrapper + [binary_name] + cmdlist = self.exe_wrapper.get_command() + [binary_name] else: cmdlist = self.exelist + ['--run', '"' + binary_name + '"'] mlog.debug('Sanity check run command line: ', ' '.join(cmdlist)) @@ -160,7 +166,10 @@ class CudaCompiler(Compiler): else: mlog.debug('cudaGetDeviceCount() returned ' + stde) - def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None): + def has_header_symbol(self, hname: str, symbol: str, prefix: str, + env: 'Environment', *, + extra_args: T.Optional[T.List[str]] = None, + dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: result, cached = super().has_header_symbol(hname, symbol, prefix, env, extra_args=extra_args, dependencies=dependencies) if result: return True, cached @@ -173,15 +182,15 @@ class CudaCompiler(Compiler): int main(void) {{ return 0; }}''' return self.compiles(t.format(**fargs), env, extra_args=extra_args, dependencies=dependencies) - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = super().get_options() opts.update({'cuda_std': coredata.UserComboOption('C++ language standard to use', ['none', 'c++03', 'c++11', 'c++14'], 'none')}) return opts - def _to_host_compiler_options(self, options): - overrides = {name: opt.value for name, opt in options.copy().items()} + def _to_host_compiler_options(self, options: 'OptionDictType') -> 'OptionDictType': + overrides = {name: opt.value for name, opt in options.items()} return OptionOverrideProxy(overrides, self.host_compiler.get_options()) def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: @@ -205,56 +214,61 @@ class CudaCompiler(Compiler): arg = arg.replace('-Wl,', '', 1) arg = arg.replace(' ', '\\') # espace whitespace cooked.append(arg) - return cls._to_host_flags(cooked, 'linker') + return cls._to_host_flags(cooked, _Phase.LINKER) - def get_option_link_args(self, options): + def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return self._cook_link_args(self.host_compiler.get_option_link_args(self._to_host_compiler_options(options))) - def get_soname_args(self, *args): - return self._cook_link_args(self.host_compiler.get_soname_args(*args)) + def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str, + suffix: str, soversion: str, + darwin_versions: T.Tuple[str, str], + is_shared_module: bool) -> T.List[str]: + return self._cook_link_args(self.host_compiler.get_soname_args( + env, prefix, shlib_name, suffix, soversion, darwin_versions, + is_shared_module)) - def get_compile_only_args(self): + def get_compile_only_args(self) -> T.List[str]: return ['-c'] - def get_no_optimization_args(self): + def get_no_optimization_args(self) -> T.List[str]: return ['-O0'] - def get_optimization_args(self, optimization_level): + def get_optimization_args(self, optimization_level: str) -> T.List[str]: # alternatively, consider simply redirecting this to the host compiler, which would # give us more control over options like "optimize for space" (which nvcc doesn't support): # return self._to_host_flags(self.host_compiler.get_optimization_args(optimization_level)) return cuda_optimization_args[optimization_level] - def get_debug_args(self, is_debug): + def get_debug_args(self, is_debug: bool) -> T.List[str]: return cuda_debug_args[is_debug] - def get_werror_args(self): + def get_werror_args(self) -> T.List[str]: return ['-Werror=cross-execution-space-call,deprecated-declarations,reorder'] - def get_warn_args(self, level): + def get_warn_args(self, level: str) -> T.List[str]: return self.warn_args[level] - def get_buildtype_args(self, buildtype): + def get_buildtype_args(self, buildtype: str) -> T.List[str]: # nvcc doesn't support msvc's "Edit and Continue" PDB format; "downgrade" to # a regular PDB to avoid cl's warning to that effect (D9025 : overriding '/ZI' with '/Zi') host_args = ['/Zi' if arg == '/ZI' else arg for arg in self.host_compiler.get_buildtype_args(buildtype)] return cuda_buildtype_args[buildtype] + self._to_host_flags(host_args) - def get_include_args(self, path, is_system): + def get_include_args(self, path: str, is_system: bool) -> T.List[str]: if path == '': path = '.' return ['-I' + path] - def get_compile_debugfile_args(self, rel_obj, **kwargs): - return self._to_host_flags(self.host_compiler.get_compile_debugfile_args(rel_obj, **kwargs)) + def get_compile_debugfile_args(self, rel_obj: str, pch: bool = False) -> T.List[str]: + return self._to_host_flags(self.host_compiler.get_compile_debugfile_args(rel_obj, pch)) - def get_link_debugfile_args(self, targetfile): + def get_link_debugfile_args(self, targetfile: str) -> T.List[str]: return self._cook_link_args(self.host_compiler.get_link_debugfile_args(targetfile)) def get_depfile_suffix(self) -> str: return 'd' - def get_buildtype_linker_args(self, buildtype): + def get_buildtype_linker_args(self, buildtype: str) -> T.List[str]: return self._cook_link_args(self.host_compiler.get_buildtype_linker_args(buildtype)) def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, @@ -264,13 +278,14 @@ class CudaCompiler(Compiler): env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath) return (self._cook_link_args(rpath_args), rpath_dirs_to_remove) - def linker_to_compiler_args(self, args): + def linker_to_compiler_args(self, args: T.List[str]) -> T.List[str]: return args - def get_pic_args(self): + def get_pic_args(self) -> T.List[str]: return self._to_host_flags(self.host_compiler.get_pic_args()) - def compute_parameters_with_absolute_paths(self, parameter_list, build_dir): + def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], + build_dir: str) -> T.List[str]: return [] def get_output_args(self, target: str) -> T.List[str]: @@ -279,13 +294,14 @@ class CudaCompiler(Compiler): def get_std_exe_link_args(self) -> T.List[str]: return self._cook_link_args(self.host_compiler.get_std_exe_link_args()) - def find_library(self, libname, env, extra_dirs, libtype: LibType = LibType.PREFER_SHARED): + def find_library(self, libname: str, env: 'Environment', extra_dirs: T.List[str], + libtype: LibType = LibType.PREFER_SHARED) -> T.Optional[T.List[str]]: return ['-l' + libname] # FIXME - def get_crt_compile_args(self, crt_val, buildtype): + def get_crt_compile_args(self, crt_val: str, buildtype: str) -> T.List[str]: return self._to_host_flags(self.host_compiler.get_crt_compile_args(crt_val, buildtype)) - def get_crt_link_args(self, crt_val, buildtype): + def get_crt_link_args(self, crt_val: str, buildtype: str) -> T.List[str]: # nvcc defaults to static, release version of msvc runtime and provides no # native option to override it; override it with /NODEFAULTLIB host_link_arg_overrides = [] @@ -294,11 +310,11 @@ class CudaCompiler(Compiler): host_link_arg_overrides += ['/NODEFAULTLIB:LIBCMT.lib'] return self._cook_link_args(host_link_arg_overrides + self.host_compiler.get_crt_link_args(crt_val, buildtype)) - def get_target_link_args(self, target): + def get_target_link_args(self, target: 'BuildTarget') -> T.List[str]: return self._cook_link_args(super().get_target_link_args(target)) - def get_dependency_compile_args(self, dep): + def get_dependency_compile_args(self, dep: 'Dependency') -> T.List[str]: return self._to_host_flags(super().get_dependency_compile_args(dep)) - def get_dependency_link_args(self, dep): + def get_dependency_link_args(self, dep: 'Dependency') -> T.List[str]: return self._cook_link_args(super().get_dependency_link_args(dep)) diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index 5f5f7d4..5bcda58 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -206,9 +206,6 @@ class DmdLikeCompilerMixin: return self.get_target_arch_args() return [] - def get_std_exe_link_args(self): - return [] - def gen_import_library_args(self, implibname): return self.linker.import_library_args(implibname) @@ -561,9 +558,6 @@ class DCompiler(Compiler): return self.get_target_arch_args() return [] - def get_std_exe_link_args(self): - return [] - def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'): if callable(extra_args): extra_args = extra_args(mode) diff --git a/mesonbuild/compilers/java.py b/mesonbuild/compilers/java.py index fb4ff7c..3b4d2f5 100644 --- a/mesonbuild/compilers/java.py +++ b/mesonbuild/compilers/java.py @@ -48,12 +48,6 @@ class JavaCompiler(BasicLinkerIsCompilerMixin, Compiler): def get_coverage_args(self): return [] - def get_std_exe_link_args(self): - return [] - - def get_include_args(self, path): - return [] - def get_pic_args(self): return [] diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 840dc30..7cac7dc 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -197,10 +197,6 @@ class CLikeCompiler(Compiler): def get_werror_args(self) -> T.List[str]: return ['-Werror'] - def get_std_exe_link_args(self) -> T.List[str]: - # TODO: is this a linker property? - return [] - def get_include_args(self, path: str, is_system: bool) -> T.List[str]: if path == '': path = '.' @@ -1257,9 +1253,6 @@ class CLikeCompiler(Compiler): return [] return ['-pthread'] - def thread_link_flags(self, env: 'Environment') -> T.List[str]: - return self.linker.thread_flags(env) - def linker_to_compiler_args(self, args: T.List[str]) -> T.List[str]: return args.copy() diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index baa7272..7b4c092 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -103,9 +103,6 @@ class RustCompiler(Compiler): return parameter_list - def get_std_exe_link_args(self): - return [] - def get_output_args(self, outputname: str) -> T.List[str]: return ['-o', outputname] -- cgit v1.1 From efceec96156f5fc701a07089bf31a81e8145a67b Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 25 Sep 2020 12:24:47 -0700 Subject: Compilers/vala: Add type annotations --- mesonbuild/compilers/compilers.py | 9 +++++++ mesonbuild/compilers/vala.py | 50 ++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 24 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index fbb3eae..260a1f4 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1088,6 +1088,15 @@ class Compiler(metaclass=abc.ABCMeta): """Arguments to turn off default inclusion of standard libraries.""" return [] + def get_warn_args(self, level: str) -> T.List[str]: + return [] + + def get_werror_args(self) -> T.List[str]: + return [] + + def get_optimization_args(self, optimization_level: str) -> T.List[str]: + raise EnvironmentError('{} does not implement get_optimization_args'.format(self.id)) + def get_args_from_envvars(lang: str, for_machine: MachineChoice, diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py index f31a294..af800c2 100644 --- a/mesonbuild/compilers/vala.py +++ b/mesonbuild/compilers/vala.py @@ -18,64 +18,66 @@ import typing as T from .. import mlog from ..mesonlib import EnvironmentException, MachineChoice, version_compare -from .compilers import Compiler +from .compilers import Compiler, LibType if T.TYPE_CHECKING: from ..envconfig import MachineInfo + from ..environment import Environment class ValaCompiler(Compiler): language = 'vala' - def __init__(self, exelist, version, for_machine: MachineChoice, + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, info: 'MachineInfo'): super().__init__(exelist, version, for_machine, info, is_cross=is_cross) self.version = version self.id = 'valac' self.base_options = ['b_colorout'] - def needs_static_linker(self): + def needs_static_linker(self) -> bool: return False # Because compiles into C. - def get_optimization_args(self, optimization_level): + def get_optimization_args(self, optimization_level: str) -> T.List[str]: return [] - def get_debug_args(self, is_debug): + def get_debug_args(self, is_debug: bool) -> T.List[str]: return ['--debug'] if is_debug else [] - def get_output_args(self, target): + def get_output_args(self, target: str) -> T.List[str]: return [] # Because compiles into C. - def get_compile_only_args(self): + def get_compile_only_args(self) -> T.List[str]: return [] # Because compiles into C. - def get_pic_args(self): + def get_pic_args(self) -> T.List[str]: return [] - def get_pie_args(self): + def get_pie_args(self) -> T.List[str]: return [] - def get_pie_link_args(self): + def get_pie_link_args(self) -> T.List[str]: return [] - def get_always_args(self): + def get_always_args(self) -> T.List[str]: return ['-C'] - def get_warn_args(self, warning_level): + def get_warn_args(self, warning_level: str) -> T.List[str]: return [] - def get_no_warn_args(self): + def get_no_warn_args(self) -> T.List[str]: return ['--disable-warnings'] - def get_werror_args(self): + def get_werror_args(self) -> T.List[str]: return ['--fatal-warnings'] - def get_colorout_args(self, colortype): + def get_colorout_args(self, colortype: str) -> T.List[str]: if version_compare(self.version, '>=0.37.1'): return ['--color=' + colortype] return [] - def compute_parameters_with_absolute_paths(self, parameter_list, build_dir): + def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], + build_dir: str) -> T.List[str]: for idx, i in enumerate(parameter_list): if i[:9] == '--girdir=': parameter_list[idx] = i[:9] + os.path.normpath(os.path.join(build_dir, i[9:])) @@ -88,7 +90,7 @@ class ValaCompiler(Compiler): return parameter_list - def sanity_check(self, work_dir, environment): + def sanity_check(self, work_dir: str, environment: 'Environment') -> None: code = 'class MesonSanityCheck : Object { }' extra_flags = [] extra_flags += environment.coredata.get_external_args(self.for_machine, self.language) @@ -98,16 +100,16 @@ class ValaCompiler(Compiler): extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language) with self.cached_compile(code, environment.coredata, extra_args=extra_flags, mode='compile') as p: if p.returncode != 0: - msg = 'Vala compiler {!r} can not compile programs' \ - ''.format(self.name_string()) + msg = 'Vala compiler {!r} can not compile programs'.format(self.name_string()) raise EnvironmentException(msg) - def get_buildtype_args(self, buildtype): - if buildtype == 'debug' or buildtype == 'debugoptimized' or buildtype == 'minsize': + def get_buildtype_args(self, buildtype: str) -> T.List[str]: + if buildtype in {'debug', 'debugoptimized', 'minsize'}: return ['--debug'] return [] - def find_library(self, libname, env, extra_dirs, *args): + def find_library(self, libname: str, env: 'Environment', extra_dirs: T.List[str], + libtype: LibType = LibType.PREFER_SHARED) -> T.Optional[T.List[str]]: if extra_dirs and isinstance(extra_dirs, str): extra_dirs = [extra_dirs] # Valac always looks in the default vapi dir, so only search there if @@ -129,8 +131,8 @@ class ValaCompiler(Compiler): mlog.debug('Searched {!r} and {!r} wasn\'t found'.format(extra_dirs, libname)) return None - def thread_flags(self, env): + def thread_flags(self, env: 'Environment') -> T.List[str]: return [] - def thread_link_flags(self, env): + def thread_link_flags(self, env: 'Environment') -> T.List[str]: return [] -- cgit v1.1 From e437bdd0a9472ef9f1eb667b3b8411dd51fd66bf Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 28 Sep 2020 09:56:10 -0700 Subject: compilers/swift: Add type annotations --- mesonbuild/compilers/swift.py | 67 ++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 30 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py index 55f2761..8682e54 100644 --- a/mesonbuild/compilers/swift.py +++ b/mesonbuild/compilers/swift.py @@ -21,76 +21,83 @@ from .compilers import Compiler, swift_buildtype_args, clike_debug_args if T.TYPE_CHECKING: from ..envconfig import MachineInfo - -swift_optimization_args = {'0': [], - 'g': [], - '1': ['-O'], - '2': ['-O'], - '3': ['-O'], - 's': ['-O'], - } + from ..environment import Environment + from ..linkers import DynamicLinker + +swift_optimization_args = { + '0': [], + 'g': [], + '1': ['-O'], + '2': ['-O'], + '3': ['-O'], + 's': ['-O'], +} # type: T.Dict[str, T.List[str]] class SwiftCompiler(Compiler): LINKER_PREFIX = ['-Xlinker'] language = 'swift' - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross: bool, info: 'MachineInfo', **kwargs): - super().__init__(exelist, version, for_machine, info, is_cross=is_cross, **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', full_version: T.Optional[str] = None, + linker: T.Optional['DynamicLinker'] = None): + super().__init__(exelist, version, for_machine, info, + is_cross=is_cross, full_version=full_version, + linker=linker) self.version = version self.id = 'llvm' - def needs_static_linker(self): + def needs_static_linker(self) -> bool: return True - def get_werror_args(self): + def get_werror_args(self) -> T.List[str]: return ['--fatal-warnings'] - def get_dependency_gen_args(self, outtarget, outfile): + def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: return ['-emit-dependencies'] - def depfile_for_object(self, objfile): + def depfile_for_object(self, objfile: str) -> str: return os.path.splitext(objfile)[0] + '.' + self.get_depfile_suffix() - def get_depfile_suffix(self): + def get_depfile_suffix(self) -> str: return 'd' - def get_output_args(self, target): + def get_output_args(self, target: str) -> T.List[str]: return ['-o', target] - def get_header_import_args(self, headername): + def get_header_import_args(self, headername: str) -> T.List[str]: return ['-import-objc-header', headername] - def get_warn_args(self, level): + def get_warn_args(self, level: str) -> T.List[str]: return [] - def get_buildtype_args(self, buildtype): + def get_buildtype_args(self, buildtype: str) -> T.List[str]: return swift_buildtype_args[buildtype] - def get_std_exe_link_args(self): + def get_std_exe_link_args(self) -> T.List[str]: return ['-emit-executable'] - def get_module_args(self, modname): + def get_module_args(self, modname: str) -> T.List[str]: return ['-module-name', modname] - def get_mod_gen_args(self): + def get_mod_gen_args(self) -> T.List[str]: return ['-emit-module'] - def get_include_args(self, dirname): - return ['-I' + dirname] + def get_include_args(self, path: str, is_system: bool) -> T.List[str]: + return ['-I' + path] - def get_compile_only_args(self): + def get_compile_only_args(self) -> T.List[str]: return ['-c'] - def compute_parameters_with_absolute_paths(self, parameter_list, build_dir): + def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], + build_dir: str) -> T.List[str]: for idx, i in enumerate(parameter_list): if i[:2] == '-I' or i[:2] == '-L': parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) return parameter_list - def sanity_check(self, work_dir, environment): + def sanity_check(self, work_dir: str, environment: 'Environment') -> None: src = 'swifttest.swift' source_name = os.path.join(work_dir, src) output_name = os.path.join(work_dir, 'swifttest') @@ -113,8 +120,8 @@ class SwiftCompiler(Compiler): if subprocess.call(output_name) != 0: raise EnvironmentException('Executables created by Swift compiler %s are not runnable.' % self.name_string()) - def get_debug_args(self, is_debug): + def get_debug_args(self, is_debug: bool) -> T.List[str]: return clike_debug_args[is_debug] - def get_optimization_args(self, optimization_level): + def get_optimization_args(self, optimization_level: str) -> T.List[str]: return swift_optimization_args[optimization_level] -- cgit v1.1 From 4430269d4e4030b39724a78ec1435599d779e7b3 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 28 Sep 2020 10:15:03 -0700 Subject: compilers/rust: add type annotations --- mesonbuild/compilers/rust.py | 63 ++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 25 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index 7b4c092..02bc791 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -13,51 +13,63 @@ # limitations under the License. import subprocess, os.path +import textwrap import typing as T from ..mesonlib import EnvironmentException, MachineChoice, Popen_safe from .compilers import Compiler, rust_buildtype_args, clike_debug_args if T.TYPE_CHECKING: + from ..dependencies import ExternalProgram from ..envconfig import MachineInfo from ..environment import Environment # noqa: F401 + from ..linkers import DynamicLinker -rust_optimization_args = {'0': [], - 'g': ['-C', 'opt-level=0'], - '1': ['-C', 'opt-level=1'], - '2': ['-C', 'opt-level=2'], - '3': ['-C', 'opt-level=3'], - 's': ['-C', 'opt-level=s'], - } +rust_optimization_args = { + '0': [], + 'g': ['-C', 'opt-level=0'], + '1': ['-C', 'opt-level=1'], + '2': ['-C', 'opt-level=2'], + '3': ['-C', 'opt-level=3'], + 's': ['-C', 'opt-level=s'], +} # type: T.Dict[str, T.List[str]] class RustCompiler(Compiler): # rustc doesn't invoke the compiler itself, it doesn't need a LINKER_PREFIX language = 'rust' - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross: bool, info: 'MachineInfo', exe_wrapper=None, **kwargs): - super().__init__(exelist, version, for_machine, info, is_cross=is_cross, **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, info: 'MachineInfo', + exe_wrapper: T.Optional['ExternalProgram'] = None, + full_version: T.Optional[str] = None, + linker: T.Optional['DynamicLinker'] = None): + super().__init__(exelist, version, for_machine, info, + is_cross=is_cross, full_version=full_version, + linker=linker) self.exe_wrapper = exe_wrapper self.id = 'rustc' - def needs_static_linker(self): + def needs_static_linker(self) -> bool: return False - def sanity_check(self, work_dir, environment): + def sanity_check(self, work_dir: str, environment: 'Environment') -> None: source_name = os.path.join(work_dir, 'sanity.rs') output_name = os.path.join(work_dir, 'rusttest') with open(source_name, 'w') as ofile: - ofile.write('''fn main() { -} -''') + ofile.write(textwrap.dedent( + '''fn main() { + } + ''')) pc = subprocess.Popen(self.exelist + ['-o', output_name, source_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=work_dir) - stdo, stde = pc.communicate() - stdo = stdo.decode('utf-8', errors='replace') - stde = stde.decode('utf-8', errors='replace') + _stdo, _stde = pc.communicate() + assert isinstance(_stdo, bytes) + assert isinstance(_stde, bytes) + stdo = _stdo.decode('utf-8', errors='replace') + stde = _stde.decode('utf-8', errors='replace') if pc.returncode != 0: raise EnvironmentException('Rust compiler %s can not compile programs.\n%s\n%s' % ( self.name_string(), @@ -67,7 +79,7 @@ class RustCompiler(Compiler): if self.exe_wrapper is None: # Can't check if the binaries run so we have to assume they do return - cmdlist = self.exe_wrapper + [output_name] + cmdlist = self.exe_wrapper.get_command() + [output_name] else: cmdlist = [output_name] pe = subprocess.Popen(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) @@ -75,24 +87,25 @@ class RustCompiler(Compiler): if pe.returncode != 0: raise EnvironmentException('Executables created by Rust compiler %s are not runnable.' % self.name_string()) - def get_dependency_gen_args(self, outfile): + def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: return ['--dep-info', outfile] - def get_buildtype_args(self, buildtype): + def get_buildtype_args(self, buildtype: str) -> T.List[str]: return rust_buildtype_args[buildtype] - def get_sysroot(self): + def get_sysroot(self) -> str: cmd = self.exelist + ['--print', 'sysroot'] p, stdo, stde = Popen_safe(cmd) return stdo.split('\n')[0] - def get_debug_args(self, is_debug): + def get_debug_args(self, is_debug: bool) -> T.List[str]: return clike_debug_args[is_debug] - def get_optimization_args(self, optimization_level): + def get_optimization_args(self, optimization_level: str) -> T.List[str]: return rust_optimization_args[optimization_level] - def compute_parameters_with_absolute_paths(self, parameter_list, build_dir): + def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], + build_dir: str) -> T.List[str]: for idx, i in enumerate(parameter_list): if i[:2] == '-L': for j in ['dependency', 'crate', 'native', 'framework', 'all']: -- cgit v1.1 From 3fc37fc13e12779343ddaf830ebde7e096f77a41 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 28 Sep 2020 10:21:46 -0700 Subject: compilers/java: Add type annotations --- mesonbuild/compilers/java.py | 46 +++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 24 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/java.py b/mesonbuild/compilers/java.py index 3b4d2f5..895173e 100644 --- a/mesonbuild/compilers/java.py +++ b/mesonbuild/compilers/java.py @@ -15,6 +15,7 @@ import os.path import shutil import subprocess +import textwrap import typing as T from ..mesonlib import EnvironmentException, MachineChoice @@ -23,44 +24,40 @@ from .mixins.islinker import BasicLinkerIsCompilerMixin if T.TYPE_CHECKING: from ..envconfig import MachineInfo + from ..environment import Environment class JavaCompiler(BasicLinkerIsCompilerMixin, Compiler): language = 'java' - def __init__(self, exelist, version, for_machine: MachineChoice, - info: 'MachineInfo'): - super().__init__(exelist, version, for_machine, info) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + info: 'MachineInfo', full_version: T.Optional[str] = None): + super().__init__(exelist, version, for_machine, info, full_version=full_version) self.id = 'unknown' self.javarunner = 'java' - def get_werror_args(self): + def get_werror_args(self) -> T.List[str]: return ['-Werror'] - def get_compile_only_args(self): - return [] - - def get_output_args(self, subdir): + def get_output_args(self, subdir: str) -> T.List[str]: if subdir == '': subdir = './' return ['-d', subdir, '-s', subdir] - def get_coverage_args(self): - return [] - - def get_pic_args(self): + def get_pic_args(self) -> T.List[str]: return [] - def get_pch_use_args(self, pch_dir, header): + def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: return [] - def get_pch_name(self, header_name): + def get_pch_name(self, name: str) -> str: return '' - def get_buildtype_args(self, buildtype): + def get_buildtype_args(self, buildtype: str) -> T.List[str]: return java_buildtype_args[buildtype] - def compute_parameters_with_absolute_paths(self, parameter_list, build_dir): + def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], + build_dir: str) -> T.List[str]: for idx, i in enumerate(parameter_list): if i in ['-cp', '-classpath', '-sourcepath'] and idx + 1 < len(parameter_list): path_list = parameter_list[idx + 1].split(os.pathsep) @@ -69,17 +66,18 @@ class JavaCompiler(BasicLinkerIsCompilerMixin, Compiler): return parameter_list - def sanity_check(self, work_dir, environment): + def sanity_check(self, work_dir: str, environment: 'Environment') -> None: src = 'SanityCheck.java' obj = 'SanityCheck' source_name = os.path.join(work_dir, src) with open(source_name, 'w') as ofile: - ofile.write('''class SanityCheck { - public static void main(String[] args) { - int i; - } -} -''') + ofile.write(textwrap.dedent( + '''class SanityCheck { + public static void main(String[] args) { + int i; + } + } + ''')) pc = subprocess.Popen(self.exelist + [src], cwd=work_dir) pc.wait() if pc.returncode != 0: @@ -99,5 +97,5 @@ class JavaCompiler(BasicLinkerIsCompilerMixin, Compiler): "all about it." raise EnvironmentException(m) - def needs_static_linker(self): + def needs_static_linker(self) -> bool: return False -- cgit v1.1 From e039727e63561b0ecf75eff853579ee85f498a11 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 28 Sep 2020 10:29:00 -0700 Subject: compilers/fortran: add type annotations --- mesonbuild/compilers/compilers.py | 9 ++ mesonbuild/compilers/fortran.py | 226 ++++++++++++++++++++++---------------- 2 files changed, 143 insertions(+), 92 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 260a1f4..0a53529 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1097,6 +1097,15 @@ class Compiler(metaclass=abc.ABCMeta): def get_optimization_args(self, optimization_level: str) -> T.List[str]: raise EnvironmentError('{} does not implement get_optimization_args'.format(self.id)) + def get_module_incdir_args(self) -> T.Tuple[str, ...]: + raise EnvironmentError('{} does not implement get_module_incdir_args'.format(self.id)) + + def get_module_outdir_args(self, path: str) -> T.List[str]: + raise EnvironmentError('{} does not implement get_module_outdir_args'.format(self.id)) + + def module_name_to_filename(self, module_name: str) -> str: + raise EnvironmentError('{} does not implement module_name_to_filename'.format(self.id)) + def get_args_from_envvars(lang: str, for_machine: MachineChoice, diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index 8d17d13..628a14a 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -36,31 +36,35 @@ from mesonbuild.mesonlib import ( ) if T.TYPE_CHECKING: + from ..coredata import OptionDictType + from ..dependencies import Dependency, ExternalProgram from ..envconfig import MachineInfo + from ..environment import Environment + from ..linkers import DynamicLinker class FortranCompiler(CLikeCompiler, Compiler): language = 'fortran' - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross: bool, info: 'MachineInfo', exe_wrapper=None, **kwargs): - Compiler.__init__(self, exelist, version, for_machine, info, is_cross=is_cross, **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): + Compiler.__init__(self, exelist, version, for_machine, info, + is_cross=is_cross, full_version=full_version, linker=linker) CLikeCompiler.__init__(self, exe_wrapper) - self.id = 'unknown' - def has_function(self, funcname, prefix, env, *, extra_args=None, dependencies=None): + def has_function(self, funcname: str, prefix: str, env: 'Environment', *, + extra_args: T.Optional[T.List[str]] = None, + dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: raise MesonException('Fortran does not have "has_function" capability.\n' 'It is better to test if a Fortran capability is working like:\n\n' "meson.get_compiler('fortran').links('block; end block; end program')\n\n" 'that example is to see if the compiler has Fortran 2008 Block element.') - def sanity_check(self, work_dir: Path, environment): - """ - Check to be sure a minimal program can compile and execute - with this compiler & platform. - """ - work_dir = Path(work_dir) + def sanity_check(self, work_dir_: str, environment: 'Environment') -> None: + work_dir = Path(work_dir_) source_name = work_dir / 'sanitycheckf.f90' binary_name = work_dir / 'sanitycheckf' if binary_name.is_file(): @@ -96,28 +100,26 @@ class FortranCompiler(CLikeCompiler, Compiler): except OSError: raise EnvironmentException('Executables created by Fortran compiler %s are not runnable.' % self.name_string()) - def get_std_warn_args(self, level): - return FortranCompiler.std_warn_args - - def get_buildtype_args(self, buildtype): + def get_buildtype_args(self, buildtype: str) -> T.List[str]: return gnulike_buildtype_args[buildtype] - def get_optimization_args(self, optimization_level): + def get_optimization_args(self, optimization_level: str) -> T.List[str]: return gnu_optimization_args[optimization_level] - def get_debug_args(self, is_debug): + def get_debug_args(self, is_debug: bool) -> T.List[str]: return clike_debug_args[is_debug] - def get_preprocess_only_args(self): + def get_preprocess_only_args(self) -> T.List[str]: return ['-cpp'] + super().get_preprocess_only_args() - def get_module_incdir_args(self): + def get_module_incdir_args(self) -> T.Tuple[str, ...]: return ('-I', ) - def get_module_outdir_args(self, path): + def get_module_outdir_args(self, path: str) -> T.List[str]: return ['-module', path] - def compute_parameters_with_absolute_paths(self, parameter_list, build_dir): + def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], + build_dir: str) -> T.List[str]: for idx, i in enumerate(parameter_list): if i[:2] == '-I' or i[:2] == '-L': parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) @@ -138,11 +140,12 @@ class FortranCompiler(CLikeCompiler, Compiler): return filename - def find_library(self, libname, env, extra_dirs, libtype: LibType = LibType.PREFER_SHARED): + def find_library(self, libname: str, env: 'Environment', extra_dirs: T.List[str], + libtype: LibType = LibType.PREFER_SHARED) -> T.Optional[T.List[str]]: code = 'stop; end program' return self._find_library_impl(libname, env, extra_dirs, code, libtype) - def has_multi_arguments(self, args: T.Sequence[str], env): + def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: for arg in args[:]: # some compilers, e.g. GCC, don't warn for unsupported warning-disable # flags, so when we are testing a flag like "-Wno-forgotten-towel", also @@ -164,11 +167,15 @@ class FortranCompiler(CLikeCompiler, Compiler): class GnuFortranCompiler(GnuCompiler, FortranCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - defines=None, **kwargs): + + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + defines: T.Optional[T.Dict[str, str]] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): FortranCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, **kwargs) + is_cross, info, exe_wrapper, linker=linker, + full_version=full_version) GnuCompiler.__init__(self, defines) default_warn_args = ['-Wall'] self.warn_args = {'0': [], @@ -176,7 +183,7 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic', '-fimplicit-none']} - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = FortranCompiler.get_options(self) fortran_stds = ['legacy', 'f95', 'f2003'] if version_compare(self.version, '>=4.4.0'): @@ -192,14 +199,14 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler): }) return opts - def get_option_compile_args(self, options) -> T.List[str]: + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] if std.value != 'none': args.append('-std=' + std.value) return args - def get_dependency_gen_args(self, outtarget, outfile) -> T.List[str]: + def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: # Disabled until this is fixed: # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62162 # return ['-cpp', '-MD', '-MQ', outtarget] @@ -211,7 +218,10 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler): def language_stdlib_only_link_flags(self) -> T.List[str]: return ['-lgfortran', '-lm'] - def has_header(self, hname, prefix, env, *, extra_args=None, dependencies=None, disable_cache=False): + def has_header(self, hname: str, prefix: str, env: 'Environment', *, + extra_args: T.Optional[T.List[str]] = None, + dependencies: T.Optional[T.List['Dependency']] = None, + disable_cache: bool = False) -> T.Tuple[bool, bool]: ''' Derived from mixins/clike.py:has_header, but without C-style usage of __has_include which breaks with GCC-Fortran 10: @@ -224,22 +234,27 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler): class ElbrusFortranCompiler(GnuFortranCompiler, ElbrusCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - defines=None, **kwargs): - GnuFortranCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, defines, - **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + defines: T.Optional[T.Dict[str, str]] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): + GnuFortranCompiler.__init__(self, exelist, version, for_machine, is_cross, + info, exe_wrapper, defines=defines, + linker=linker, full_version=full_version) ElbrusCompiler.__init__(self) class G95FortranCompiler(FortranCompiler): LINKER_PREFIX = '-Wl,' - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): FortranCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, **kwargs) + is_cross, info, exe_wrapper, linker=linker, + full_version=full_version) self.id = 'g95' default_warn_args = ['-Wall'] self.warn_args = {'0': [], @@ -250,7 +265,7 @@ class G95FortranCompiler(FortranCompiler): def get_module_outdir_args(self, path: str) -> T.List[str]: return ['-fmod=' + path] - def get_no_warn_args(self): + def get_no_warn_args(self) -> T.List[str]: # FIXME: Confirm that there's no compiler option to disable all warnings return [] @@ -259,22 +274,25 @@ class SunFortranCompiler(FortranCompiler): LINKER_PREFIX = '-Wl,' - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - **kwargs): - FortranCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, **kwargs) + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): + FortranCompiler.__init__(self, exelist, version, for_machine, + is_cross, info, exe_wrapper, linker=linker, + full_version=full_version) self.id = 'sun' - def get_dependency_gen_args(self, outtarget, outfile) -> T.List[str]: + def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: return ['-fpp'] - def get_always_args(self): + def get_always_args(self) -> T.List[str]: return [] - def get_warn_args(self, level): + def get_warn_args(self, level: str) -> T.List[str]: return [] - def get_module_incdir_args(self): + def get_module_incdir_args(self) -> T.Tuple[str, ...]: return ('-M', ) def get_module_outdir_args(self, path: str) -> T.List[str]: @@ -286,12 +304,15 @@ class SunFortranCompiler(FortranCompiler): class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - **kwargs): - self.file_suffixes = ('f90', 'f', 'for', 'ftn', 'fpp') + file_suffixes = ('f90', 'f', 'for', 'ftn', 'fpp', ) + + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): FortranCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, **kwargs) + is_cross, info, exe_wrapper, linker=linker, + full_version=full_version) # FIXME: Add support for OS X and Windows in detect_fortran_compiler so # we are sent the type of compiler IntelGnuLikeCompiler.__init__(self) @@ -302,7 +323,7 @@ class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler): '2': default_warn_args + ['-warn', 'unused'], '3': ['-warn', 'all']} - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = FortranCompiler.get_options(self) fortran_stds = ['legacy', 'f95', 'f2003', 'f2008', 'f2018'] opts.update({ @@ -314,7 +335,7 @@ class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler): }) return opts - def get_option_compile_args(self, options) -> T.List[str]: + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} @@ -325,7 +346,7 @@ class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler): def get_preprocess_only_args(self) -> T.List[str]: return ['-cpp', '-EP'] - def get_always_args(self): + def get_always_args(self) -> T.List[str]: """Ifort doesn't have -pipe.""" val = super().get_always_args() val.remove('-pipe') @@ -340,14 +361,17 @@ class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler): class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler): - file_suffixes = ['f90', 'f', 'for', 'ftn', 'fpp'] + file_suffixes = ('f90', 'f', 'for', 'ftn', 'fpp', ) always_args = ['/nologo'] - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, target: str, info: 'MachineInfo', exe_wrapper=None, - **kwargs): + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, + is_cross: bool, target: str, info: 'MachineInfo', + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): FortranCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, **kwargs) + is_cross, info, exe_wrapper, linker=linker, + full_version=full_version) IntelVisualStudioLikeCompiler.__init__(self, target) default_warn_args = ['/warn:general', '/warn:truncated_source'] @@ -356,7 +380,7 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler): '2': default_warn_args + ['/warn:unused'], '3': ['/warn:all']} - def get_options(self): + def get_options(self) -> 'OptionDictType': opts = FortranCompiler.get_options(self) fortran_stds = ['legacy', 'f95', 'f2003', 'f2008', 'f2018'] opts.update({ @@ -368,7 +392,7 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler): }) return opts - def get_option_compile_args(self, options) -> T.List[str]: + def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]: args = [] std = options['std'] stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} @@ -376,16 +400,19 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler): args.append('/stand:' + stds[std.value]) return args - def get_module_outdir_args(self, path) -> T.List[str]: + def get_module_outdir_args(self, path: str) -> T.List[str]: return ['/module:' + path] class PathScaleFortranCompiler(FortranCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - **kwargs): + + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): FortranCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, **kwargs) + is_cross, info, exe_wrapper, linker=linker, + full_version=full_version) self.id = 'pathscale' default_warn_args = ['-fullwarn'] self.warn_args = {'0': [], @@ -398,11 +425,14 @@ class PathScaleFortranCompiler(FortranCompiler): class PGIFortranCompiler(PGICompiler, FortranCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - **kwargs): + + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): FortranCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, **kwargs) + is_cross, info, exe_wrapper, linker=linker, + full_version=full_version) PGICompiler.__init__(self) default_warn_args = ['-Minform=inform'] @@ -417,11 +447,14 @@ class PGIFortranCompiler(PGICompiler, FortranCompiler): class NvidiaHPC_FortranCompiler(PGICompiler, FortranCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - **kwargs): + + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): FortranCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, **kwargs) + is_cross, info, exe_wrapper, linker=linker, + full_version=full_version) PGICompiler.__init__(self) self.id = 'nvidia_hpc' @@ -433,12 +466,15 @@ class NvidiaHPC_FortranCompiler(PGICompiler, FortranCompiler): class FlangFortranCompiler(ClangCompiler, FortranCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - **kwargs): + + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): FortranCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, **kwargs) - ClangCompiler.__init__(self, []) + is_cross, info, exe_wrapper, linker=linker, + full_version=full_version) + ClangCompiler.__init__(self, {}) self.id = 'flang' default_warn_args = ['-Minform=inform'] self.warn_args = {'0': [], @@ -450,11 +486,14 @@ class FlangFortranCompiler(ClangCompiler, FortranCompiler): return ['-lflang', '-lpgmath'] class Open64FortranCompiler(FortranCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - **kwargs): + + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): FortranCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, **kwargs) + is_cross, info, exe_wrapper, linker=linker, + full_version=full_version) self.id = 'open64' default_warn_args = ['-fullwarn'] self.warn_args = {'0': [], @@ -467,17 +506,20 @@ class Open64FortranCompiler(FortranCompiler): class NAGFortranCompiler(FortranCompiler): - def __init__(self, exelist, version, for_machine: MachineChoice, - is_cross, info: 'MachineInfo', exe_wrapper=None, - **kwargs): + + def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, + info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None): FortranCompiler.__init__(self, exelist, version, for_machine, - is_cross, info, exe_wrapper, **kwargs) + is_cross, info, exe_wrapper, linker=linker, + full_version=full_version) self.id = 'nagfor' - def get_warn_args(self, level): + def get_warn_args(self, level: str) -> T.List[str]: return [] - def get_module_outdir_args(self, path) -> T.List[str]: + def get_module_outdir_args(self, path: str) -> T.List[str]: return ['-mdir', path] def openmp_flags(self) -> T.List[str]: -- cgit v1.1 From 8291e947f5c2a69ea1aad75109c692ee6f8f4540 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 28 Sep 2020 12:53:15 -0700 Subject: compilers: move get_compile_check_args() to Compiler This is groundwork to put _build_wrapper in the base Compiler, which is needed to make the D compilers truly type safe. --- mesonbuild/compilers/compilers.py | 34 ++++++++++++++++++++++++++++++---- mesonbuild/compilers/cpp.py | 15 ++++++++------- mesonbuild/compilers/mixins/clike.py | 24 +++++++++--------------- 3 files changed, 47 insertions(+), 26 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 0a53529..42bc251 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -14,6 +14,7 @@ import abc import contextlib, os.path, re, tempfile +import enum import itertools import typing as T from functools import lru_cache @@ -165,6 +166,14 @@ def is_known_suffix(fname: 'mesonlib.FileOrString') -> bool: return suffix in all_suffixes + +class CompileCheckMode(enum.Enum): + + PREPROCESS = 'preprocess' + COMPILE = 'compile' + LINK = 'link' + + cuda_buildtype_args = {'plain': [], 'debug': [], 'debugoptimized': [], @@ -716,14 +725,16 @@ class Compiler(metaclass=abc.ABCMeta): suffix = 'obj' return os.path.join(dirname, 'output.' + suffix) - def get_compiler_args_for_mode(self, mode: str) -> T.List[str]: + def get_compiler_args_for_mode(self, mode: CompileCheckMode) -> T.List[str]: # TODO: mode should really be an enum args = [] # type: T.List[str] args += self.get_always_args() - if mode == 'compile': + if mode is CompileCheckMode.COMPILE: args += self.get_compile_only_args() - if mode == 'preprocess': + elif mode is CompileCheckMode.PREPROCESS: args += self.get_preprocess_only_args() + else: + assert mode is CompileCheckMode.LINK return args def compiler_args(self, args: T.Optional[T.Iterable[str]] = None) -> CompilerArgs: @@ -761,7 +772,7 @@ class Compiler(metaclass=abc.ABCMeta): if mode != 'preprocess': output = self._get_compile_output(tmpdirname, mode) commands += self.get_output_args(output) - commands.extend(self.get_compiler_args_for_mode(mode)) + commands.extend(self.get_compiler_args_for_mode(CompileCheckMode(mode))) # extra_args must be last because it could contain '/link' to # pass args to VisualStudio's linker. In that case everything # in the command line after '/link' is given to the linker. @@ -1106,6 +1117,21 @@ class Compiler(metaclass=abc.ABCMeta): def module_name_to_filename(self, module_name: str) -> str: raise EnvironmentError('{} does not implement module_name_to_filename'.format(self.id)) + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: + """Arguments to pass the compiler and/or linker for checks. + + The default implementation turns off optimizations. mode should be + one of: + + Examples of things that go here: + - extra arguments for error checking + """ + return self.get_no_optimization_args() + + def get_no_optimization_args(self) -> T.List[str]: + """Arguments to the compiler to turn off all optimizations.""" + return [] + def get_args_from_envvars(lang: str, for_machine: MachineChoice, diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 4ef13e8..d934fa8 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -26,6 +26,7 @@ from .compilers import ( gnu_winlibs, msvc_winlibs, Compiler, + CompileCheckMode, ) from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES from .mixins.clike import CLikeCompiler @@ -90,11 +91,11 @@ class CPPCompiler(CLikeCompiler, Compiler): code = 'class breakCCompiler;int main(void) { return 0; }\n' return self._sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code) - def get_compiler_check_args(self) -> T.List[str]: + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: # -fpermissive allows non-conforming code to compile which is necessary # for many C++ checks. Particularly, the has_header_symbol check is # too strict without this and always fails. - return super().get_compiler_check_args() + ['-fpermissive'] + return super().get_compiler_check_args(mode) + ['-fpermissive'] def has_header_symbol(self, hname: str, symbol: str, prefix: str, env: 'Environment', *, @@ -605,9 +606,9 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase): return args - def get_compiler_check_args(self) -> T.List[str]: + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: # XXX: this is a hack because so much GnuLike stuff is in the base CPPCompiler class. - return CLikeCompiler.get_compiler_check_args(self) + return Compiler.get_compiler_check_args(self, mode) class CPP11AsCPP14Mixin(CompilerMixinBase): @@ -739,7 +740,7 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler): def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_compiler_check_args(self) -> T.List[str]: + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: return [] @@ -768,7 +769,7 @@ class CcrxCPPCompiler(CcrxCompiler, CPPCompiler): def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_compiler_check_args(self) -> T.List[str]: + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: return [] class C2000CPPCompiler(C2000Compiler, CPPCompiler): @@ -802,5 +803,5 @@ class C2000CPPCompiler(C2000Compiler, CPPCompiler): def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_compiler_check_args(self) -> T.List[str]: + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: return [] diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 7cac7dc..9de715c 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -37,6 +37,7 @@ from ... import mlog from ...linkers import GnuLikeDynamicLinkerMixin, SolarisDynamicLinker, CompCertDynamicLinker from ...mesonlib import LibType from .. import compilers +from ..compilers import CompileCheckMode from .visualstudio import VisualStudioLikeCompiler if T.TYPE_CHECKING: @@ -184,13 +185,6 @@ class CLikeCompiler(Compiler): def get_no_optimization_args(self) -> T.List[str]: return ['-O0'] - def get_compiler_check_args(self) -> T.List[str]: - ''' - Get arguments useful for compiler checks such as being permissive in - the code quality and not doing any optimization. - ''' - return self.get_no_optimization_args() - def get_output_args(self, target: str) -> T.List[str]: return ['-o', target] @@ -296,7 +290,7 @@ class CLikeCompiler(Compiler): source_name = os.path.join(work_dir, sname) binname = sname.rsplit('.', 1)[0] - mode = 'link' + mode = CompileCheckMode.LINK if self.is_cross: binname += '_cross' if self.exe_wrapper is None: @@ -305,7 +299,7 @@ class CLikeCompiler(Compiler): # on OSX the compiler binary is the same but you need # a ton of compiler flags to differentiate between # arm and x86_64. So just compile. - mode = 'compile' + mode = CompileCheckMode.COMPILE cargs, largs = self._get_basic_compiler_args(environment, mode) extra_flags = cargs + self.linker_to_compiler_args(largs) @@ -432,7 +426,7 @@ class CLikeCompiler(Compiler): def _get_compiler_check_args(self, env: 'Environment', extra_args: T.Union[None, arglist.CompilerArgs, T.List[str]], dependencies: T.Optional[T.List['Dependency']], - mode: str = 'compile') -> arglist.CompilerArgs: + mode: CompileCheckMode = CompileCheckMode.COMPILE) -> arglist.CompilerArgs: # TODO: the caller should handle the listfing of these arguments if extra_args is None: extra_args = [] @@ -460,7 +454,7 @@ class CLikeCompiler(Compiler): cargs += ca largs += la - cargs += self.get_compiler_check_args() + cargs += self.get_compiler_check_args(mode) # on MSVC compiler and linker flags must be separated by the "/link" argument # at this point, the '/link' argument may already be part of extra_args, otherwise, it is added here @@ -482,10 +476,10 @@ class CLikeCompiler(Compiler): def _build_wrapper(self, code: str, env: 'Environment', extra_args: T.Union[None, arglist.CompilerArgs, T.List[str]] = None, dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = 'compile', want_output: bool = False, + mode: str = CompileCheckMode.COMPILE, want_output: bool = False, disable_cache: bool = False, temp_dir: str = None) -> T.Iterator[T.Optional[compilers.CompileResult]]: - args = self._get_compiler_check_args(env, extra_args, dependencies, mode) + args = self._get_compiler_check_args(env, extra_args, dependencies, CompileCheckMode(mode)) if disable_cache or want_output: with self.compile(code, extra_args=args, mode=mode, want_output=want_output, temp_dir=env.scratch_dir) as r: yield r @@ -720,7 +714,7 @@ class CLikeCompiler(Compiler): #endif {delim}\n{define}''' args = self._get_compiler_check_args(env, extra_args, dependencies, - mode='preprocess').to_native() + mode=CompileCheckMode.PREPROCESS).to_native() func = functools.partial(self.cached_compile, code.format(**fargs), env.coredata, extra_args=args, mode='preprocess') if disable_cache: func = functools.partial(self.compile, code.format(**fargs), extra_args=args, mode='preprocess', temp_dir=env.scratch_dir) @@ -966,7 +960,7 @@ class CLikeCompiler(Compiler): } #endif ''' - args = self.get_compiler_check_args() + args = self.get_compiler_check_args(CompileCheckMode.COMPILE) n = 'symbols_have_underscore_prefix' with self._build_wrapper(code, env, extra_args=args, mode='compile', want_output=True, temp_dir=env.scratch_dir) as p: if p.returncode != 0: -- cgit v1.1 From 1c20f187e87e7bfec0c242cef88f1d06ab324b39 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 28 Sep 2020 12:57:11 -0700 Subject: compilers/intel: use get_compiler_check_args Instead of trying to override the compiles() method, which gets skipped in a bunch of cases. --- mesonbuild/compilers/mixins/clike.py | 12 ++++++------ mesonbuild/compilers/mixins/intel.py | 27 +++++++++------------------ 2 files changed, 15 insertions(+), 24 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 9de715c..c21fbd0 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -385,10 +385,10 @@ class CLikeCompiler(Compiler): return self.compiles(t.format(**fargs), env, extra_args=extra_args, dependencies=dependencies) - def _get_basic_compiler_args(self, env: 'Environment', mode: str) -> T.Tuple[T.List[str], T.List[str]]: + def _get_basic_compiler_args(self, env: 'Environment', mode: CompileCheckMode) -> T.Tuple[T.List[str], T.List[str]]: cargs = [] # type: T.List[str] largs = [] # type: T.List[str] - if mode == 'link': + if mode is CompileCheckMode.LINK: # Sometimes we need to manually select the CRT to use with MSVC. # One example is when trying to do a compiler check that involves # linking with static libraries since MSVC won't select a CRT for @@ -409,7 +409,7 @@ class CLikeCompiler(Compiler): cleaned_sys_args = self.remove_linkerlike_args(sys_args) cargs += cleaned_sys_args - if mode == 'link': + if mode is CompileCheckMode.LINK: ld_value = env.lookup_binary_entry(self.for_machine, self.language + '_ld') if ld_value is not None: largs += self.use_linker_args(ld_value[0]) @@ -433,7 +433,7 @@ class CLikeCompiler(Compiler): else: # TODO: we want to do this in the caller extra_args = mesonlib.listify(extra_args) - extra_args = mesonlib.listify([e(mode) if callable(e) else e for e in extra_args]) + extra_args = mesonlib.listify([e(mode.value) if callable(e) else e for e in extra_args]) if dependencies is None: dependencies = [] @@ -446,7 +446,7 @@ class CLikeCompiler(Compiler): for d in dependencies: # Add compile flags needed by dependencies cargs += d.get_compile_args() - if mode == 'link': + if mode is CompileCheckMode.LINK: # Add link flags needed to find dependencies largs += d.get_link_args() @@ -476,7 +476,7 @@ class CLikeCompiler(Compiler): def _build_wrapper(self, code: str, env: 'Environment', extra_args: T.Union[None, arglist.CompilerArgs, T.List[str]] = None, dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = CompileCheckMode.COMPILE, want_output: bool = False, + mode: str = 'compile', want_output: bool = False, disable_cache: bool = False, temp_dir: str = None) -> T.Iterator[T.Optional[compilers.CompileResult]]: args = self._get_compiler_check_args(env, extra_args, dependencies, CompileCheckMode(mode)) diff --git a/mesonbuild/compilers/mixins/intel.py b/mesonbuild/compilers/mixins/intel.py index 5bb55ff..1fc55fc 100644 --- a/mesonbuild/compilers/mixins/intel.py +++ b/mesonbuild/compilers/mixins/intel.py @@ -24,6 +24,7 @@ import os import typing as T from ... import mesonlib +from ..compilers import CompileCheckMode from .gnu import GnuLikeCompiler from .visualstudio import VisualStudioLikeCompiler @@ -99,13 +100,8 @@ class IntelGnuLikeCompiler(GnuLikeCompiler): else: return ['-openmp'] - def compiles(self, code: str, env: 'Environment', *, - extra_args: T.Union[None, T.List[str], 'CompilerArgs'] = None, - dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = 'compile', - disable_cache: bool = False) -> T.Tuple[bool, bool]: - extra_args = extra_args.copy() if extra_args is not None else [] - extra_args += [ + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: + extra_args = [ '-diag-error', '10006', # ignoring unknown option '-diag-error', '10148', # Option not supported '-diag-error', '10155', # ignoring argument required @@ -113,7 +109,7 @@ class IntelGnuLikeCompiler(GnuLikeCompiler): '-diag-error', '10157', # Ignoring argument of the wrong type '-diag-error', '10158', # Argument must be separate. Can be hit by trying an option like -foo-bar=foo when -foo=bar is a valid option but -foo-bar isn't ] - return super().compiles(code, env, extra_args=extra_args, dependencies=dependencies, mode=mode, disable_cache=disable_cache) + return super().get_compiler_check_args(mode) + extra_args def get_profile_generate_args(self) -> T.List[str]: return ['-prof-gen=threadsafe'] @@ -157,15 +153,10 @@ class IntelVisualStudioLikeCompiler(VisualStudioLikeCompiler): super().__init__(target) self.id = 'intel-cl' - def compiles(self, code: str, env: 'Environment', *, - extra_args: T.Union[None, T.List[str], 'CompilerArgs'] = None, - dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = 'compile', - disable_cache: bool = False) -> T.Tuple[bool, bool]: - # This covers a case that .get('foo', []) doesn't, that extra_args is - if mode != 'link': - extra_args = extra_args.copy() if extra_args is not None else [] - extra_args.extend([ + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: + args = super().get_compiler_check_args(mode) + if mode is not CompileCheckMode.LINK: + args.extend([ '/Qdiag-error:10006', # ignoring unknown option '/Qdiag-error:10148', # Option not supported '/Qdiag-error:10155', # ignoring argument required @@ -173,7 +164,7 @@ class IntelVisualStudioLikeCompiler(VisualStudioLikeCompiler): '/Qdiag-error:10157', # Ignoring argument of the wrong type '/Qdiag-error:10158', # Argument must be separate. Can be hit by trying an option like -foo-bar=foo when -foo=bar is a valid option but -foo-bar isn't ]) - return super().compiles(code, env, extra_args=extra_args, dependencies=dependencies, mode=mode, disable_cache=disable_cache) + return args def get_toolset_version(self) -> T.Optional[str]: # Avoid circular dependencies.... -- cgit v1.1 From cd59ce98dc88318c6784cfddfe3fadda2495041b Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 28 Sep 2020 15:37:48 -0700 Subject: compilers: clang: use get_compiler_check_args --- mesonbuild/compilers/mixins/clang.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py index 8c85944..acdb352 100644 --- a/mesonbuild/compilers/mixins/clang.py +++ b/mesonbuild/compilers/mixins/clang.py @@ -20,6 +20,7 @@ import typing as T from ... import mesonlib from ...linkers import AppleDynamicLinker +from ..compilers import CompileCheckMode from .gnu import GnuLikeCompiler if T.TYPE_CHECKING: @@ -76,11 +77,13 @@ class ClangCompiler(GnuLikeCompiler): # so it might change semantics at any time. return ['-include-pch', os.path.join(pch_dir, self.get_pch_name(header))] - def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: - myargs = ['-Werror=unknown-warning-option', '-Werror=unused-command-line-argument'] - if mesonlib.version_compare(self.version, '>=3.6.0'): - myargs.append('-Werror=ignored-optimization-argument') - return super().has_multi_arguments(myargs + args, env) + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: + myargs = [] # type: T.List[str] + if mode is CompileCheckMode.COMPILE: + myargs.extend(['-Werror=unknown-warning-option', '-Werror=unused-command-line-argument']) + if mesonlib.version_compare(self.version, '>=3.6.0'): + myargs.append('-Werror=ignored-optimization-argument') + return super().get_compiler_check_args(mode) + myargs def has_function(self, funcname: str, prefix: str, env: 'Environment', *, extra_args: T.Optional[T.List[str]] = None, -- cgit v1.1 From 738e343860b25f545ebf98fec93ba8ee1fc3cabc Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 28 Sep 2020 13:56:30 -0700 Subject: compilers: move _build_wrapper out of clike into Compiler This abstraction is really useful, and most compilers could use it (including D). It also will allow the Gnu mixins to work properly without the CLikeCompiler in their mro. --- mesonbuild/compilers/compilers.py | 88 ++++++++++++++++++++++++++++++------ mesonbuild/compilers/mixins/clike.py | 42 ++--------------- 2 files changed, 79 insertions(+), 51 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 42bc251..b1bb269 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -642,20 +642,6 @@ class Compiler(metaclass=abc.ABCMeta): dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: raise EnvironmentException('Language %s does not support header symbol checks.' % self.get_display_language()) - def compiles(self, code: str, env: 'Environment', *, - extra_args: T.Union[None, T.List[str], CompilerArgs] = None, - dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = 'compile', - disable_cache: bool = False) -> T.Tuple[bool, bool]: - raise EnvironmentException('Language %s does not support compile checks.' % self.get_display_language()) - - def links(self, code: str, env: 'Environment', *, - extra_args: T.Union[None, T.List[str], CompilerArgs] = None, - dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = 'compile', - disable_cache: bool = False) -> T.Tuple[bool, bool]: - raise EnvironmentException('Language %s does not support link checks.' % self.get_display_language()) - def run(self, code: str, env: 'Environment', *, extra_args: T.Optional[T.List[str]] = None, dependencies: T.Optional[T.List['Dependency']] = None) -> RunResult: @@ -1132,6 +1118,80 @@ class Compiler(metaclass=abc.ABCMeta): """Arguments to the compiler to turn off all optimizations.""" return [] + def build_wrapper_args(self, env: 'Environment', + extra_args: T.Union[None, CompilerArgs, T.List[str]], + dependencies: T.Optional[T.List['Dependency']], + mode: CompileCheckMode = CompileCheckMode.COMPILE) -> CompilerArgs: + """Arguments to pass the build_wrapper helper. + + This generally needs to be set on a per-language baises. It provides + a hook for languages to handle dependencies and extra args. The base + implementation handles the most common cases, namely adding the + check_arguments, unwrapping dependencies, and appending extra args. + """ + if callable(extra_args): + extra_args = extra_args(mode) + if extra_args is None: + extra_args = [] + if dependencies is None: + dependencies = [] + + # Collect compiler arguments + args = self.compiler_args(self.get_compiler_check_args(mode)) + for d in dependencies: + # Add compile flags needed by dependencies + args += d.get_compile_args() + if mode is CompileCheckMode.LINK: + # Add link flags needed to find dependencies + args += d.get_link_args() + + if mode is CompileCheckMode.COMPILE: + # Add DFLAGS from the env + args += env.coredata.get_external_args(self.for_machine, self.language) + elif mode is CompileCheckMode.LINK: + # Add LDFLAGS from the env + args += env.coredata.get_external_link_args(self.for_machine, self.language) + # extra_args must override all other arguments, so we add them last + args += extra_args + return args + + @contextlib.contextmanager + def _build_wrapper(self, code: str, env: 'Environment', + extra_args: T.Union[None, CompilerArgs, T.List[str]] = None, + dependencies: T.Optional[T.List['Dependency']] = None, + mode: str = 'compile', want_output: bool = False, + disable_cache: bool = False, + temp_dir: str = None) -> T.Iterator[T.Optional[CompileResult]]: + """Helper for getting a cacched value when possible. + + This method isn't meant to be called externally, it's mean to be + wrapped by other methods like compiles() and links(). + """ + args = self.build_wrapper_args(env, extra_args, dependencies, CompileCheckMode(mode)) + if disable_cache or want_output: + with self.compile(code, extra_args=args, mode=mode, want_output=want_output, temp_dir=env.scratch_dir) as r: + yield r + else: + with self.cached_compile(code, env.coredata, extra_args=args, mode=mode, temp_dir=env.scratch_dir) as r: + yield r + + def compiles(self, code: str, env: 'Environment', *, + extra_args: T.Union[None, T.List[str], CompilerArgs] = None, + dependencies: T.Optional[T.List['Dependency']] = None, + mode: str = 'compile', + disable_cache: bool = False) -> T.Tuple[bool, bool]: + with self._build_wrapper(code, env, extra_args, dependencies, mode, disable_cache=disable_cache) as p: + return p.returncode == 0, p.cached + + + def links(self, code: str, env: 'Environment', *, + extra_args: T.Union[None, T.List[str], CompilerArgs] = None, + dependencies: T.Optional[T.List['Dependency']] = None, + mode: str = 'compile', + disable_cache: bool = False) -> T.Tuple[bool, bool]: + return self.compiles(code, env, extra_args=extra_args, + dependencies=dependencies, mode='link', disable_cache=disable_cache) + def get_args_from_envvars(lang: str, for_machine: MachineChoice, diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index c21fbd0..8008836 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -20,7 +20,6 @@ of this is to have mixin's, which are classes that are designed *not* to be standalone, they only work through inheritance. """ -import contextlib import collections import functools import glob @@ -423,10 +422,10 @@ class CLikeCompiler(Compiler): cargs += self.get_compiler_args_for_mode(mode) return cargs, largs - def _get_compiler_check_args(self, env: 'Environment', - extra_args: T.Union[None, arglist.CompilerArgs, T.List[str]], - dependencies: T.Optional[T.List['Dependency']], - mode: CompileCheckMode = CompileCheckMode.COMPILE) -> arglist.CompilerArgs: + def build_wrapper_args(self, env: 'Environment', + extra_args: T.Union[None, arglist.CompilerArgs, T.List[str]], + dependencies: T.Optional[T.List['Dependency']], + mode: CompileCheckMode = CompileCheckMode.COMPILE) -> arglist.CompilerArgs: # TODO: the caller should handle the listfing of these arguments if extra_args is None: extra_args = [] @@ -464,37 +463,6 @@ class CLikeCompiler(Compiler): args = cargs + extra_args + largs return args - def compiles(self, code: str, env: 'Environment', *, - extra_args: T.Union[None, T.List[str], arglist.CompilerArgs] = None, - dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = 'compile', - disable_cache: bool = False) -> T.Tuple[bool, bool]: - with self._build_wrapper(code, env, extra_args, dependencies, mode, disable_cache=disable_cache) as p: - return p.returncode == 0, p.cached - - @contextlib.contextmanager - def _build_wrapper(self, code: str, env: 'Environment', - extra_args: T.Union[None, arglist.CompilerArgs, T.List[str]] = None, - dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = 'compile', want_output: bool = False, - disable_cache: bool = False, - temp_dir: str = None) -> T.Iterator[T.Optional[compilers.CompileResult]]: - args = self._get_compiler_check_args(env, extra_args, dependencies, CompileCheckMode(mode)) - if disable_cache or want_output: - with self.compile(code, extra_args=args, mode=mode, want_output=want_output, temp_dir=env.scratch_dir) as r: - yield r - else: - with self.cached_compile(code, env.coredata, extra_args=args, mode=mode, temp_dir=env.scratch_dir) as r: - yield r - - def links(self, code: str, env: 'Environment', *, - extra_args: T.Union[None, T.List[str], arglist.CompilerArgs] = None, - dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = 'compile', - disable_cache: bool = False) -> T.Tuple[bool, bool]: - return self.compiles(code, env, extra_args=extra_args, - dependencies=dependencies, mode='link', disable_cache=disable_cache) - def run(self, code: str, env: 'Environment', *, extra_args: T.Optional[T.List[str]] = None, dependencies: T.Optional[T.List['Dependency']] = None) -> compilers.RunResult: @@ -713,7 +681,7 @@ class CLikeCompiler(Compiler): # define {define} #endif {delim}\n{define}''' - args = self._get_compiler_check_args(env, extra_args, dependencies, + args = self.build_wrapper_args(env, extra_args, dependencies, mode=CompileCheckMode.PREPROCESS).to_native() func = functools.partial(self.cached_compile, code.format(**fargs), env.coredata, extra_args=args, mode='preprocess') if disable_cache: -- cgit v1.1 From 6eb981e0c03b2ff0f6af65688be9eeb0a9358226 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 28 Sep 2020 13:59:44 -0700 Subject: compilers/gnu: Don't pretend to inherit CLike We don't need it anymore, and it would be problematic for the D compilers. --- mesonbuild/compilers/mixins/gnu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py index 9c60fcb..41afadd 100644 --- a/mesonbuild/compilers/mixins/gnu.py +++ b/mesonbuild/compilers/mixins/gnu.py @@ -27,7 +27,7 @@ from ... import mlog if T.TYPE_CHECKING: from ...environment import Environment - from .clike import CLikeCompiler as Compiler + from ..compilers import Compiler else: # This is a bit clever, for mypy we pretend that these mixins descend from # Compiler, so we get all of the methods and attributes defined for us, but -- cgit v1.1 From 6a9761a2c0c099d20885f748a373b214c2cdb8d4 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 28 Sep 2020 14:50:51 -0700 Subject: compilers/d: add type annotations --- mesonbuild/compilers/compilers.py | 5 + mesonbuild/compilers/d.py | 266 ++++++++++++++++++++------------------ 2 files changed, 143 insertions(+), 128 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index b1bb269..67552ee 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1192,6 +1192,11 @@ class Compiler(metaclass=abc.ABCMeta): return self.compiles(code, env, extra_args=extra_args, dependencies=dependencies, mode='link', disable_cache=disable_cache) + def get_feature_args(self, kwargs: T.Dict[str, T.Any], build_to_src: str) -> T.List[str]: + """Used by D for extra language features.""" + # TODO: using a TypeDict here would improve this + raise EnvironmentError('{} does not implement get_feature_args'.format(self.id)) + def get_args_from_envvars(lang: str, for_machine: MachineChoice, diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index 5bcda58..630291a 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -30,8 +30,13 @@ from .compilers import ( from .mixins.gnu import GnuCompiler if T.TYPE_CHECKING: - from ..dependencies import ExternalProgram + from .compilers import Compiler as CompilerMixinBase + from ..dependencies import Dependency, ExternalProgram from ..envconfig import MachineInfo + from ..environment import Environment + from ..linkers import DynamicLinker +else: + CompilerMixinBase = object d_feature_args = {'gcc': {'unittest': '-funittest', 'debug': '-fdebug', @@ -48,7 +53,7 @@ d_feature_args = {'gcc': {'unittest': '-funittest', 'version': '-version', 'import_dir': '-J' } - } + } # type: T.Dict[str, T.Dict[str, str]] ldc_optimization_args = {'0': [], 'g': [], @@ -56,7 +61,7 @@ ldc_optimization_args = {'0': [], '2': ['-O2'], '3': ['-O3'], 's': ['-Os'], - } + } # type: T.Dict[str, T.List[str]] dmd_optimization_args = {'0': [], 'g': [], @@ -64,23 +69,35 @@ dmd_optimization_args = {'0': [], '2': ['-O'], '3': ['-O'], 's': ['-O'], - } + } # type: T.Dict[str, T.List[str]] -class DmdLikeCompilerMixin: +class DmdLikeCompilerMixin(CompilerMixinBase): + + """Mixin class for DMD and LDC. + + LDC has a number of DMD like arguments, and this class allows for code + sharing between them as makes sense. + """ + + if T.TYPE_CHECKING: + mscrt_args = {} # type: T.Dict[str, T.List[str]] + + def _get_target_arch_args(self) -> T.List[str]: ... LINKER_PREFIX = '-L=' - def get_output_args(self, target): - return ['-of=' + target] + def get_output_args(self, outputname: str) -> T.List[str]: + return ['-of=' + outputname] - def get_linker_output_args(self, target): - return ['-of=' + target] + def get_linker_output_args(self, outputname: str) -> T.List[str]: + return ['-of=' + outputname] - def get_include_args(self, path, is_system): + def get_include_args(self, path: str, is_system: bool) -> T.List[str]: return ['-I=' + path] - def compute_parameters_with_absolute_paths(self, parameter_list, build_dir): + def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], + build_dir: str) -> T.List[str]: for idx, i in enumerate(parameter_list): if i[:3] == '-I=': parameter_list[idx] = i[:3] + os.path.normpath(os.path.join(build_dir, i[3:])) @@ -93,33 +110,34 @@ class DmdLikeCompilerMixin: return parameter_list - def get_warn_args(self, level): + def get_warn_args(self, level: str) -> T.List[str]: return ['-wi'] - def get_werror_args(self): + def get_werror_args(self) -> T.List[str]: return ['-w'] - def get_coverage_args(self): + def get_coverage_args(self) -> T.List[str]: return ['-cov'] - def get_coverage_link_args(self): + def get_coverage_link_args(self) -> T.List[str]: return [] - def get_preprocess_only_args(self): + def get_preprocess_only_args(self) -> T.List[str]: return ['-E'] - def get_compile_only_args(self): + def get_compile_only_args(self) -> T.List[str]: return ['-c'] - def get_depfile_suffix(self): + def get_depfile_suffix(self) -> str: return 'deps' - def get_pic_args(self): + def get_pic_args(self) -> T.List[str]: if self.info.is_windows(): return [] return ['-fPIC'] - def get_feature_args(self, kwargs, build_to_src): + def get_feature_args(self, kwargs: T.Dict[str, T.Any], build_to_src: str) -> T.List[str]: + # TODO: using a TypeDict here would improve this res = [] if 'unittest' in kwargs: unittest = kwargs.pop('unittest') @@ -201,15 +219,17 @@ class DmdLikeCompilerMixin: return res - def get_buildtype_linker_args(self, buildtype): + def get_buildtype_linker_args(self, buildtype: str) -> T.List[str]: if buildtype != 'plain': - return self.get_target_arch_args() + return self._get_target_arch_args() return [] - def gen_import_library_args(self, implibname): + def gen_import_library_args(self, implibname: str) -> T.List[str]: return self.linker.import_library_args(implibname) - def build_rpath_args(self, env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath): + def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, + rpath_paths: str, build_rpath: str, + install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: if self.info.is_windows(): return ([], set()) @@ -233,7 +253,7 @@ class DmdLikeCompilerMixin: return super().build_rpath_args( env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath) - def translate_args_to_nongnu(self, args): + def _translate_args_to_nongnu(self, args: T.List[str]) -> T.List[str]: dcargs = [] # Translate common arguments to flags the LDC/DMD compilers # can understand. @@ -241,11 +261,11 @@ class DmdLikeCompilerMixin: # and are therefore out of the user's control. for arg in args: # Translate OS specific arguments first. - osargs = [] + osargs = [] # type: T.List[str] if self.info.is_windows(): osargs = self.translate_arg_to_windows(arg) elif self.info.is_darwin(): - osargs = self.translate_arg_to_osx(arg) + osargs = self._translate_arg_to_osx(arg) if osargs: dcargs.extend(osargs) continue @@ -324,7 +344,7 @@ class DmdLikeCompilerMixin: return dcargs @classmethod - def translate_arg_to_windows(cls, arg): + def translate_arg_to_windows(cls, arg: str) -> T.List[str]: args = [] if arg.startswith('-Wl,'): # Translate linker arguments here. @@ -350,20 +370,20 @@ class DmdLikeCompilerMixin: return args @classmethod - def translate_arg_to_osx(cls, arg): + def _translate_arg_to_osx(cls, arg: str) -> T.List[str]: args = [] if arg.startswith('-install_name'): args.append('-L=' + arg) return args - def get_debug_args(self, is_debug): + def get_debug_args(self, is_debug: bool) -> T.List[str]: ddebug_args = [] if is_debug: ddebug_args = [d_feature_args[self.id]['debug']] return clike_debug_args[is_debug] + ddebug_args - def get_crt_args(self, crt_val, buildtype): + def _get_crt_args(self, crt_val: str, buildtype: str) -> T.List[str]: if not self.info.is_windows(): return [] @@ -386,26 +406,32 @@ class DmdLikeCompilerMixin: assert(buildtype == 'custom') raise EnvironmentException('Requested C runtime based on buildtype, but buildtype is "custom".') - def get_soname_args(self, *args, **kwargs) -> T.List[str]: + def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str, + suffix: str, soversion: str, + darwin_versions: T.Tuple[str, str], + is_shared_module: bool) -> T.List[str]: + sargs = super().get_soname_args(env, prefix, shlib_name, suffix, + soversion, darwin_versions, is_shared_module) + # LDC and DMD actually do use a linker, but they proxy all of that with # their own arguments if self.linker.id.startswith('ld.'): soargs = [] - for arg in super().get_soname_args(*args, **kwargs): + for arg in sargs: a, b = arg.split(',', maxsplit=1) soargs.append(a) soargs.append(self.LINKER_PREFIX + b) return soargs elif self.linker.id.startswith('ld64'): soargs = [] - for arg in super().get_soname_args(*args, **kwargs): + for arg in sargs: if not arg.startswith(self.LINKER_PREFIX): soargs.append(self.LINKER_PREFIX + arg) else: soargs.append(arg) return soargs else: - return super().get_soname_args(*args, **kwargs) + return sargs def get_allow_undefined_link_args(self) -> T.List[str]: args = self.linker.get_allow_undefined_args() @@ -418,9 +444,11 @@ class DmdLikeCompilerMixin: args = [a.replace('-L=', '-Xcc=-Wl,') for a in args] return args + class DCompilerArgs(CompilerArgs): prepend_prefixes = ('-I', '-L') - dedup2_prefixes = ('-I') + dedup2_prefixes = ('-I', ) + class DCompiler(Compiler): mscrt_args = { @@ -434,19 +462,22 @@ class DCompiler(Compiler): language = 'd' def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, - info: 'MachineInfo', arch: str, exe_wrapper: T.Optional['ExternalProgram'] = None, - **kwargs): - super().__init__(exelist, version, for_machine, info, **kwargs) - self.id = 'unknown' + info: 'MachineInfo', arch: str, *, + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None, + is_cross: bool = False): + super().__init__(exelist, version, for_machine, info, linker=linker, + full_version=full_version, is_cross=is_cross) self.arch = arch self.exe_wrapper = exe_wrapper - def sanity_check(self, work_dir, environment): + def sanity_check(self, work_dir: str, environment: 'Environment') -> None: source_name = os.path.join(work_dir, 'sanity.d') output_name = os.path.join(work_dir, 'dtest') with open(source_name, 'w') as ofile: ofile.write('''void main() { }''') - pc = subprocess.Popen(self.exelist + self.get_output_args(output_name) + self.get_target_arch_args() + [source_name], cwd=work_dir) + pc = subprocess.Popen(self.exelist + self.get_output_args(output_name) + self._get_target_arch_args() + [source_name], cwd=work_dir) pc.wait() if pc.returncode != 0: raise EnvironmentException('D compiler %s can not compile programs.' % self.name_string()) @@ -460,18 +491,19 @@ class DCompiler(Compiler): if subprocess.call(cmdlist) != 0: raise EnvironmentException('Executables created by D compiler %s are not runnable.' % self.name_string()) - def needs_static_linker(self): + def needs_static_linker(self) -> bool: return True - def get_depfile_suffix(self): + def get_depfile_suffix(self) -> str: return 'deps' - def get_pic_args(self): + def get_pic_args(self) -> T.List[str]: if self.info.is_windows(): return [] return ['-fPIC'] - def get_feature_args(self, kwargs, build_to_src): + def get_feature_args(self, kwargs: T.Dict[str, T.Any], build_to_src: str) -> T.List[str]: + # TODO: using a TypeDict here would improve this res = [] if 'unittest' in kwargs: unittest = kwargs.pop('unittest') @@ -553,54 +585,18 @@ class DCompiler(Compiler): return res - def get_buildtype_linker_args(self, buildtype): + def get_buildtype_linker_args(self, buildtype: str) -> T.List[str]: if buildtype != 'plain': - return self.get_target_arch_args() + return self._get_target_arch_args() return [] - def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'): - if callable(extra_args): - extra_args = extra_args(mode) - if extra_args is None: - extra_args = [] - elif isinstance(extra_args, str): - extra_args = [extra_args] - if dependencies is None: - dependencies = [] - elif not isinstance(dependencies, list): - dependencies = [dependencies] - # Collect compiler arguments - args = self.compiler_args() - for d in dependencies: - # Add compile flags needed by dependencies - args += d.get_compile_args() - if mode == 'link': - # Add link flags needed to find dependencies - args += d.get_link_args() - - if mode == 'compile': - # Add DFLAGS from the env - args += env.coredata.get_external_args(self.for_machine, self.language) - elif mode == 'link': - # Add LDFLAGS from the env - args += env.coredata.get_external_link_args(self.for_machine, self.language) - # extra_args must override all other arguments, so we add them last - args += extra_args - return args - def compiler_args(self, args: T.Optional[T.Iterable[str]] = None) -> DCompilerArgs: return DCompilerArgs(self, args) - def compiles(self, code, env, *, extra_args=None, dependencies=None, mode='compile'): - args = self._get_compiler_check_args(env, extra_args, dependencies, mode) - - with self.cached_compile(code, env.coredata, extra_args=args, mode=mode) as p: - return p.returncode == 0, p.cached - - def has_multi_arguments(self, args, env): + def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: return self.compiles('int i;\n', env, extra_args=args) - def get_target_arch_args(self): + def _get_target_arch_args(self) -> T.List[str]: # LDC2 on Windows targets to current OS architecture, but # it should follow the target specified by the MSVC toolchain. if self.info.is_windows(): @@ -609,15 +605,12 @@ class DCompiler(Compiler): return ['-m32'] return [] - def get_crt_compile_args(self, crt_val, buildtype): + def get_crt_compile_args(self, crt_val: str, buildtype: str) -> T.List[str]: return [] - def get_crt_link_args(self, crt_val, buildtype): + def get_crt_link_args(self, crt_val: str, buildtype: str) -> T.List[str]: return [] - def thread_link_flags(self, env): - return self.linker.thread_flags(env) - class GnuDCompiler(GnuCompiler, DCompiler): @@ -625,9 +618,14 @@ class GnuDCompiler(GnuCompiler, DCompiler): LINKER_PREFIX = GnuCompiler.LINKER_PREFIX def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, - info: 'MachineInfo', arch: str, *, exe_wrapper: T.Optional['ExternalProgram'] = None, - **kwargs): - DCompiler.__init__(self, exelist, version, for_machine, info, arch, exe_wrapper=exe_wrapper, **kwargs) + info: 'MachineInfo', arch: str, *, + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None, + is_cross: bool = False): + DCompiler.__init__(self, exelist, version, for_machine, info, arch, + exe_wrapper=exe_wrapper, linker=linker, + full_version=full_version, is_cross=is_cross) GnuCompiler.__init__(self, {}) self.id = 'gcc' default_warn_args = ['-Wall', '-Wdeprecated'] @@ -643,23 +641,24 @@ class GnuDCompiler(GnuCompiler, DCompiler): # (and some backported versions) self._has_deps_support = version_compare(self.version, '>=7.1') - def get_colorout_args(self, colortype): + def get_colorout_args(self, colortype: str) -> T.List[str]: if self._has_color_support: super().get_colorout_args(colortype) return [] - def get_dependency_gen_args(self, outtarget, outfile): + def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: if self._has_deps_support: return super().get_dependency_gen_args(outtarget, outfile) return [] - def get_warn_args(self, level): + def get_warn_args(self, level: str) -> T.List[str]: return self.warn_args[level] - def get_buildtype_args(self, buildtype): + def get_buildtype_args(self, buildtype: str) -> T.List[str]: return d_gdc_buildtype_args[buildtype] - def compute_parameters_with_absolute_paths(self, parameter_list, build_dir): + def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], + build_dir: str) -> T.List[str]: for idx, i in enumerate(parameter_list): if i[:2] == '-I' or i[:2] == '-L': parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) @@ -675,46 +674,51 @@ class GnuDCompiler(GnuCompiler, DCompiler): return args return args + ['-shared-libphobos'] - def get_disable_assert_args(self): + def get_disable_assert_args(self) -> T.List[str]: return ['-frelease'] class LLVMDCompiler(DmdLikeCompilerMixin, DCompiler): def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, - info: 'MachineInfo', arch: str, **kwargs): - DCompiler.__init__(self, exelist, version, for_machine, info, arch, **kwargs) + info: 'MachineInfo', arch: str, *, + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None, + is_cross: bool = False): + DCompiler.__init__(self, exelist, version, for_machine, info, arch, + exe_wrapper=exe_wrapper, linker=linker, + full_version=full_version, is_cross=is_cross) self.id = 'llvm' self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug'] - def get_colorout_args(self, colortype): + def get_colorout_args(self, colortype: str) -> T.List[str]: if colortype == 'always': return ['-enable-color'] return [] - def get_warn_args(self, level): - if level == '2' or level == '3': + def get_warn_args(self, level: str) -> T.List[str]: + if level in {'2', '3'}: return ['-wi', '-dw'] elif level == '1': return ['-wi'] - else: - return [] + return [] - def get_buildtype_args(self, buildtype): + def get_buildtype_args(self, buildtype: str) -> T.List[str]: if buildtype != 'plain': - return self.get_target_arch_args() + d_ldc_buildtype_args[buildtype] + return self._get_target_arch_args() + d_ldc_buildtype_args[buildtype] return d_ldc_buildtype_args[buildtype] - def get_pic_args(self): + def get_pic_args(self) -> T.List[str]: return ['-relocation-model=pic'] - def get_crt_link_args(self, crt_val, buildtype): - return self.get_crt_args(crt_val, buildtype) + def get_crt_link_args(self, crt_val: str, buildtype: str) -> T.List[str]: + return self._get_crt_args(crt_val, buildtype) - def unix_args_to_native(self, args): - return self.translate_args_to_nongnu(args) + def unix_args_to_native(self, args: T.List[str]) -> T.List[str]: + return self._translate_args_to_nongnu(args) - def get_optimization_args(self, optimization_level): + def get_optimization_args(self, optimization_level: str) -> T.List[str]: return ldc_optimization_args[optimization_level] @classmethod @@ -734,22 +738,28 @@ class LLVMDCompiler(DmdLikeCompilerMixin, DCompiler): class DmdDCompiler(DmdLikeCompilerMixin, DCompiler): def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, - info: 'MachineInfo', arch: str, **kwargs): - DCompiler.__init__(self, exelist, version, for_machine, info, arch, **kwargs) + info: 'MachineInfo', arch: str, *, + exe_wrapper: T.Optional['ExternalProgram'] = None, + linker: T.Optional['DynamicLinker'] = None, + full_version: T.Optional[str] = None, + is_cross: bool = False): + DCompiler.__init__(self, exelist, version, for_machine, info, arch, + exe_wrapper=exe_wrapper, linker=linker, + full_version=full_version, is_cross=is_cross) self.id = 'dmd' self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug'] - def get_colorout_args(self, colortype): + def get_colorout_args(self, colortype: str) -> T.List[str]: if colortype == 'always': return ['-color=on'] return [] - def get_buildtype_args(self, buildtype): + def get_buildtype_args(self, buildtype: str) -> T.List[str]: if buildtype != 'plain': - return self.get_target_arch_args() + d_dmd_buildtype_args[buildtype] + return self._get_target_arch_args() + d_dmd_buildtype_args[buildtype] return d_dmd_buildtype_args[buildtype] - def get_std_exe_link_args(self): + def get_std_exe_link_args(self) -> T.List[str]: if self.info.is_windows(): # DMD links against D runtime only when main symbol is found, # so these needs to be inserted when linking static D libraries. @@ -760,7 +770,7 @@ class DmdDCompiler(DmdLikeCompilerMixin, DCompiler): return ['phobos.lib'] return [] - def get_std_shared_lib_link_args(self): + def get_std_shared_lib_link_args(self) -> T.List[str]: libname = 'libphobos2.so' if self.info.is_windows(): if self.arch == 'x86_64': @@ -771,7 +781,7 @@ class DmdDCompiler(DmdLikeCompilerMixin, DCompiler): libname = 'phobos.lib' return ['-shared', '-defaultlib=' + libname] - def get_target_arch_args(self): + def _get_target_arch_args(self) -> T.List[str]: # DMD32 and DMD64 on 64-bit Windows defaults to 32-bit (OMF). # Force the target to 64-bit in order to stay consistent # across the different platforms. @@ -783,13 +793,13 @@ class DmdDCompiler(DmdLikeCompilerMixin, DCompiler): return ['-m32'] return [] - def get_crt_compile_args(self, crt_val, buildtype): - return self.get_crt_args(crt_val, buildtype) + def get_crt_compile_args(self, crt_val: str, buildtype: str) -> T.List[str]: + return self._get_crt_args(crt_val, buildtype) - def unix_args_to_native(self, args): - return self.translate_args_to_nongnu(args) + def unix_args_to_native(self, args: T.List[str]) -> T.List[str]: + return self._translate_args_to_nongnu(args) - def get_optimization_args(self, optimization_level): + def get_optimization_args(self, optimization_level: str) -> T.List[str]: return dmd_optimization_args[optimization_level] def can_linker_accept_rsp(self) -> bool: -- cgit v1.1 From 577a2de7e87128b75e8e7e0c5d1a35986d43fd14 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 28 Sep 2020 15:29:25 -0700 Subject: compilers/fortran: fix has_multi_*_arguments The implementation of the link variant was what should have been the compiler variant, and there was no valid compiler variant, which meant it was getting C code. --- mesonbuild/compilers/fortran.py | 23 ++++------------------- mesonbuild/compilers/mixins/clike.py | 12 ++++++++---- 2 files changed, 12 insertions(+), 23 deletions(-) (limited to 'mesonbuild/compilers') diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index 628a14a..6cbd2ce 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -29,7 +29,6 @@ from .mixins.intel import IntelGnuLikeCompiler, IntelVisualStudioLikeCompiler from .mixins.clang import ClangCompiler from .mixins.elbrus import ElbrusCompiler from .mixins.pgi import PGICompiler -from .. import mlog from mesonbuild.mesonlib import ( version_compare, EnvironmentException, MesonException, MachineChoice, LibType @@ -145,25 +144,11 @@ class FortranCompiler(CLikeCompiler, Compiler): code = 'stop; end program' return self._find_library_impl(libname, env, extra_dirs, code, libtype) + def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: + return self._has_multi_arguments(args, env, 'stop; end program') + def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: - for arg in args[:]: - # some compilers, e.g. GCC, don't warn for unsupported warning-disable - # flags, so when we are testing a flag like "-Wno-forgotten-towel", also - # check the equivalent enable flag too "-Wforgotten-towel" - # GCC does error for "-fno-foobar" - if arg.startswith('-Wno-'): - args.append('-W' + arg[5:]) - if arg.startswith('-Wl,'): - mlog.warning('{} looks like a linker argument, ' - 'but has_argument and other similar methods only ' - 'support checking compiler arguments. Using them ' - 'to check linker arguments are never supported, ' - 'and results are likely to be wrong regardless of ' - 'the compiler you are using. has_link_argument or ' - 'other similar method can be used instead.' - .format(arg)) - code = 'stop; end program' - return self.has_arguments(args, env, code, mode='compile') + return self._has_multi_link_arguments(args, env, 'stop; end program') class GnuFortranCompiler(GnuCompiler, FortranCompiler): diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 8008836..c7e76d7 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -1222,7 +1222,7 @@ class CLikeCompiler(Compiler): mode: str) -> T.Tuple[bool, bool]: return self.compiles(code, env, extra_args=args, mode=mode) - def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: + def _has_multi_arguments(self, args: T.List[str], env: 'Environment', code: str) -> T.Tuple[bool, bool]: new_args = [] # type: T.List[str] for arg in args: # some compilers, e.g. GCC, don't warn for unsupported warning-disable @@ -1240,18 +1240,22 @@ class CLikeCompiler(Compiler): 'other similar method can be used instead.' .format(arg)) new_args.append(arg) - code = 'extern int i;\nint i;\n' return self.has_arguments(new_args, env, code, mode='compile') - def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: + def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: + return self._has_multi_arguments(args, env, 'extern int i;\nint i;\n') + + def _has_multi_link_arguments(self, args: T.List[str], env: 'Environment', code: str) -> T.Tuple[bool, bool]: # First time we check for link flags we need to first check if we have # --fatal-warnings, otherwise some linker checks could give some # false positive. args = self.linker.fatal_warnings() + args args = self.linker_to_compiler_args(args) - code = 'int main(void) { return 0; }\n' return self.has_arguments(args, env, code, mode='link') + def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: + return self._has_multi_link_arguments(args, env, 'int main(void) { return 0; }\n') + @staticmethod def _concatenate_string_literals(s: str) -> str: pattern = re.compile(r'(?P
.*([^\\]")|^")(?P([^\\"]|\\.)*)"\s+"(?P([^\\"]|\\.)*)(?P".*)')
-- 
cgit v1.1


From 135f5d5838263e2afd344d916710071037ffcadc Mon Sep 17 00:00:00 2001
From: Dylan Baker 
Date: Tue, 29 Sep 2020 09:21:08 -0700
Subject: compilers: make get_optimization_args abstract

---
 mesonbuild/compilers/compilers.py | 3 ++-
 mesonbuild/compilers/java.py      | 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

(limited to 'mesonbuild/compilers')

diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 67552ee..4b48e31 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -1091,8 +1091,9 @@ class Compiler(metaclass=abc.ABCMeta):
     def get_werror_args(self) -> T.List[str]:
         return []
 
+    @abc.abstractmethod
     def get_optimization_args(self, optimization_level: str) -> T.List[str]:
-        raise EnvironmentError('{} does not implement get_optimization_args'.format(self.id))
+        pass
 
     def get_module_incdir_args(self) -> T.Tuple[str, ...]:
         raise EnvironmentError('{} does not implement get_module_incdir_args'.format(self.id))
diff --git a/mesonbuild/compilers/java.py b/mesonbuild/compilers/java.py
index 895173e..77e1a9b 100644
--- a/mesonbuild/compilers/java.py
+++ b/mesonbuild/compilers/java.py
@@ -99,3 +99,6 @@ class JavaCompiler(BasicLinkerIsCompilerMixin, Compiler):
 
     def needs_static_linker(self) -> bool:
         return False
+
+    def get_optimization_args(self, optimization_level: str) -> T.List[str]:
+        return []
-- 
cgit v1.1


From ff51e1c5aa08e34324129ab0f7bdbf8a28a4f95f Mon Sep 17 00:00:00 2001
From: Dylan Baker 
Date: Tue, 29 Sep 2020 13:53:04 -0700
Subject: compilers/clike: Store exe_wrapper as ExternalProgram

Which is what other languages do.
---
 mesonbuild/compilers/fortran.py      | 2 +-
 mesonbuild/compilers/mixins/clike.py | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'mesonbuild/compilers')

diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 6cbd2ce..1714fab 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -88,7 +88,7 @@ class FortranCompiler(CLikeCompiler, Compiler):
             if self.exe_wrapper is None:
                 # Can't check if the binaries run so we have to assume they do
                 return
-            cmdlist = self.exe_wrapper + [str(binary_name)]
+            cmdlist = self.exe_wrapper.get_command() + [str(binary_name)]
         else:
             cmdlist = [str(binary_name)]
         # %% Run the test executable
diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py
index c7e76d7..dca09ea 100644
--- a/mesonbuild/compilers/mixins/clike.py
+++ b/mesonbuild/compilers/mixins/clike.py
@@ -140,7 +140,7 @@ class CLikeCompiler(Compiler):
         if not exe_wrapper or not exe_wrapper.found() or not exe_wrapper.get_command():
             self.exe_wrapper = None
         else:
-            self.exe_wrapper = exe_wrapper.get_command()
+            self.exe_wrapper = exe_wrapper
 
     def compiler_args(self, args: T.Optional[T.Iterable[str]] = None) -> CLikeCompilerArgs:
         # This is correct, mypy just doesn't understand co-operative inheritance
@@ -326,7 +326,7 @@ class CLikeCompiler(Compiler):
             if self.exe_wrapper is None:
                 # Can't check if the binaries run so we have to assume they do
                 return
-            cmdlist = self.exe_wrapper + [binary_name]
+            cmdlist = self.exe_wrapper.get_command() + [binary_name]
         else:
             cmdlist = [binary_name]
         mlog.debug('Running test binary command: ' + ' '.join(cmdlist))
@@ -476,7 +476,7 @@ class CLikeCompiler(Compiler):
                     p.returncode))
                 return compilers.RunResult(False)
             if need_exe_wrapper:
-                cmdlist = self.exe_wrapper + [p.output_name]
+                cmdlist = self.exe_wrapper.get_command() + [p.output_name]
             else:
                 cmdlist = [p.output_name]
             try:
-- 
cgit v1.1


From b309f4904b7c84491e8c16aa23ef6a983f0e72a8 Mon Sep 17 00:00:00 2001
From: Dylan Baker 
Date: Tue, 29 Sep 2020 14:07:57 -0700
Subject: compilers/fortran: make ifort on windows signature match ICL's

---
 mesonbuild/compilers/fortran.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'mesonbuild/compilers')

diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 1714fab..9f2f106 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -350,7 +350,7 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler):
     always_args = ['/nologo']
 
     def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice,
-                 is_cross: bool, target: str, info: 'MachineInfo',
+                 is_cross: bool, info: 'MachineInfo', target: str,
                  exe_wrapper: T.Optional['ExternalProgram'] = None,
                  linker: T.Optional['DynamicLinker'] = None,
                  full_version: T.Optional[str] = None):
-- 
cgit v1.1


From f9316fbb46a8fcc7f69db7164e8ac0b30a0212d2 Mon Sep 17 00:00:00 2001
From: Dylan Baker 
Date: Wed, 30 Sep 2020 14:48:37 -0700
Subject: compilers/icl: Fix pch usage

---
 mesonbuild/compilers/mixins/intel.py | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'mesonbuild/compilers')

diff --git a/mesonbuild/compilers/mixins/intel.py b/mesonbuild/compilers/mixins/intel.py
index 1fc55fc..442e8c7 100644
--- a/mesonbuild/compilers/mixins/intel.py
+++ b/mesonbuild/compilers/mixins/intel.py
@@ -186,3 +186,6 @@ class IntelVisualStudioLikeCompiler(VisualStudioLikeCompiler):
 
     def get_optimization_args(self, optimization_level: str) -> T.List[str]:
         return self.OPTIM_ARGS[optimization_level]
+
+    def get_pch_base_name(self, header: str) -> str:
+        return os.path.basename(header)
\ No newline at end of file
-- 
cgit v1.1


From 2fe400c350a49930c3fbe86602efa9e0950bb1cb Mon Sep 17 00:00:00 2001
From: Dylan Baker 
Date: Thu, 1 Oct 2020 13:58:23 -0700
Subject: compilers/icl fix IntelClCPP argument checking

Unlike MSVC and ClangCl it needs to call into it's own compiler check
args
---
 mesonbuild/compilers/cpp.py | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'mesonbuild/compilers')

diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index d934fa8..0c63b30 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -707,6 +707,10 @@ class IntelClCPPCompiler(VisualStudioLikeCPPCompilerMixin, IntelVisualStudioLike
         cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest']
         return self._get_options_impl(super().get_options(), cpp_stds)
 
+    def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
+        # XXX: this is a hack because so much GnuLike stuff is in the base CPPCompiler class.
+        return IntelVisualStudioLikeCompiler.get_compiler_check_args(self, mode)
+
 
 class ArmCPPCompiler(ArmCompiler, CPPCompiler):
     def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool,
-- 
cgit v1.1