aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/compilers/mixins/clang.py15
-rw-r--r--mesonbuild/compilers/mixins/visualstudio.py12
-rw-r--r--mesonbuild/linkers/detect.py3
-rw-r--r--mesonbuild/linkers/linkers.py6
-rw-r--r--test cases/common/180 has link arg/meson.build20
5 files changed, 55 insertions, 1 deletions
diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py
index a57b9a9..f982509 100644
--- a/mesonbuild/compilers/mixins/clang.py
+++ b/mesonbuild/compilers/mixins/clang.py
@@ -11,7 +11,7 @@ import typing as T
from ... import mesonlib
from ...linkers.linkers import AppleDynamicLinker, ClangClDynamicLinker, LLVMDynamicLinker, GnuGoldDynamicLinker, \
- MoldDynamicLinker
+ MoldDynamicLinker, MSVCDynamicLinker
from ...mesonlib import OptionKey
from ..compilers import CompileCheckMode
from .gnu import GnuLikeCompiler
@@ -111,6 +111,13 @@ class ClangCompiler(GnuLikeCompiler):
# Shouldn't work, but it'll be checked explicitly in the OpenMP dependency.
return []
+ def gen_vs_module_defs_args(self, defsfile: str) -> T.List[str]:
+ if isinstance(self.linker, (MSVCDynamicLinker)):
+ # With MSVC, DLLs only export symbols that are explicitly exported,
+ # so if a module defs file is specified, we use that to export symbols
+ return ['-Wl,/DEF:' + defsfile]
+ return super().gen_vs_module_defs_args(defsfile)
+
@classmethod
def use_linker_args(cls, linker: str, version: str) -> T.List[str]:
# Clang additionally can use a linker specified as a path, which GCC
@@ -155,6 +162,12 @@ class ClangCompiler(GnuLikeCompiler):
args.extend(super().get_lto_compile_args(threads=threads))
return args
+ def linker_to_compiler_args(self, args: T.List[str]) -> T.List[str]:
+ if isinstance(self.linker, (ClangClDynamicLinker, MSVCDynamicLinker)):
+ return [flag if flag.startswith('-Wl,') else f'-Wl,{flag}' for flag in args]
+ else:
+ return args
+
def get_lto_link_args(self, *, threads: int = 0, mode: str = 'default',
thinlto_cache_dir: T.Optional[str] = None) -> T.List[str]:
args = self.get_lto_compile_args(threads=threads, mode=mode)
diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py
index d6ebd6e..4e2ce09 100644
--- a/mesonbuild/compilers/mixins/visualstudio.py
+++ b/mesonbuild/compilers/mixins/visualstudio.py
@@ -460,6 +460,18 @@ class ClangClCompiler(VisualStudioLikeCompiler):
path = '.'
return ['/clang:-isystem' + path] if is_system else ['-I' + path]
+ @classmethod
+ def use_linker_args(cls, linker: str, version: str) -> T.List[str]:
+ # Clang additionally can use a linker specified as a path, unlike MSVC.
+ if linker == 'lld-link':
+ return ['-fuse-ld=lld-link']
+ return super().use_linker_args(linker, version)
+
+ def linker_to_compiler_args(self, args: T.List[str]) -> T.List[str]:
+ # clang-cl forwards arguments span-wise with the /LINK flag
+ # therefore -Wl will be received by lld-link or LINK and rejected
+ return super().use_linker_args(self.linker.id, '') + super().linker_to_compiler_args([flag[4:] if flag.startswith('-Wl,') else flag for flag in args])
+
def get_dependency_compile_args(self, dep: 'Dependency') -> T.List[str]:
if dep.get_include_type() == 'system':
converted: T.List[str] = []
diff --git a/mesonbuild/linkers/detect.py b/mesonbuild/linkers/detect.py
index 1bce413..bb391d1 100644
--- a/mesonbuild/linkers/detect.py
+++ b/mesonbuild/linkers/detect.py
@@ -55,6 +55,9 @@ def guess_win_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
if value is not None:
override = comp_class.use_linker_args(value[0], comp_version)
check_args += override
+ elif 'lld-link' in compiler:
+ override = comp_class.use_linker_args('lld-link', comp_version)
+ check_args += override
if extra_args is not None:
check_args.extend(extra_args)
diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py
index 657e361..ca3c854 100644
--- a/mesonbuild/linkers/linkers.py
+++ b/mesonbuild/linkers/linkers.py
@@ -1319,6 +1319,9 @@ class MSVCDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):
def get_win_subsystem_args(self, value: str) -> T.List[str]:
return self._apply_prefix([f'/SUBSYSTEM:{value.upper()}'])
+ def fatal_warnings(self) -> T.List[str]:
+ return ['-WX']
+
class ClangClDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):
@@ -1348,6 +1351,9 @@ class ClangClDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):
def get_thinlto_cache_args(self, path: str) -> T.List[str]:
return ["/lldltocache:" + path]
+ def fatal_warnings(self) -> T.List[str]:
+ return ['-WX']
+
class XilinkDynamicLinker(VisualStudioLikeLinkerMixin, DynamicLinker):
diff --git a/test cases/common/180 has link arg/meson.build b/test cases/common/180 has link arg/meson.build
index 6bfbd59..111b0b9 100644
--- a/test cases/common/180 has link arg/meson.build
+++ b/test cases/common/180 has link arg/meson.build
@@ -45,3 +45,23 @@ endif
assert(cc.has_multi_link_arguments(is_arg), 'Arg that should have worked does not work.')
assert(cc.has_multi_link_arguments([useless, is_arg]), 'Arg that should have worked does not work.')
+
+# These are Visual Studio only flags
+# Testing has_argument_syntax is incorrect as it skips Microsoft Clang
+if cc.get_define('_MSC_FULL_VER') != ''
+ if cc.get_linker_id() == 'link'
+ is_only = '/OPT:REF'
+ is_shared = '/GUARD:CF'
+ else # ld-link
+ is_only = '--color-diagnostics'
+ is_shared = '-guard:cf'
+ endif
+
+ # requires -Wl,xxx as it goes through the compiler
+ if cc.get_argument_syntax() != 'msvc'
+ is_only = '-Wl,@0@'.format(is_only)
+ is_shared = '-Wl,@0@'.format(is_shared)
+ endif
+
+ assert(cc.has_multi_link_arguments([is_only, is_shared]), 'Arg that should have worked does not work.')
+endif