|
|
|
@ -12,6 +12,7 @@ |
|
|
|
|
# See the License for the specific language governing permissions and |
|
|
|
|
# limitations under the License. |
|
|
|
|
|
|
|
|
|
import copy |
|
|
|
|
import functools |
|
|
|
|
import os.path |
|
|
|
|
import typing |
|
|
|
@ -26,7 +27,8 @@ from .compilers import ( |
|
|
|
|
ClangCompiler, |
|
|
|
|
GnuCompiler, |
|
|
|
|
ElbrusCompiler, |
|
|
|
|
IntelCompiler, |
|
|
|
|
IntelGnuLikeCompiler, |
|
|
|
|
IntelVisualStudioLikeCompiler, |
|
|
|
|
PGICompiler, |
|
|
|
|
ArmCompiler, |
|
|
|
|
ArmclangCompiler, |
|
|
|
@ -104,7 +106,7 @@ class CPPCompiler(CLikeCompiler, Compiler): |
|
|
|
|
# 2. even if it did have an env object, that might contain another more |
|
|
|
|
# recent -std= argument, which might lead to a cascaded failure. |
|
|
|
|
CPP_TEST = 'int i = static_cast<int>(0);' |
|
|
|
|
with self.compile(code=CPP_TEST, extra_args=[cpp_std_value], mode='compile') as p: |
|
|
|
|
with self.compile(CPP_TEST, extra_args=[cpp_std_value], mode='compile') as p: |
|
|
|
|
if p.returncode == 0: |
|
|
|
|
mlog.debug('Compiler accepts {}:'.format(cpp_std_value), 'YES') |
|
|
|
|
return True |
|
|
|
@ -310,10 +312,10 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler): |
|
|
|
|
dependencies=dependencies) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class IntelCPPCompiler(IntelCompiler, CPPCompiler): |
|
|
|
|
class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): |
|
|
|
|
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrap, **kwargs): |
|
|
|
|
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs) |
|
|
|
|
IntelCompiler.__init__(self, compiler_type) |
|
|
|
|
IntelGnuLikeCompiler.__init__(self, compiler_type) |
|
|
|
|
self.lang_header = 'c++-header' |
|
|
|
|
default_warn_args = ['-Wall', '-w3', '-diag-disable:remark', |
|
|
|
|
'-Wpch-messages', '-Wnon-virtual-dtor'] |
|
|
|
@ -371,6 +373,16 @@ class VisualStudioLikeCPPCompilerMixin: |
|
|
|
|
|
|
|
|
|
"""Mixin for C++ specific method overrides in MSVC-like compilers.""" |
|
|
|
|
|
|
|
|
|
VC_VERSION_MAP = { |
|
|
|
|
'none': (True, None), |
|
|
|
|
'vc++11': (True, 11), |
|
|
|
|
'vc++14': (True, 14), |
|
|
|
|
'vc++17': (True, 17), |
|
|
|
|
'c++11': (False, 11), |
|
|
|
|
'c++14': (False, 14), |
|
|
|
|
'c++17': (False, 17), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
def get_option_link_args(self, options): |
|
|
|
|
return options['cpp_winlibs'].value[:] |
|
|
|
|
|
|
|
|
@ -397,34 +409,12 @@ class VisualStudioLikeCPPCompilerMixin: |
|
|
|
|
elif eh.value != 'none': |
|
|
|
|
args.append('/EH' + eh.value) |
|
|
|
|
|
|
|
|
|
vc_version_map = { |
|
|
|
|
'none': (True, None), |
|
|
|
|
'vc++11': (True, 11), |
|
|
|
|
'vc++14': (True, 14), |
|
|
|
|
'vc++17': (True, 17), |
|
|
|
|
'c++11': (False, 11), |
|
|
|
|
'c++14': (False, 14), |
|
|
|
|
'c++17': (False, 17)} |
|
|
|
|
|
|
|
|
|
permissive, ver = vc_version_map[options['cpp_std'].value] |
|
|
|
|
|
|
|
|
|
if ver is None: |
|
|
|
|
pass |
|
|
|
|
elif ver == 11: |
|
|
|
|
# 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) |
|
|
|
|
# if one is using anything before that point, one cannot set the standard. |
|
|
|
|
if self.id == 'clang-cl' or version_compare(self.version, '>=19.00.24210'): |
|
|
|
|
mlog.warning('MSVC does not support C++11; ' |
|
|
|
|
'attempting best effort; setting the standard to C++14') |
|
|
|
|
args.append('/std:c++14') |
|
|
|
|
else: |
|
|
|
|
mlog.warning('This version of MSVC does not support cpp_std arguments') |
|
|
|
|
else: |
|
|
|
|
permissive, ver = self.VC_VERSION_MAP[options['cpp_std'].value] |
|
|
|
|
|
|
|
|
|
if ver is not None: |
|
|
|
|
args.append('/std:c++{}'.format(ver)) |
|
|
|
|
|
|
|
|
|
if not permissive and version_compare(self.version, '>=19.11'): |
|
|
|
|
if not permissive: |
|
|
|
|
args.append('/permissive-') |
|
|
|
|
|
|
|
|
|
return args |
|
|
|
@ -434,7 +424,33 @@ class VisualStudioLikeCPPCompilerMixin: |
|
|
|
|
return CLikeCompiler.get_compiler_check_args(self) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VisualStudioCPPCompiler(VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompiler, CPPCompiler): |
|
|
|
|
class CPP11AsCPP14Mixin: |
|
|
|
|
|
|
|
|
|
"""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): |
|
|
|
|
# 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) |
|
|
|
|
# if one is using anything before that point, one cannot set the standard. |
|
|
|
|
if options['cpp_std'].value in {'vc++11', 'c++11'}: |
|
|
|
|
mlog.warning(self.id, 'does not support C++11;', |
|
|
|
|
'attempting best effort; setting the standard to C++14') |
|
|
|
|
# Don't mutate anything we're going to change, we need to use |
|
|
|
|
# deepcopy since we're messing with members, and we can't simply |
|
|
|
|
# copy the members because the option proxy doesn't support it. |
|
|
|
|
options = copy.deepcopy(options) |
|
|
|
|
if options['cpp_std'].value == 'vc++11': |
|
|
|
|
options['cpp_std'].value = 'vc++14' |
|
|
|
|
else: |
|
|
|
|
options['cpp_std'].value = 'c++14' |
|
|
|
|
return super().get_option_compile_args(options) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompiler, CPPCompiler): |
|
|
|
|
def __init__(self, exelist, version, is_cross, exe_wrap, target): |
|
|
|
|
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) |
|
|
|
|
VisualStudioLikeCompiler.__init__(self, target) |
|
|
|
@ -445,14 +461,29 @@ class VisualStudioCPPCompiler(VisualStudioLikeCPPCompilerMixin, VisualStudioLike |
|
|
|
|
cpp_stds = ['none', 'c++11', 'vc++11'] |
|
|
|
|
# Visual Studio 2015 and later |
|
|
|
|
if version_compare(self.version, '>=19'): |
|
|
|
|
cpp_stds.extend(['c++14', 'vc++14', 'c++latest', 'vc++latest']) |
|
|
|
|
cpp_stds.extend(['c++14', 'c++latest', 'vc++latest']) |
|
|
|
|
# Visual Studio 2017 and later |
|
|
|
|
if version_compare(self.version, '>=19.11'): |
|
|
|
|
cpp_stds.extend(['c++17', 'vc++17']) |
|
|
|
|
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): |
|
|
|
|
if options['cpp_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) |
|
|
|
|
options['cpp_std'].value = 'none' |
|
|
|
|
|
|
|
|
|
args = super().get_option_compile_args(options) |
|
|
|
|
|
|
|
|
|
if version_compare(self.version, '<19.11'): |
|
|
|
|
try: |
|
|
|
|
i = args.index('/permissive-') |
|
|
|
|
except ValueError: |
|
|
|
|
return args |
|
|
|
|
del args[i] |
|
|
|
|
return args |
|
|
|
|
|
|
|
|
|
class ClangClCPPCompiler(VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompiler, CPPCompiler): |
|
|
|
|
class ClangClCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompiler, CPPCompiler): |
|
|
|
|
def __init__(self, exelist, version, is_cross, exe_wrap, target): |
|
|
|
|
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) |
|
|
|
|
VisualStudioLikeCompiler.__init__(self, target) |
|
|
|
@ -463,6 +494,18 @@ class ClangClCPPCompiler(VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompi |
|
|
|
|
return self._get_options_impl(super().get_options(), cpp_stds) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class IntelClCPPCompiler(VisualStudioLikeCPPCompilerMixin, IntelVisualStudioLikeCompiler, CPPCompiler): |
|
|
|
|
|
|
|
|
|
def __init__(self, exelist, version, is_cross, exe_wrap, target): |
|
|
|
|
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) |
|
|
|
|
IntelVisualStudioLikeCompiler.__init__(self, target) |
|
|
|
|
|
|
|
|
|
def get_options(self): |
|
|
|
|
# This has only been tested with verison 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, compiler_type, is_cross, exe_wrap=None, **kwargs): |
|
|
|
|
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs) |
|
|
|
|