aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2018-11-04 19:56:08 +0200
committerGitHub <noreply@github.com>2018-11-04 19:56:08 +0200
commit1eb455f8696643b625b10a85551ff9fd28dd7d2a (patch)
treef6fa0bb549b609d3db1fea05181e7ff92c6b1fa3 /mesonbuild/compilers
parent253c581412d7f2b09af353dd83d943454bd555be (diff)
parentac6d4338cce68f5040825fb9bfb95dd147390e76 (diff)
downloadmeson-1eb455f8696643b625b10a85551ff9fd28dd7d2a.zip
meson-1eb455f8696643b625b10a85551ff9fd28dd7d2a.tar.gz
meson-1eb455f8696643b625b10a85551ff9fd28dd7d2a.tar.bz2
Merge pull request #4250 from jon-turney/windows-clang-cl
Add support for clang-cl on Windows
Diffstat (limited to 'mesonbuild/compilers')
-rw-r--r--mesonbuild/compilers/__init__.py4
-rw-r--r--mesonbuild/compilers/c.py33
-rw-r--r--mesonbuild/compilers/cpp.py23
-rw-r--r--mesonbuild/compilers/d.py2
4 files changed, 47 insertions, 15 deletions
diff --git a/mesonbuild/compilers/__init__.py b/mesonbuild/compilers/__init__.py
index 677301e..7050b0c 100644
--- a/mesonbuild/compilers/__init__.py
+++ b/mesonbuild/compilers/__init__.py
@@ -45,6 +45,8 @@ __all__ = [
'ClangCPPCompiler',
'ClangObjCCompiler',
'ClangObjCPPCompiler',
+ 'ClangClCCompiler',
+ 'ClangClCPPCompiler',
'CompilerArgs',
'CPPCompiler',
'DCompiler',
@@ -114,6 +116,7 @@ from .c import (
ArmCCompiler,
ArmclangCCompiler,
ClangCCompiler,
+ ClangClCCompiler,
GnuCCompiler,
ElbrusCCompiler,
IntelCCompiler,
@@ -124,6 +127,7 @@ from .cpp import (
ArmCPPCompiler,
ArmclangCPPCompiler,
ClangCPPCompiler,
+ ClangClCPPCompiler,
GnuCPPCompiler,
ElbrusCPPCompiler,
IntelCPPCompiler,
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 9b24e85..35c71df 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -170,7 +170,7 @@ class CCompiler(Compiler):
else:
# GNU ld and LLVM lld
return ['-Wl,--allow-shlib-undefined']
- elif self.id == 'msvc':
+ elif isinstance(self, VisualStudioCCompiler):
# link.exe
return ['/FORCE:UNRESOLVED']
# FIXME: implement other linkers
@@ -392,6 +392,8 @@ class CCompiler(Compiler):
return self.compiles(t.format(**fargs), env, extra_args, dependencies)
def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
+ if callable(extra_args):
+ extra_args = extra_args(mode)
if extra_args is None:
extra_args = []
elif isinstance(extra_args, str):
@@ -890,7 +892,7 @@ class CCompiler(Compiler):
stlibext = ['a']
# We've always allowed libname to be both `foo` and `libfoo`,
# and now people depend on it
- if strict and self.id != 'msvc': # lib prefix is not usually used with msvc
+ if strict and not isinstance(self, VisualStudioCCompiler): # lib prefix is not usually used with msvc
prefixes = ['lib']
else:
prefixes = ['lib', '']
@@ -900,7 +902,7 @@ class CCompiler(Compiler):
elif for_windows(env.is_cross_build(), env):
# FIXME: .lib files can be import or static so we should read the
# file, figure out which one it is, and reject the wrong kind.
- if self.id == 'msvc':
+ if isinstance(self, VisualStudioCCompiler):
shlibext = ['lib']
else:
shlibext = ['dll.a', 'lib', 'dll']
@@ -1296,7 +1298,7 @@ class VisualStudioCCompiler(CCompiler):
def get_buildtype_args(self, buildtype):
args = compilers.msvc_buildtype_args[buildtype]
- if version_compare(self.version, '<18.0'):
+ if self.id == 'msvc' and version_compare(self.version, '<18.0'):
args = [arg for arg in args if arg != '/Gw']
return args
@@ -1314,6 +1316,8 @@ class VisualStudioCCompiler(CCompiler):
def get_pch_use_args(self, pch_dir, header):
base = os.path.basename(header)
+ if self.id == 'clang-cl':
+ base = header
pchname = self.get_pch_name(header)
return ['/FI' + base, '/Yu' + base, '/Fp' + os.path.join(pch_dir, pchname)]
@@ -1341,7 +1345,12 @@ class VisualStudioCCompiler(CCompiler):
return []
def get_linker_exelist(self):
- return ['link'] # FIXME, should have same path as compiler.
+ # FIXME, should have same path as compiler.
+ # FIXME, should be controllable via cross-file.
+ if self.id == 'clang-cl':
+ return ['lld-link']
+ else:
+ return ['link']
def get_linker_always_args(self):
return ['/nologo']
@@ -1449,6 +1458,8 @@ class VisualStudioCCompiler(CCompiler):
# http://stackoverflow.com/questions/15259720/how-can-i-make-the-microsoft-c-compiler-treat-unknown-flags-as-errors-rather-t
def has_arguments(self, args, env, code, mode):
warning_text = '4044' if mode == 'link' else '9002'
+ if self.id == 'clang-cl' and mode != 'link':
+ args = args + ['-Werror=unknown-argument']
with self._build_wrapper(code, env, extra_args=args, mode=mode) as p:
if p.returncode != 0:
return False
@@ -1464,7 +1475,7 @@ class VisualStudioCCompiler(CCompiler):
# build obviously, which is why we only do this when PCH is on.
# This was added in Visual Studio 2013 (MSVC 18.0). Before that it was
# always on: https://msdn.microsoft.com/en-us/library/dn502518.aspx
- if pch and version_compare(self.version, '>=18.0'):
+ if pch and self.id == 'msvc' and version_compare(self.version, '>=18.0'):
args = ['/FS'] + args
return args
@@ -1481,7 +1492,7 @@ class VisualStudioCCompiler(CCompiler):
def get_instruction_set_args(self, instruction_set):
if self.is_64:
return vs64_instruction_set_args.get(instruction_set, None)
- if self.version.split('.')[0] == '16' and instruction_set == 'avx':
+ if self.id == 'msvc' and self.version.split('.')[0] == '16' and instruction_set == 'avx':
# VS documentation says that this exists and should work, but
# it does not. The headers do not contain AVX intrinsics
# and the can not be called.
@@ -1489,6 +1500,10 @@ class VisualStudioCCompiler(CCompiler):
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]))
@@ -1546,6 +1561,10 @@ class VisualStudioCCompiler(CCompiler):
def get_argument_syntax(self):
return 'msvc'
+class ClangClCCompiler(VisualStudioCCompiler):
+ def __init__(self, exelist, version, is_cross, exe_wrap, is_64):
+ super().__init__(exelist, version, is_cross, exe_wrap, is_64)
+ self.id = 'clang-cl'
class ArmCCompiler(ArmCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 9dc2876..65a1033 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -19,7 +19,7 @@ from .. import coredata
from .. import mlog
from ..mesonlib import MesonException, version_compare
-from .c import CCompiler, VisualStudioCCompiler
+from .c import CCompiler, VisualStudioCCompiler, ClangClCCompiler
from .compilers import (
CompilerType,
gnu_winlibs,
@@ -310,12 +310,15 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
def get_options(self):
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'])
- # Visual Studio 2017 and later
- if version_compare(self.version, '>=19.11'):
- cpp_stds.extend(['c++17', 'vc++17'])
+ if self.id == 'clang-cl':
+ cpp_stds.extend(['c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest'])
+ else:
+ # Visual Studio 2015 and later
+ if version_compare(self.version, '>=19'):
+ cpp_stds.extend(['c++14', 'vc++14', 'c++latest', 'vc++latest'])
+ # Visual Studio 2017 and later
+ if version_compare(self.version, '>=19.11'):
+ cpp_stds.extend(['c++17', 'vc++17'])
opts = CPPCompiler.get_options(self)
opts.update({'cpp_eh': coredata.UserComboOption('cpp_eh',
@@ -356,7 +359,7 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
# 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 version_compare(self.version, '>=19.00.24210'):
+ 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')
@@ -378,6 +381,10 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
# so just use the plain C args.
return VisualStudioCCompiler.get_compiler_check_args(self)
+class ClangClCPPCompiler(VisualStudioCPPCompiler, ClangClCCompiler):
+ def __init__(self, exelist, version, is_cross, exe_wrap, is_64):
+ VisualStudioCPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, is_64)
+ self.id = 'clang-cl'
class ArmCPPCompiler(ArmCompiler, CPPCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrap=None, **kwargs):
diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py
index 099d907..0a59e7f 100644
--- a/mesonbuild/compilers/d.py
+++ b/mesonbuild/compilers/d.py
@@ -274,6 +274,8 @@ class DCompiler(Compiler):
return ['-Wl,-rpath,{}'.format(paths)]
def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
+ if callable(extra_args):
+ extra_args = extra_args(mode)
if extra_args is None:
extra_args = []
elif isinstance(extra_args, str):