Compare commits

...

34 Commits

Author SHA1 Message Date
Jussi Pakkanen 7b8ef78bc0
Merge pull request #5331 from dcbaker/icl 5 years ago
Nirbheek Chauhan b849f6f935 FAQ: Add an entry about the library naming scheme with MSVC [skip ci] 5 years ago
Dylan Baker 523c7beefc docs/markdown: add snippet for intel-cl support 5 years ago
Dylan Baker be88945ee3 docs/reference-table: Add intel-cl 5 years ago
Dylan Baker b557d00f90 environment: search for icl and ifort before cl and goftran 5 years ago
Dylan Baker 7e4b2f5758 environment: Add search for ICL 5 years ago
Dylan Baker f5ea341319 compilers/clike: ICL needs msvc workarounds in has_function 5 years ago
Dylan Baker fa54f05f09 compilers: Add basic ICL abstractions 5 years ago
Dylan Baker de011e031c modules/windows: ICL uses rc, not windres 5 years ago
Dylan Baker b935359978 backends/ninja: Ifort is msvc-like but doesn't have showincludes 5 years ago
Dylan Baker 94591ce7b0 build: Treat ICL like MSVC in regards to standard lib linking 5 years ago
Dylan Baker c916024b41 compilers: ICL is not GCC like 5 years ago
Dylan Baker 080f59cf43 compilers: rename IntelCompiler to IntelGnuLikeCompiler 5 years ago
Dylan Baker 5fb64b0cfa compilers: Split msvc version code into helper 5 years ago
Dylan Baker 7d0e0d6f6e linkers: Add linker class for intel's xilib 5 years ago
Dylan Baker af19db7b40 linkers: Split Visual Studio Linker into a mixin 5 years ago
Dylan Baker 14fa3da33e compilers/cpp: Split code out of VisualStudioLikeCPPCompiler for treating c++11 as c++14 5 years ago
Dylan Baker cb70a20490 compilers: make keyword args to Compiler.compile keyword only 5 years ago
Dylan Baker dcfd918548 run_unittests: assume that on windows that intel means icl 5 years ago
Dylan Baker 3e82a4b517 run_unittests: intel-cl links like msvc 5 years ago
Dylan Baker 73eca8255b run_unittests: Don't assume that VS like compilers have MSVC versions 5 years ago
Dylan Baker c72fd1e333 run_unittests: ICL also doesn't do proper resource dependency detection 5 years ago
Dylan Baker ecc1f17f8e tests/fortran/14: Add vsdef files 5 years ago
Dylan Baker 23d2311d12 tests/fortran/9 cpp: It's okay to link ICL and ifort 5 years ago
Dylan Baker 0dc88487dd tests/fortran/1: call compiler.get_id() == str instead of compiler == str 5 years ago
Dylan Baker d3a1994031 tests/204: Fix intel-cl expectations 5 years ago
Dylan Baker 7d4e3d2589 tests/206: Fix intel vs intel-cl expectations 5 years ago
Dylan Baker 73d6bde9b6 tests/143: Add xilib check for ICL 5 years ago
Dylan Baker 43c1ab0d98 tests/132: ICL should not run this test like MSVC and clang-cl 5 years ago
Dylan Baker 86a8bf1148 tests/124: ICL alos does not use ASM 5 years ago
Dylan Baker c91e779d8b tests/123: Add /nologo to cl and ml 5 years ago
Dylan Baker dc564a71a3 tests/123: For MSVC like compilers to treat the .S file like a .c file 5 years ago
Dylan Baker ac5b1d1bc8 tests/common/40: ICL behaves like MSVC and should be tested like it 5 years ago
Dylan Baker 28aac9fc3b test cases: Add ICL branches in addition to ICC branches 5 years ago
  1. 34
      docs/markdown/FAQ.md
  2. 47
      docs/markdown/Reference-tables.md
  3. 13
      docs/markdown/snippets/intel-cl.md
  4. 4
      mesonbuild/backend/ninjabackend.py
  5. 2
      mesonbuild/build.py
  6. 12
      mesonbuild/compilers/__init__.py
  7. 39
      mesonbuild/compilers/c.py
  8. 4
      mesonbuild/compilers/clike.py
  9. 75
      mesonbuild/compilers/compilers.py
  10. 111
      mesonbuild/compilers/cpp.py
  11. 38
      mesonbuild/compilers/fortran.py
  12. 37
      mesonbuild/environment.py
  13. 18
      mesonbuild/linkers.py
  14. 2
      mesonbuild/modules/windows.py
  15. 2
      run_project_tests.py
  16. 13
      run_unittests.py
  17. 5
      test cases/common/1 trivial/meson.build
  18. 5
      test cases/common/123 llvm ir and assembly/meson.build
  19. 2
      test cases/common/124 cpp and asm/meson.build
  20. 2
      test cases/common/132 generated assembly/meson.build
  21. 2
      test cases/common/143 C and CPP link/meson.build
  22. 5
      test cases/common/2 cpp/meson.build
  23. 4
      test cases/common/204 function attributes/meson.build
  24. 10
      test cases/common/206 argument syntax/meson.build
  25. 2
      test cases/common/40 has function/meson.build
  26. 2
      test cases/fortran/1 basic/meson.build
  27. 2
      test cases/fortran/14 fortran links c/clib.def
  28. 2
      test cases/fortran/14 fortran links c/meson.build
  29. 2
      test cases/fortran/9 cpp/meson.build

