Merge pull request #5331 from dcbaker/icl

ICL (Intel for Windows) support
pull/5394/head
Jussi Pakkanen 6 years ago committed by GitHub
commit 7b8ef78bc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      docs/markdown/Reference-tables.md
  2. 13
      docs/markdown/snippets/intel-cl.md
  3. 4
      mesonbuild/backend/ninjabackend.py
  4. 2
      mesonbuild/build.py
  5. 12
      mesonbuild/compilers/__init__.py
  6. 39
      mesonbuild/compilers/c.py
  7. 4
      mesonbuild/compilers/clike.py
  8. 75
      mesonbuild/compilers/compilers.py
  9. 109
      mesonbuild/compilers/cpp.py
  10. 38
      mesonbuild/compilers/fortran.py
  11. 37
      mesonbuild/environment.py
  12. 18
      mesonbuild/linkers.py
  13. 2
      mesonbuild/modules/windows.py
  14. 2
      run_project_tests.py
  15. 13
      run_unittests.py
  16. 5
      test cases/common/1 trivial/meson.build
  17. 5
      test cases/common/123 llvm ir and assembly/meson.build
  18. 2
      test cases/common/124 cpp and asm/meson.build
  19. 2
      test cases/common/132 generated assembly/meson.build
  20. 2
      test cases/common/143 C and CPP link/meson.build
  21. 5
      test cases/common/2 cpp/meson.build
  22. 4
      test cases/common/204 function attributes/meson.build
  23. 10
      test cases/common/206 argument syntax/meson.build
  24. 2
      test cases/common/40 has function/meson.build
  25. 2
      test cases/fortran/1 basic/meson.build
  26. 2
      test cases/fortran/14 fortran links c/clib.def
  27. 2
      test cases/fortran/14 fortran links c/meson.build
  28. 2
      test cases/fortran/9 cpp/meson.build

@ -16,7 +16,8 @@ These are return values of the `get_id` (Compiler family) and
| flang | Flang Fortran compiler | |
| g95 | The G95 Fortran compiler | |
| gcc | The GNU Compiler Collection | gcc |
| intel | Intel compiler | msvc on windows, otherwise gcc |
| intel | Intel compiler (Linux and Mac) | gcc |
| intel-cl | Intel compiler (Windows) | msvc |
| lcc | Elbrus C/C++/Fortran Compiler | |
| llvm | LLVM-based compiler (Swift, D) | |
| mono | Xamarin C# compiler | |

@ -0,0 +1,13 @@
## Support for the Intel Compiler on Windows (ICL)
Support has been added for ICL.EXE and ifort on windows. The support should be
on part with ICC support on Linux/MacOS. The ICL C/C++ compiler behaves like
Microsoft's CL.EXE rather than GCC/Clang like ICC does, and has a different id,
`intel-cl` to differentiate it.
```meson
cc = meson.get_compiler('c')
if cc.get_id == 'intel-cl'
add_project_argument('/Qfoobar:yes', language : 'c')
endif
```

@ -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:

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

@ -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,

@ -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)

@ -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))

@ -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):

@ -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]
permissive, ver = self.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:
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)
class ClangClCPPCompiler(VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompiler, CPPCompiler):
if version_compare(self.version, '<19.11'):
try:
i = args.index('/permissive-')
except ValueError:
return args
del args[i]
return args
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)

@ -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):

@ -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):

@ -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):

@ -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)

@ -120,7 +120,7 @@ def get_relative_files_list_from_dir(fromdir):
def platform_fix_name(fname, compiler, env):
# canonicalize compiler
if compiler == 'clang-cl':
if compiler in {'clang-cl', 'intel-cl'}:
canonical_compiler = 'msvc'
else:
canonical_compiler = compiler

