|
|
|
@ -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'] |
|
|
|
|