@ -365,3 +365,37 @@ compiler.
- If the compiler is freely available, consider adding it to the CI
system.
## Why does building my project with MSVC output static libraries called `libfoo.a`?
The naming convention for static libraries on Windows is usually `foo.lib`.
Unfortunately, import libraries are also called `foo.lib`.
This causes filename collisions with the default library type where we build
both shared and static libraries, and also causes collisions during
installation since all libraries are installed to the same directory by default.
To resolve this, we decided to default to creating static libraries of the form
`libfoo.a` when building with MSVC. This has the following advantages:
1. Filename collisions are completely avoided.
1. The format for MSVC static libraries is `ar`, which is the same as the GNU
static library format, so using this extension is semantically correct.
1. The static library filename format is now the same on all platforms and with
all toolchains.
1. Both Clang and GNU compilers can search for `libfoo.a` when specifying
a library as `-lfoo`. This does not work for alternative naming schemes for
static libraries such as `libfoo.lib`.
1. Since `-lfoo` works out of the box, pkgconfig files will work correctly for
projects built with both MSVC, GCC, and Clang on Windows.
1. MSVC does not have arguments to search for library filenames, and [it does
not care what the extension is](https://docs.microsoft.com/en-us/cpp/build/reference/link-input-files?view=vs-2019),
so specifying `libfoo.a` instead of `foo.lib` does not change the workflow,
and is an improvement since it's less ambiguous.
If, for some reason, you really need your project to output static libraries of
the form `foo.lib` when building with MSVC, you can set the
[`name_prefix:`](https://mesonbuild.com/Reference-manual.html#library)
kwarg to `''` and the [`name_suffix:`](https://mesonbuild.com/Reference-manual.html#library)
kwarg to `'lib'`. To get the default behaviour for each, you can either not
specify the kwarg, or pass `[]` (an empty array) to it.

@ -5,29 +5,30 @@
These are return values of the `get_id` (Compiler family) and
`get_argument_syntax` (Argument syntax) method in a compiler object.
| Value | Compiler family | Argument syntax |
| ----- | --------------- | --------------- |
| arm | ARM compiler | |
| armclang | ARMCLANG compiler | |
| ccrx | Renesas RX Family C/C++ compiler | |
| clang | The Clang compiler | gcc |
| clang-cl | The Clang compiler (MSVC compatible driver) | msvc |
| dmd | D lang reference compiler | |
| flang | Flang Fortran compiler | |
| g95 | The G95 Fortran compiler | |
| gcc | The GNU Compiler Collection | gcc |
| intel | Intel compiler | msvc on windows, otherwise gcc |
| lcc | Elbrus C/C++/Fortran Compiler | |
| llvm | LLVM-based compiler (Swift, D) | |
| mono | Xamarin C# compiler | |
| msvc | Microsoft Visual Studio | msvc |
| nagfor | The NAG Fortran compiler | |
| open64 | The Open64 Fortran Compiler | |
| pathscale | The Pathscale Fortran compiler | |
| pgi | Portland PGI C/C++/Fortran compilers | |
| rustc | Rust compiler | |
| sun | Sun Fortran compiler | |
| valac | Vala compiler | |
| Value | Compiler family | Argument syntax |
| ----- | --------------- | --------------- |
| arm | ARM compiler | |
| armclang | ARMCLANG compiler | |
| ccrx | Renesas RX Family C/C++ compiler | |
| clang | The Clang compiler | gcc |
| clang-cl | The Clang compiler (MSVC compatible driver) | msvc |
| dmd | D lang reference compiler | |
| flang | Flang Fortran compiler | |
| g95 | The G95 Fortran compiler | |
| gcc | The GNU Compiler Collection | 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 | |
| msvc | Microsoft Visual Studio | msvc |
| nagfor | The NAG Fortran compiler | |
| open64 | The Open64 Fortran Compiler | |
| pathscale | The Pathscale Fortran compiler | |
| pgi | Portland PGI C/C++/Fortran compilers | |
| rustc | Rust compiler | |
| sun | Sun Fortran compiler | |
| valac | Vala compiler | |
## Script environment variables

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

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