@ -981,7 +981,8 @@ class InternalTests(unittest.TestCase):
toolset_ver = cc.get_toolset_version()
self.assertIsNotNone(toolset_ver)
# Visual Studio 2015 and older versions do not define VCToolsVersion
if int(''.join(cc.version.split('.')[0:2])) < 1910:
# TODO: ICL doesn't set this in the VSC2015 profile either
if cc.id == 'msvc' and int(''.join(cc.version.split('.')[0:2])) < 1910:
return
self.assertIn('VCToolsVersion', os.environ)
vctools_ver = os.environ['VCToolsVersion']
@ -1938,7 +1939,7 @@ class AllPlatformTests(BasePlatformTests):
'''
gnu = mesonbuild.compilers.GnuCompiler
clang = mesonbuild.compilers.ClangCompiler
intel = mesonbuild.compilers.IntelCompiler
intel = mesonbuild.compilers.IntelGnuLikeCompiler
msvc = (mesonbuild.compilers.VisualStudioCCompiler, mesonbuild.compilers.VisualStudioCPPCompiler)
clangcl = (mesonbuild.compilers.ClangClCCompiler, mesonbuild.compilers.ClangClCPPCompiler)
ar = mesonbuild.linkers.ArLinker
@ -2821,7 +2822,7 @@ recommended as it is not supported on some platforms''')
testdirlib = os.path.join(testdirbase, 'lib')
extra_args = None
env = get_fake_env(testdirlib, self.builddir, self.prefix)
if env.detect_c_compiler(False).get_id() not in ['msvc', 'clang-cl']:
if env.detect_c_compiler(False).get_id() not in {'msvc', 'clang-cl', 'intel-cl'}:
# static libraries are not linkable with -l with msvc because meson installs them
# as .a files which unix_args_to_native will not know as it expects libraries to use
# .lib as extension. For a DLL the import library is installed as .lib. Thus for msvc
@ -3994,7 +3995,7 @@ class WindowsTests(BasePlatformTests):
# resource compiler depfile generation is not yet implemented for msvc
env = get_fake_env(testdir, self.builddir, self.prefix)
depfile_works = env.detect_c_compiler(False).get_id() not in ['msvc', 'clang-cl']
depfile_works = env.detect_c_compiler(False).get_id() not in {'msvc', 'clang-cl', 'intel-cl'}
self.init(testdir)
self.build()
@ -5872,6 +5873,10 @@ class NativeFileTests(BasePlatformTests):
raise unittest.SkipTest('No alternate Fortran implementation.')
elif comp.id == 'gcc':
if shutil.which('ifort'):
# There is an ICC for windows (windows build, linux host),
# but we don't support that ATM so lets not worry about it.
if is_windows():
return 'ifort', 'intel-cl'
return 'ifort', 'intel'
elif shutil.which('flang'):
return 'flang', 'flang'

