aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2019-05-14 00:24:48 +0300
committerGitHub <noreply@github.com>2019-05-14 00:24:48 +0300
commit7b8ef78bc0002d0327626c6218b793f87c2a5eb8 (patch)
tree44ffa3b3c11e8e154615d65e79f9c79f5334648d /mesonbuild
parentb849f6f935787055834ed3745faf7203c22c982b (diff)
parent523c7beefc170395fd3f49cf4609aadb8e986ad1 (diff)
downloadmeson-7b8ef78bc0002d0327626c6218b793f87c2a5eb8.zip
meson-7b8ef78bc0002d0327626c6218b793f87c2a5eb8.tar.gz
meson-7b8ef78bc0002d0327626c6218b793f87c2a5eb8.tar.bz2
Merge pull request #5331 from dcbaker/icl
ICL (Intel for Windows) support
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/backend/ninjabackend.py4
-rw-r--r--mesonbuild/build.py2
-rw-r--r--mesonbuild/compilers/__init__.py12
-rw-r--r--mesonbuild/compilers/c.py39
-rw-r--r--mesonbuild/compilers/clike.py4
-rw-r--r--mesonbuild/compilers/compilers.py75
-rw-r--r--mesonbuild/compilers/cpp.py111
-rw-r--r--mesonbuild/compilers/fortran.py38
-rw-r--r--mesonbuild/environment.py37
-rw-r--r--mesonbuild/linkers.py18
-rw-r--r--mesonbuild/modules/windows.py2
11 files changed, 271 insertions, 71 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index e0a6440..69682d4 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -221,6 +221,10 @@ class NinjaBackend(backends.Backend):
Detect the search prefix to use.'''
for compiler in self.build.compilers.values():
# Have to detect the dependency format
+
+ # IFort on windows is MSVC like, but doesn't have /showincludes
+ if isinstance(compiler, FortranCompiler):
+ continue
if isinstance(compiler, VisualStudioLikeCompiler):
break
else:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 603e0d0..bc17445 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1249,7 +1249,7 @@ You probably should put it in link_with instead.''')
'''
linker, _ = self.get_clink_dynamic_linker_and_stdlibs()
# Mixing many languages with MSVC is not supported yet so ignore stdlibs.
- if linker and linker.get_id() in ['msvc', 'clang-cl', 'llvm', 'dmd']:
+ if linker and linker.get_id() in {'msvc', 'clang-cl', 'intel-cl', 'llvm', 'dmd'}:
return True
return False
diff --git a/mesonbuild/compilers/__init__.py b/mesonbuild/compilers/__init__.py
index 3c06f38..ea65c21 100644
--- a/mesonbuild/compilers/__init__.py
+++ b/mesonbuild/compilers/__init__.py
@@ -65,10 +65,14 @@ __all__ = [
'FlangFortranCompiler',
'GnuObjCCompiler',
'GnuObjCPPCompiler',
- 'IntelCompiler',
+ 'IntelGnuLikeCompiler',
+ 'IntelVisualStudioLikeCompiler',
'IntelCCompiler',
'IntelCPPCompiler',
+ 'IntelClCCompiler',
+ 'IntelClCPPCompiler',
'IntelFortranCompiler',
+ 'IntelClFortranCompiler',
'JavaCompiler',
'LLVMDCompiler',
'MonoCompiler',
@@ -119,9 +123,10 @@ from .compilers import (
ClangCompiler,
CompilerArgs,
GnuCompiler,
- IntelCompiler,
+ IntelGnuLikeCompiler,
CcrxCompiler,
VisualStudioLikeCompiler,
+ IntelVisualStudioLikeCompiler,
)
from .c import (
CCompiler,
@@ -132,6 +137,7 @@ from .c import (
GnuCCompiler,
ElbrusCCompiler,
IntelCCompiler,
+ IntelClCCompiler,
PGICCompiler,
CcrxCCompiler,
VisualStudioCCompiler,
@@ -145,6 +151,7 @@ from .cpp import (
GnuCPPCompiler,
ElbrusCPPCompiler,
IntelCPPCompiler,
+ IntelClCPPCompiler,
PGICPPCompiler,
CcrxCPPCompiler,
VisualStudioCPPCompiler,
@@ -164,6 +171,7 @@ from .fortran import (
ElbrusFortranCompiler,
FlangFortranCompiler,
IntelFortranCompiler,
+ IntelClFortranCompiler,
NAGFortranCompiler,
Open64FortranCompiler,
PathScaleFortranCompiler,
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 73a4083..0cfcbc3 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -16,7 +16,7 @@ import os.path
import typing
from .. import coredata
-from ..mesonlib import MesonException, version_compare
+from ..mesonlib import MesonException, version_compare, mlog
from .c_function_attributes import C_FUNC_ATTRIBUTES
from .clike import CLikeCompiler
@@ -30,7 +30,8 @@ from .compilers import (
CompilerType,
GnuCompiler,
ElbrusCompiler,
- IntelCompiler,
+ IntelGnuLikeCompiler,
+ IntelVisualStudioLikeCompiler,
PGICompiler,
CcrxCompiler,
VisualStudioLikeCompiler,
@@ -221,10 +222,10 @@ class ElbrusCCompiler(GnuCCompiler, ElbrusCompiler):
dependencies=dependencies)
-class IntelCCompiler(IntelCompiler, CCompiler):
+class IntelCCompiler(IntelGnuLikeCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
- IntelCompiler.__init__(self, compiler_type)
+ IntelGnuLikeCompiler.__init__(self, compiler_type)
self.lang_header = 'c-header'
default_warn_args = ['-Wall', '-w3', '-diag-disable:remark']
self.warn_args = {'0': [],
@@ -279,6 +280,36 @@ class ClangClCCompiler(VisualStudioLikeCompiler, VisualStudioLikeCCompilerMixin,
self.id = 'clang-cl'
+class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerMixin, CCompiler):
+
+ """Intel "ICL" compiler abstraction."""
+
+ __have_warned = False
+
+ def __init__(self, exelist, version, is_cross, exe_wrap, target):
+ CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
+ IntelVisualStudioLikeCompiler.__init__(self, target)
+
+ def get_options(self):
+ opts = super().get_options()
+ c_stds = ['none', 'c89', 'c99', 'c11']
+ opts.update({'c_std': coredata.UserComboOption('c_std', 'C language standard to use',
+ c_stds,
+ 'none')})
+ return opts
+
+ def get_option_compile_args(self, options):
+ args = []
+ std = options['c_std']
+ if std.value == 'c89':
+ if not self.__have_warned:
+ self.__have_warned = True
+ mlog.warning("ICL doesn't explicitly implement c89, setting the standard to 'none', which is close.")
+ elif std.value != 'none':
+ args.append('/Qstd:' + std.value)
+ return args
+
+
class ArmCCompiler(ArmCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
diff --git a/mesonbuild/compilers/clike.py b/mesonbuild/compilers/clike.py
index e9d5d1d..3d29b75 100644
--- a/mesonbuild/compilers/clike.py
+++ b/mesonbuild/compilers/clike.py
@@ -776,7 +776,7 @@ class CLikeCompiler:
return True, cached
# MSVC does not have compiler __builtin_-s.
- if self.get_id() == 'msvc':
+ if self.get_id() in {'msvc', 'intel-cl'}:
return False, False
# Detect function as a built-in
@@ -849,7 +849,7 @@ class CLikeCompiler:
'''
args = self.get_compiler_check_args()
n = 'symbols_have_underscore_prefix'
- with self.compile(code, args, 'compile', want_output=True) as p:
+ with self.compile(code, extra_args=args, mode='compile', want_output=True) as p:
if p.returncode != 0:
m = 'BUG: Unable to compile {!r} check: {}'
raise RuntimeError(m.format(n, p.stdo))
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index bafb023..dacf75d 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -1146,7 +1146,7 @@ class Compiler:
return os.path.join(dirname, 'output.' + suffix)
@contextlib.contextmanager
- def compile(self, code, extra_args=None, mode='link', want_output=False):
+ def compile(self, code, extra_args=None, *, mode='link', want_output=False):
if extra_args is None:
extra_args = []
try:
@@ -1199,7 +1199,7 @@ class Compiler:
pass
@contextlib.contextmanager
- def cached_compile(self, code, cdata: coredata.CoreData, extra_args=None, mode: str = 'link'):
+ def cached_compile(self, code, cdata: coredata.CoreData, *, extra_args=None, mode: str = 'link'):
assert(isinstance(cdata, coredata.CoreData))
# Calculate the key
@@ -1465,14 +1465,14 @@ def get_compiler_uses_gnuld(c):
# FIXME: Perhaps we should detect the linker in the environment?
# FIXME: Assumes that *BSD use GNU ld, but they might start using lld soon
compiler_type = getattr(c, 'compiler_type', None)
- return compiler_type in (
+ return compiler_type in {
CompilerType.GCC_STANDARD,
CompilerType.GCC_MINGW,
CompilerType.GCC_CYGWIN,
CompilerType.CLANG_STANDARD,
CompilerType.CLANG_MINGW,
CompilerType.ICC_STANDARD,
- CompilerType.ICC_WIN)
+ }
def get_largefile_args(compiler):
'''
@@ -1791,16 +1791,7 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
return None
return vs32_instruction_set_args.get(instruction_set, None)
- def get_toolset_version(self):
- if self.id == 'clang-cl':
- # I have no idea
- return '14.1'
-
- # See boost/config/compiler/visualc.cpp for up to date mapping
- try:
- version = int(''.join(self.version.split('.')[0:2]))
- except ValueError:
- return None
+ def _calculate_toolset_version(self, version: int) -> Optional[str]:
if version < 1310:
return '7.0'
elif version < 1400:
@@ -1824,6 +1815,18 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
mlog.warning('Could not find toolset for version {!r}'.format(self.version))
return None
+ def get_toolset_version(self):
+ if self.id == 'clang-cl':
+ # I have no idea
+ return '14.1'
+
+ # See boost/config/compiler/visualc.cpp for up to date mapping
+ try:
+ version = int(''.join(self.version.split('.')[0:2]))
+ except ValueError:
+ return None
+ return self._calculate_toolset_version(version)
+
def get_default_include_dirs(self):
if 'INCLUDE' not in os.environ:
return []
@@ -2288,7 +2291,7 @@ class ArmclangCompiler:
# Tested on linux for ICC 14.0.3, 15.0.6, 16.0.4, 17.0.1, 19.0.0
-class IntelCompiler(GnuLikeCompiler):
+class IntelGnuLikeCompiler(GnuLikeCompiler):
def __init__(self, compiler_type):
super().__init__(compiler_type)
@@ -2344,6 +2347,48 @@ class IntelCompiler(GnuLikeCompiler):
return ['-prof-use']
+class IntelVisualStudioLikeCompiler(VisualStudioLikeCompiler):
+
+ """Abstractions for ICL, the Intel compiler on Windows."""
+
+ def __init__(self, target: str):
+ super().__init__(target)
+ self.compiler_type = CompilerType.ICC_WIN
+ self.id = 'intel-cl'
+
+ def compile(self, code, *, extra_args=None, **kwargs):
+ # This covers a case that .get('foo', []) doesn't, that extra_args is
+ if kwargs.get('mode', 'compile') != 'link':
+ extra_args = extra_args.copy() if extra_args is not None else []
+ extra_args.extend([
+ '/Qdiag-error:10006', # ignoring unknown option
+ '/Qdiag-error:10148', # Option not supported
+ '/Qdiag-error:10155', # ignoring argument required
+ '/Qdiag-error:10156', # ignoring not argument allowed
+ '/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().compile(code, extra_args, **kwargs)
+
+ def get_toolset_version(self) -> Optional[str]:
+ # Avoid circular dependencies....
+ from ..environment import search_version
+
+ # ICL provides a cl.exe that returns the version of MSVC it tries to
+ # emulate, so we'll get the version from that and pass it to the same
+ # function the real MSVC uses to calculate the toolset version.
+ _, _, err = Popen_safe(['cl.exe'])
+ v1, v2, *_ = search_version(err).split('.')
+ version = int(v1 + v2)
+ return self._calculate_toolset_version(version)
+
+ def get_linker_exelist(self):
+ return ['xilink']
+
+ def openmp_flags(self):
+ return ['/Qopenmp']
+
+
class ArmCompiler:
# Functionality that is common to all ARM family compilers.
def __init__(self, compiler_type):
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 988eac6..9fae22c 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -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)
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 3fee43b..06e01d0 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -26,8 +26,9 @@ from .compilers import (
GnuCompiler,
ClangCompiler,
ElbrusCompiler,
- IntelCompiler,
+ IntelGnuLikeCompiler,
PGICompiler,
+ IntelVisualStudioLikeCompiler,
)
from .clike import CLikeCompiler
@@ -66,6 +67,7 @@ class FortranCompiler(CLikeCompiler, Compiler):
for_machine = MachineChoice.HOST
extra_flags = environment.coredata.get_external_args(for_machine, self.language)
extra_flags += environment.coredata.get_external_link_args(for_machine, self.language)
+ extra_flags += self.get_always_args()
# %% build the test executable
pc = subprocess.Popen(self.exelist + extra_flags + [str(source_name), '-o', str(binary_name)])
pc.wait()
@@ -213,13 +215,13 @@ class SunFortranCompiler(FortranCompiler):
return ['-xopenmp']
-class IntelFortranCompiler(IntelCompiler, FortranCompiler):
+class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags):
self.file_suffixes = ('f90', 'f', 'for', 'ftn', 'fpp')
FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwags)
# FIXME: Add support for OS X and Windows in detect_fortran_compiler so
# we are sent the type of compiler
- IntelCompiler.__init__(self, CompilerType.ICC_STANDARD)
+ IntelGnuLikeCompiler.__init__(self, CompilerType.ICC_STANDARD)
self.id = 'intel'
default_warn_args = ['-warn', 'general', '-warn', 'truncated_source']
self.warn_args = {'0': [],
@@ -239,6 +241,36 @@ class IntelFortranCompiler(IntelCompiler, FortranCompiler):
def language_stdlib_only_link_flags(self):
return ['-lifcore', '-limf']
+class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler):
+
+ file_suffixes = ['f90', 'f', 'for', 'ftn', 'fpp']
+ always_args = ['/nologo']
+
+ BUILD_ARGS = {
+ 'plain': [],
+ 'debug': ["/Zi", "/Od"],
+ 'debugoptimized': ["/Zi", "/O1"],
+ 'release': ["/O2"],
+ 'minsize': ["/Os"],
+ 'custom': [],
+ }
+
+ def __init__(self, exelist, version, is_cross, target: str, exe_wrapper=None):
+ FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
+ IntelVisualStudioLikeCompiler.__init__(self, target)
+
+ default_warn_args = ['/warn:general', '/warn:truncated_source']
+ self.warn_args = {'0': [],
+ '1': default_warn_args,
+ '2': default_warn_args + ['/warn:unused'],
+ '3': ['/warn:all']}
+
+ def get_module_outdir_args(self, path) -> List[str]:
+ return ['/module:' + path]
+
+ def get_buildtype_args(self, buildtype: str) -> List[str]:
+ return self.BUILD_ARGS[buildtype]
+
class PathScaleFortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags):
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index dd1d4cf..9620639 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -15,7 +15,7 @@
import os, platform, re, sys, shlex, shutil, subprocess, typing
from . import coredata
-from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker, CcrxLinker
+from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker, CcrxLinker, IntelVisualStudioLinker
from . import mesonlib
from .mesonlib import (
MesonException, EnvironmentException, MachineChoice, Popen_safe,
@@ -60,7 +60,10 @@ from .compilers import (
ElbrusFortranCompiler,
IntelCCompiler,
IntelCPPCompiler,
+ IntelClCCompiler,
+ IntelClCPPCompiler,
IntelFortranCompiler,
+ IntelClFortranCompiler,
JavaCompiler,
MonoCompiler,
CudaCompiler,
@@ -457,12 +460,18 @@ class Environment:
# List of potential compilers.
if mesonlib.is_windows():
# Intel C and C++ compiler is icl on Windows, but icc and icpc elsewhere.
- self.default_c = ['cl', 'cc', 'gcc', 'clang', 'clang-cl', 'pgcc', 'icl']
+ # Search for icl before cl, since Intel "helpfully" provides a
+ # cl.exe that returns *exactly the same thing* that microsofts
+ # cl.exe does, and if icl is present, it's almost certainly what
+ # you want.
+ self.default_c = ['icl', 'cl', 'cc', 'gcc', 'clang', 'clang-cl', 'pgcc']
# There is currently no pgc++ for Windows, only for Mac and Linux.
- self.default_cpp = ['cl', 'c++', 'g++', 'clang++', 'clang-cl', 'icl']
+ self.default_cpp = ['icl', 'cl', 'c++', 'g++', 'clang++', 'clang-cl']
+ self.default_fortran = ['ifort', 'gfortran', 'flang', 'pgfortran', 'g95']
else:
self.default_c = ['cc', 'gcc', 'clang', 'pgcc', 'icc']
self.default_cpp = ['c++', 'g++', 'clang++', 'pgc++', 'icpc']
+ self.default_fortran = ['gfortran', 'flang', 'pgfortran', 'ifort', 'g95']
if mesonlib.is_windows():
self.default_cs = ['csc', 'mcs']
else:
@@ -470,7 +479,6 @@ class Environment:
self.default_objc = ['cc']
self.default_objcpp = ['c++']
self.default_d = ['ldc2', 'ldc', 'gdc', 'dmd']
- self.default_fortran = ['gfortran', 'flang', 'pgfortran', 'ifort', 'g95']
self.default_java = ['javac']
self.default_cuda = ['nvcc']
self.default_rust = ['rustc']
@@ -677,8 +685,12 @@ class Environment:
arg = '--vsn'
elif 'ccrx' in compiler[0]:
arg = '-v'
+ elif 'icl' in compiler[0]:
+ # if you pass anything to icl you get stuck in a pager
+ arg = ''
else:
arg = '--version'
+
try:
p, out, err = Popen_safe(compiler + [arg])
except OSError as e:
@@ -753,6 +765,11 @@ class Environment:
compiler_type = CompilerType.CLANG_STANDARD
cls = ClangCCompiler if lang == 'c' else ClangCPPCompiler
return cls(ccache + compiler, version, compiler_type, is_cross, exe_wrap, full_version=full_version)
+ if 'Intel(R) C++ Intel(R)' in err:
+ version = search_version(err)
+ target = 'x86' if 'IA-32' in err else 'x86_64'
+ cls = IntelClCCompiler if lang == 'c' else IntelClCPPCompiler
+ return cls(compiler, version, is_cross, exe_wrap, target)
if 'Microsoft' in out or 'Microsoft' in err:
# Latest versions of Visual Studio print version
# number to stderr but earlier ones print version
@@ -886,6 +903,11 @@ class Environment:
version = search_version(err)
return SunFortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
+ if 'Intel(R) Visual Fortran' in err:
+ version = search_version(err)
+ target = 'x86' if 'IA-32' in err else 'x86_64'
+ return IntelClFortranCompiler(compiler, version, is_cross, target, exe_wrap)
+
if 'ifort (IFORT)' in out:
return IntelFortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
@@ -1172,11 +1194,14 @@ class Environment:
linkers = [self.vs_static_linker, self.clang_cl_static_linker, compiler.get_linker_exelist()]
else:
linkers = [self.default_static_linker, compiler.get_linker_exelist()]
+ elif isinstance(compiler, IntelClCCompiler):
+ # Intel has it's own linker that acts like microsoft's lib
+ linkers = ['xilib']
else:
linkers = [self.default_static_linker]
popen_exceptions = {}
for linker in linkers:
- if not set(['lib', 'lib.exe', 'llvm-lib', 'llvm-lib.exe']).isdisjoint(linker):
+ if not {'lib', 'lib.exe', 'llvm-lib', 'llvm-lib.exe', 'xilib', 'xilib.exe'}.isdisjoint(linker):
arg = '/?'
else:
arg = '--version'
@@ -1185,6 +1210,8 @@ class Environment:
except OSError as e:
popen_exceptions[' '.join(linker + [arg])] = e
continue
+ if "xilib: executing 'lib'" in err:
+ return IntelVisualStudioLinker(linker, getattr(compiler, 'machine', None))
if '/OUT:' in out.upper() or '/OUT:' in err.upper():
return VisualStudioLinker(linker, getattr(compiler, 'machine', None))
if p.returncode == 0 and ('armar' in linker or 'armar.exe' in linker):
diff --git a/mesonbuild/linkers.py b/mesonbuild/linkers.py
index c6302bf..648d1ef 100644
--- a/mesonbuild/linkers.py
+++ b/mesonbuild/linkers.py
@@ -23,7 +23,7 @@ class StaticLinker:
return mesonlib.is_windows()
-class VisualStudioLinker(StaticLinker):
+class VisualStudioLikeLinker:
always_args = ['/NOLOGO']
def __init__(self, exelist, machine):
@@ -31,7 +31,7 @@ class VisualStudioLinker(StaticLinker):
self.machine = machine
def get_exelist(self):
- return self.exelist[:]
+ return self.exelist.copy()
def get_std_link_args(self):
return []
@@ -50,10 +50,10 @@ class VisualStudioLinker(StaticLinker):
return []
def get_always_args(self):
- return VisualStudioLinker.always_args[:]
+ return self.always_args.copy()
def get_linker_always_args(self):
- return VisualStudioLinker.always_args[:]
+ return self.always_args.copy()
def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath):
return []
@@ -77,6 +77,16 @@ class VisualStudioLinker(StaticLinker):
return []
+class VisualStudioLinker(VisualStudioLikeLinker, StaticLinker):
+
+ """Microsoft's lib static linker."""
+
+
+class IntelVisualStudioLinker(VisualStudioLikeLinker, StaticLinker):
+
+ """Intel's xilib static linker."""
+
+
class ArLinker(StaticLinker):
def __init__(self, exelist):
diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
index 87a83fe..e2fd9a8 100644
--- a/mesonbuild/modules/windows.py
+++ b/mesonbuild/modules/windows.py
@@ -51,7 +51,7 @@ class WindowsModule(ExtensionModule):
if not rescomp or not rescomp.found():
comp = self.detect_compiler(state.compilers)
- if comp.id == 'msvc' or comp.id == 'clang-cl':
+ if comp.id in {'msvc', 'clang-cl', 'intel-cl'}:
rescomp = ExternalProgram('rc', silent=True)
else:
rescomp = ExternalProgram('windres', silent=True)