compilers/mixins/visualstudio: Add type annotations

pull/5661/head
Dylan Baker 5 years ago
parent 214ab455d3
commit d68969f169
  1. 225
      mesonbuild/compilers/mixins/visualstudio.py

@ -23,58 +23,68 @@ import typing
from ... import mesonlib
from ... import mlog
msvc_buildtype_args = {'plain': [],
'debug': ["/ZI", "/Ob0", "/Od", "/RTC1"],
'debugoptimized': ["/Zi", "/Ob1"],
'release': ["/Ob2", "/Gw"],
'minsize': ["/Zi", "/Gw"],
'custom': [],
}
msvc_buildtype_linker_args = {'plain': [],
'debug': [],
'debugoptimized': [],
# The otherwise implicit REF and ICF linker
# optimisations are disabled by /DEBUG.
# REF implies ICF.
'release': ['/OPT:REF'],
'minsize': ['/INCREMENTAL:NO', '/OPT:REF'],
'custom': [],
}
msvc_optimization_args = {'0': [],
'g': ['/O0'],
'1': ['/O1'],
'2': ['/O2'],
'3': ['/O2'],
's': ['/O1'], # Implies /Os.
}
msvc_debug_args = {False: [],
True: []} # Fixme!
vs32_instruction_set_args = {'mmx': ['/arch:SSE'], # There does not seem to be a flag just for MMX
'sse': ['/arch:SSE'],
'sse2': ['/arch:SSE2'],
'sse3': ['/arch:AVX'], # VS leaped from SSE2 directly to AVX.
'sse41': ['/arch:AVX'],
'sse42': ['/arch:AVX'],
'avx': ['/arch:AVX'],
'avx2': ['/arch:AVX2'],
'neon': None,
}
if typing.TYPE_CHECKING:
from ...environment import Environment
vs32_instruction_set_args = {
'mmx': ['/arch:SSE'], # There does not seem to be a flag just for MMX
'sse': ['/arch:SSE'],
'sse2': ['/arch:SSE2'],
'sse3': ['/arch:AVX'], # VS leaped from SSE2 directly to AVX.
'sse41': ['/arch:AVX'],
'sse42': ['/arch:AVX'],
'avx': ['/arch:AVX'],
'avx2': ['/arch:AVX2'],
'neon': None,
} # typing.Dicst[str, typing.Optional[typing.List[str]]]
# The 64 bit compiler defaults to /arch:avx.
vs64_instruction_set_args = {'mmx': ['/arch:AVX'],
'sse': ['/arch:AVX'],
'sse2': ['/arch:AVX'],
'sse3': ['/arch:AVX'],
'ssse3': ['/arch:AVX'],
'sse41': ['/arch:AVX'],
'sse42': ['/arch:AVX'],
'avx': ['/arch:AVX'],
'avx2': ['/arch:AVX2'],
'neon': None,
}
vs64_instruction_set_args = {
'mmx': ['/arch:AVX'],
'sse': ['/arch:AVX'],
'sse2': ['/arch:AVX'],
'sse3': ['/arch:AVX'],
'ssse3': ['/arch:AVX'],
'sse41': ['/arch:AVX'],
'sse42': ['/arch:AVX'],
'avx': ['/arch:AVX'],
'avx2': ['/arch:AVX2'],
'neon': None,
} # typing.Dicst[str, typing.Optional[typing.List[str]]]
msvc_buildtype_args = {
'plain': [],
'debug': ["/ZI", "/Ob0", "/Od", "/RTC1"],
'debugoptimized': ["/Zi", "/Ob1"],
'release': ["/Ob2", "/Gw"],
'minsize': ["/Zi", "/Gw"],
'custom': [],
} # type: typing.Dict[str, typing.List[str]]
msvc_buildtype_linker_args = {
'plain': [],
'debug': [],
'debugoptimized': [],
# The otherwise implicit REF and ICF linker optimisations are disabled by
# /DEBUG. REF implies ICF.
'release': ['/OPT:REF'],
'minsize': ['/INCREMENTAL:NO', '/OPT:REF'],
'custom': [],
} # type: typing.Dict[str, typing.List[str]]
msvc_optimization_args = {
'0': [],
'g': ['/O0'],
'1': ['/O1'],
'2': ['/O2'],
'3': ['/O2'],
's': ['/O1'], # Implies /Os.
} # type: typing.Dict[str, typing.List[str]]
msvc_debug_args = {
False: [],
True: [] # Fixme!
} # type: typing.Dict[bool, typing.List[str]]
class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
@ -94,20 +104,23 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
ignore_libs = ('m', 'c', 'pthread', 'dl', 'rt', 'execinfo')
internal_libs = ()
crt_args = {'none': [],
'md': ['/MD'],
'mdd': ['/MDd'],
'mt': ['/MT'],
'mtd': ['/MTd'],
}
crt_args = {
'none': [],
'md': ['/MD'],
'mdd': ['/MDd'],
'mt': ['/MT'],
'mtd': ['/MTd'],
} # type: typing.Dict[str, typing.List[str]]
# /showIncludes is needed for build dependency tracking in Ninja
# See: https://ninja-build.org/manual.html#_deps
always_args = ['/nologo', '/showIncludes']
warn_args = {'0': ['/W1'],
'1': ['/W2'],
'2': ['/W3'],
'3': ['/W4'],
}
warn_args = {
'0': ['/W1'],
'1': ['/W2'],
'2': ['/W3'],
'3': ['/W4'],
} # type: typing.Dict[str, typing.List[str]]
def __init__(self, target: str):
self.base_options = ['b_pch', 'b_ndebug', 'b_vscrt'] # FIXME add lto, pgo and the like
@ -122,10 +135,10 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
self.machine = target
# Override CCompiler.get_always_args
def get_always_args(self):
def get_always_args(self) -> typing.List[str]:
return self.always_args
def get_linker_debug_crt_args(self):
def get_linker_debug_crt_args(self) -> typing.List[str]:
"""
Arguments needed to select a debug crt for the linker
@ -136,55 +149,55 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
"""
return ['/MDd']
def get_buildtype_args(self, buildtype):
def get_buildtype_args(self, buildtype: str) -> typing.List[str]:
args = msvc_buildtype_args[buildtype]
if self.id == 'msvc' and mesonlib.version_compare(self.version, '<18.0'):
args = [arg for arg in args if arg != '/Gw']
return args
def get_buildtype_linker_args(self, buildtype):
def get_buildtype_linker_args(self, buildtype: str) -> typing.List[str]:
return msvc_buildtype_linker_args[buildtype]
def get_pch_suffix(self):
def get_pch_suffix(self) -> str:
return 'pch'
def get_pch_name(self, header):
def get_pch_name(self, header: str) -> str:
chopped = os.path.basename(header).split('.')[:-1]
chopped.append(self.get_pch_suffix())
pchname = '.'.join(chopped)
return pchname
def get_pch_use_args(self, pch_dir, header):
def get_pch_use_args(self, pch_dir: str, header: str) -> typing.List[str]:
base = os.path.basename(header)
if self.id == 'clang-cl':
base = header
pchname = self.get_pch_name(header)
return ['/FI' + base, '/Yu' + base, '/Fp' + os.path.join(pch_dir, pchname)]
def get_preprocess_only_args(self):
def get_preprocess_only_args(self) -> typing.List[str]:
return ['/EP']
def get_compile_only_args(self):
def get_compile_only_args(self) -> typing.List[str]:
return ['/c']
def get_no_optimization_args(self):
def get_no_optimization_args(self) -> typing.List[str]:
return ['/Od']
def get_output_args(self, target):
def get_output_args(self, target: str) -> typing.List[str]:
if target.endswith('.exe'):
return ['/Fe' + target]
return ['/Fo' + target]
def get_optimization_args(self, optimization_level):
def get_optimization_args(self, optimization_level: str) -> typing.List[str]:
return msvc_optimization_args[optimization_level]
def get_debug_args(self, is_debug):
def get_debug_args(self, is_debug: bool) -> typing.List[str]:
return msvc_debug_args[is_debug]
def get_dependency_gen_args(self, outtarget, outfile):
def get_dependency_gen_args(self, outtarget: str, outfile: str) -> typing.List[str]:
return []
def get_linker_exelist(self):
def get_linker_exelist(self) -> typing.List[str]:
# FIXME, should have same path as compiler.
# FIXME, should be controllable via cross-file.
if self.id == 'clang-cl':
@ -192,19 +205,19 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
else:
return ['link']
def get_linker_always_args(self):
def get_linker_always_args(self) -> typing.List[str]:
return ['/nologo']
def get_linker_output_args(self, outputname):
def get_linker_output_args(self, outputname: str) -> typing.List[str]:
return ['/MACHINE:' + self.machine, '/OUT:' + outputname]
def get_linker_search_args(self, dirname):
def get_linker_search_args(self, dirname: str) -> typing.List[str]:
return ['/LIBPATH:' + dirname]
def linker_to_compiler_args(self, args):
def linker_to_compiler_args(self, args: typing.List[str]) -> typing.List[str]:
return ['/link'] + args
def get_gui_app_args(self, value):
def get_gui_app_args(self, value: bool) -> typing.List[str]:
# the default is for the linker to guess the subsystem based on presence
# of main or WinMain symbols, so always be explicit
if value:
@ -212,45 +225,45 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
else:
return ['/SUBSYSTEM:CONSOLE']
def get_pic_args(self):
def get_pic_args(self) -> typing.List[str]:
return [] # PIC is handled by the loader on Windows
def gen_export_dynamic_link_args(self, env):
def gen_export_dynamic_link_args(self, env: 'Environment') -> typing.List[str]:
return [] # Not applicable with MSVC
def get_std_shared_lib_link_args(self):
def get_std_shared_lib_link_args(self) -> typing.List[str]:
return ['/DLL']
def gen_vs_module_defs_args(self, defsfile):
def gen_vs_module_defs_args(self, defsfile: str) -> typing.List[str]:
if not isinstance(defsfile, str):
raise RuntimeError('Module definitions file should be str')
# With MSVC, DLLs only export symbols that are explicitly exported,
# so if a module defs file is specified, we use that to export symbols
return ['/DEF:' + defsfile]
def gen_pch_args(self, header, source, pchname):
def gen_pch_args(self, header: str, source: str, pchname: str) -> typing.Tuple[str, typing.List[str]]:
objname = os.path.splitext(pchname)[0] + '.obj'
return objname, ['/Yc' + header, '/Fp' + pchname, '/Fo' + objname]
def gen_import_library_args(self, implibname):
def gen_import_library_args(self, implibname: str) -> typing.List[str]:
"The name of the outputted import library"
return ['/IMPLIB:' + implibname]
def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
def build_rpath_args(self, build_dir: str, from_dir: str, rpath_paths: str, build_rpath: str, install_rpath: str) -> typing.List[str]:
return []
def openmp_flags(self):
def openmp_flags(self) -> typing.List[str]:
return ['/openmp']
# FIXME, no idea what these should be.
def thread_flags(self, env):
def thread_flags(self, env: 'Environment') -> typing.List[str]:
return []
def thread_link_flags(self, env):
def thread_link_flags(self, env: 'Environment') -> typing.List[str]:
return []
@classmethod
def unix_args_to_native(cls, args):
def unix_args_to_native(cls, args: typing.List[str]) -> typing.List[str]:
result = []
for i in args:
# -mms-bitfields is specific to MinGW-GCC
@ -274,16 +287,16 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
result.append(i)
return result
def get_werror_args(self):
def get_werror_args(self) -> typing.List[str]:
return ['/WX']
def get_include_args(self, path, is_system):
def get_include_args(self, path: str, is_system: bool) -> typing.List[str]:
if path == '':
path = '.'
# msvc does not have a concept of system header dirs.
return ['-I' + path]
def compute_parameters_with_absolute_paths(self, parameter_list, build_dir):
def compute_parameters_with_absolute_paths(self, parameter_list: typing.List[str], build_dir: str) -> typing.List[str]:
for idx, i in enumerate(parameter_list):
if i[:2] == '-I' or i[:2] == '/I':
parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:]))
@ -295,7 +308,7 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
# Visual Studio is special. It ignores some arguments it does not
# understand and you can't tell it to error out on those.
# http://stackoverflow.com/questions/15259720/how-can-i-make-the-microsoft-c-compiler-treat-unknown-flags-as-errors-rather-t
def has_arguments(self, args, env, code, mode):
def has_arguments(self, args: typing.List[str], env: 'Environment', code, mode: str) -> typing.Tuple[bool, bool]:
warning_text = '4044' if mode == 'link' else '9002'
if self.id == 'clang-cl' and mode != 'link':
args = args + ['-Werror=unknown-argument']
@ -304,7 +317,7 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
return False, p.cached
return not(warning_text in p.stde or warning_text in p.stdo), p.cached
def get_compile_debugfile_args(self, rel_obj, pch=False):
def get_compile_debugfile_args(self, rel_obj: str, pch: bool = False) -> typing.List[str]:
pdbarr = rel_obj.split('.')[:-1]
pdbarr += ['pdb']
args = ['/Fd' + '.'.join(pdbarr)]
@ -318,17 +331,17 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
args = ['/FS'] + args
return args
def get_link_debugfile_args(self, targetfile):
def get_link_debugfile_args(self, targetfile: str) -> typing.List[str]:
pdbarr = targetfile.split('.')[:-1]
pdbarr += ['pdb']
return ['/DEBUG', '/PDB:' + '.'.join(pdbarr)]
def get_link_whole_for(self, args):
def get_link_whole_for(self, args: typing.List[str]) -> typing.List[str]:
# Only since VS2015
args = mesonlib.listify(args)
return ['/WHOLEARCHIVE:' + x for x in args]
def get_instruction_set_args(self, instruction_set):
def get_instruction_set_args(self, instruction_set: str) -> typing.Optional[typing.List[str]]:
if self.is_64:
return vs64_instruction_set_args.get(instruction_set, None)
if self.id == 'msvc' and self.version.split('.')[0] == '16' and instruction_set == 'avx':
@ -362,7 +375,7 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
mlog.warning('Could not find toolset for version {!r}'.format(self.version))
return None
def get_toolset_version(self):
def get_toolset_version(self) -> typing.Optional[str]:
if self.id == 'clang-cl':
# I have no idea
return '14.1'
@ -374,12 +387,12 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
return None
return self._calculate_toolset_version(version)
def get_default_include_dirs(self):
def get_default_include_dirs(self) -> typing.List[str]:
if 'INCLUDE' not in os.environ:
return []
return os.environ['INCLUDE'].split(os.pathsep)
def get_crt_compile_args(self, crt_val, buildtype):
def get_crt_compile_args(self, crt_val: str, buildtype: str) -> typing.List[str]:
if crt_val in self.crt_args:
return self.crt_args[crt_val]
assert(crt_val == 'from_buildtype')
@ -398,14 +411,14 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
assert(buildtype == 'custom')
raise mesonlib.EnvironmentException('Requested C runtime based on buildtype, but buildtype is "custom".')
def has_func_attribute(self, name, env):
def has_func_attribute(self, name: str, env: 'Environment') -> typing.Tuple[bool, bool]:
# MSVC doesn't have __attribute__ like Clang and GCC do, so just return
# false without compiling anything
return name in ['dllimport', 'dllexport'], False
def get_argument_syntax(self):
def get_argument_syntax(self) -> str:
return 'msvc'
def get_allow_undefined_link_args(self):
def get_allow_undefined_link_args(self) -> typing.List[str]:
# link.exe
return ['/FORCE:UNRESOLVED']

Loading…
Cancel
Save