@ -6,9 +6,12 @@ project('trivial test',
#this is a comment
sources = 'trivial.c'
if meson.get_compiler('c').get_id() == 'intel'
cc = meson.get_compiler('c')
if cc.get_id() == 'intel'
# Error out if the -std=xxx option is incorrect
add_project_arguments('-diag-error', '10159', language : 'c')
elif cc.get_id() == 'intel-cl'
add_project_arguments('/Qdiag-error:10159', language : 'c')
endif
if meson.is_cross_build()

@ -41,16 +41,17 @@ foreach lang : ['c', 'cpp']
error('MESON_SKIP_TEST: ML (masm) not found')
endif
# Preprocess file (ml doesn't support pre-processing)
# Force the intput to be C (/Tc) because ICL otherwise assumes it's an object (.obj) file
preproc_name = lang + square_base + '.i'
square_preproc = custom_target(lang + square_impl + 'preproc',
input : square_impl,
output : preproc_name,
command : [cl, '/EP', '/P', '/Fi' + preproc_name, '@INPUT@'] + uscore_args)
command : [cl, '/nologo', '/EP', '/P', '/Fi' + preproc_name, '/Tc', '@INPUT@'] + uscore_args)
# Use assembled object file instead of the original .S assembly source
square_impl = custom_target(lang + square_impl,
input : square_preproc,
output : lang + square_base + '.obj',
command : [ml, '/safeseh', '/Fo', '@OUTPUT@', '/c', '@INPUT@'])
command : [ml, '/nologo', '/safeseh', '/Fo', '@OUTPUT@', '/c', '@INPUT@'])
endif
if supported_cpus.contains(cpu)
e = executable('square_asm_' + lang, square_impl, 'main.' + lang,

@ -15,7 +15,7 @@ endif
sources = ['trivial.cc']
# If the compiler cannot compile assembly, don't use it
if not ['msvc', 'clang-cl'].contains(meson.get_compiler('cpp').get_id())
if not ['msvc', 'clang-cl', 'intel-cl'].contains(meson.get_compiler('cpp').get_id())
sources += ['retval-' + cpu + '.S']
cpp_args = ['-DUSE_ASM']
message('Using ASM')

@ -2,7 +2,7 @@ project('generated assembly', 'c')
cc = meson.get_compiler('c')
if ['msvc', 'clang-cl'].contains(cc.get_id())
if ['msvc', 'clang-cl', 'intel-cl'].contains(cc.get_id())
error('MESON_SKIP_TEST: assembly files cannot be compiled directly by the compiler')
endif

@ -30,6 +30,8 @@ if cxx.get_argument_syntax() == 'msvc'
static_linker = find_program('lib')
elif cxx.get_id() == 'clang-cl'
static_linker = find_program('llvm-lib')
elif cxx.get_id() == 'intel-cl'
static_linker = find_program('xilib')
else
error('unable to determine static linker to use with this compiler')
endif

@ -1,8 +1,11 @@
project('c++ test', 'cpp')
if meson.get_compiler('cpp').get_id() == 'intel'
cpp = meson.get_compiler('cpp')
if cpp.get_id() == 'intel'
# Error out if the -std=xxx option is incorrect
add_project_arguments('-diag-error', '10159', language : 'cpp')
elif cpp.get_id() == 'intel-cl'
add_project_arguments('/Qdiag-error:10159', language : 'cpp')
endif
exe = executable('trivialprog', 'trivial.cc', extra_files : 'something.txt')

@ -19,7 +19,7 @@ project('gcc func attributes', ['c', 'cpp'])
c = meson.get_compiler('c')
cpp = meson.get_compiler('cpp')
expected_result = not ['msvc', 'clang-cl'].contains(c.get_id())
expected_result = not ['msvc', 'clang-cl', 'intel-cl'].contains(c.get_id())
# Q: Why is ifunc not in this list or any of the below lists?
# A: It's too damn hard to figure out if you actually support it, since it
@ -95,7 +95,7 @@ foreach a : ['dllexport', 'dllimport']
endforeach
message('checking get_supported_function_attributes')
if not ['msvc', 'clang-cl'].contains(c.get_id())
if not ['msvc', 'clang-cl', 'intel-cl'].contains(c.get_id())
multi_expected = attributes
else
multi_expected = []

@ -5,16 +5,10 @@ project(
cc = meson.get_compiler('c')
if ['gcc', 'lcc', 'clang'].contains(cc.get_id())
if ['gcc', 'lcc', 'clang', 'intel'].contains(cc.get_id())
expected = 'gcc'
elif ['msvc', 'clang-cl'].contains(cc.get_id())
elif ['msvc', 'clang-cl', 'intel-cl'].contains(cc.get_id())
expected = 'msvc'
elif cc.get_id() == 'intel'
if host_machine.system() == 'windows'
expected = 'msvc'
else
expected = 'gcc'
endif
else
# It's possible that other compilers end up here that shouldn't
expected = 'other'

@ -21,7 +21,7 @@ foreach cc : compilers
# not taken from a cache (ie. the check above)
# On MSVC fprintf is defined as an inline function in the header, so it cannot
# be found without the include.
if cc.get_id() != 'msvc'
if not ['msvc', 'intel-cl'].contains(cc.get_id())
assert(cc.has_function('fprintf', args : unit_test_args),
'"fprintf" function not found without include (on !msvc).')
else

@ -1,7 +1,7 @@
project('simple fortran', 'fortran')
fc = meson.get_compiler('fortran')
if fc == 'gcc'
if fc.get_id() == 'gcc'
add_global_arguments('-fbounds-check', language : 'fortran')
endif

@ -5,7 +5,7 @@ if ccid == 'msvc' or ccid == 'clang-cl'
error('MESON_SKIP_TEST: MSVC and GCC do not interoperate like this.')
endif
c_lib = library('clib', 'clib.c')
c_lib = library('clib', 'clib.c', vs_module_defs : 'clib.def')
f_call_c = executable('f_call_c', 'f_call_c.f90',
link_with: c_lib,

@ -7,7 +7,7 @@ if cpp.get_id() == 'clang'
error('MESON_SKIP_TEST Clang C++ does not find -lgfortran for some reason.')
endif
if build_machine.system() == 'windows' and cpp.get_id() != 'gnu'
if build_machine.system() == 'windows' and cpp.get_id() != fc.get_id()
error('MESON_SKIP_TEST mixing gfortran with non-GNU C++ does not work.')
endif

Loading…
Cancel
Save