aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2021-03-28 21:43:29 +0300
committerGitHub <noreply@github.com>2021-03-28 21:43:29 +0300
commitf335e1299b71f88b39a142ae6c10276ef7f547b4 (patch)
tree45bb40fb991da5c63081f7aab852c38ed76a665c
parent1db49240c6491416d7e1c87bdec19bf401d9b7c5 (diff)
parent2579420a72b64c020f9538d8ccbb52fd57c804a1 (diff)
downloadmeson-f335e1299b71f88b39a142ae6c10276ef7f547b4.zip
meson-f335e1299b71f88b39a142ae6c10276ef7f547b4.tar.gz
meson-f335e1299b71f88b39a142ae6c10276ef7f547b4.tar.bz2
Merge pull request #8596 from mesonbuild/cudafix0572
Fixed version of #8527
-rw-r--r--mesonbuild/compilers/cuda.py76
-rw-r--r--test cases/cuda/16 multistd/main.cu20
-rw-r--r--test cases/cuda/16 multistd/meson.build4
3 files changed, 83 insertions, 17 deletions
diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py
index ef6375a..145b7c8 100644
--- a/mesonbuild/compilers/cuda.py
+++ b/mesonbuild/compilers/cuda.py
@@ -218,21 +218,6 @@ class CudaCompiler(Compiler):
# strings between them.
l = [cls._shield_nvcc_list_arg(s) for s in arg.split(SQ)]
l = sum([[s, DQSQ] for s in l][:-1], []) # Interleave l with DQSQs
-
- # The list l now has the structure of shielded strings interleaved
- # with double-quoted single-quotes.
- #
- # Plain concatenation would result in the tripling of the length of
- # a string made up only of single quotes. See if we can merge some
- # DQSQs together first.
- def isdqsq(x:str) -> bool:
- return x.startswith(SQ) and x.endswith(SQ) and x[1:-1].strip(SQ) == ''
- for i in range(1, len(l)-2, 2):
- if isdqsq(l[i]) and l[i+1] == '' and isdqsq(l[i+2]):
- l[i+2] = l[i][:-1]+l[i+2][1:]
- l[i] = ''
-
- # With DQSQs merged, simply concatenate everything together and return.
return ''.join(l)
else:
# A comma is present, and list mode was active.
@@ -260,6 +245,52 @@ class CudaCompiler(Compiler):
return r'\,'.join(l)
@classmethod
+ def _merge_flags(cls, flags: T.List[str]) -> T.List[str]:
+ r"""
+ The flags to NVCC gets exceedingly verbose and unreadable when too many of them
+ are shielded with -Xcompiler. Merge consecutive -Xcompiler-wrapped arguments
+ into one.
+ """
+ if len(flags) <= 1:
+ return flags
+ flagit = iter(flags)
+ xflags = []
+
+ def is_xcompiler_flag_isolated(flag: str) -> bool:
+ return flag == '-Xcompiler'
+ def is_xcompiler_flag_glued(flag: str) -> bool:
+ return flag.startswith('-Xcompiler=')
+ def is_xcompiler_flag(flag: str) -> bool:
+ return is_xcompiler_flag_isolated(flag) or is_xcompiler_flag_glued(flag)
+ def get_xcompiler_val(flag: str, flagit: T.Iterator[str]) -> str:
+ if is_xcompiler_flag_glued(flag):
+ return flag[len('-Xcompiler='):]
+ else:
+ try:
+ return next(flagit)
+ except StopIteration:
+ return ""
+
+ ingroup = False
+ for flag in flagit:
+ if not is_xcompiler_flag(flag):
+ ingroup = False
+ xflags.append(flag)
+ elif ingroup:
+ xflags[-1] += ','
+ xflags[-1] += get_xcompiler_val(flag, flagit)
+ elif is_xcompiler_flag_isolated(flag):
+ ingroup = True
+ xflags.append(flag)
+ xflags.append(get_xcompiler_val(flag, flagit))
+ elif is_xcompiler_flag_glued(flag):
+ ingroup = True
+ xflags.append(flag)
+ else:
+ raise ValueError("-Xcompiler flag merging failed, unknown argument form!")
+ return xflags
+
+ @classmethod
def _to_host_flags(cls, flags: T.List[str], phase: _Phase = _Phase.COMPILER) -> T.List[str]:
"""
Translate generic "GCC-speak" plus particular "NVCC-speak" flags to NVCC flags.
@@ -432,7 +463,7 @@ class CudaCompiler(Compiler):
xflags.append(flag)
xflags.append(val)
- return xflags
+ return cls._merge_flags(xflags)
def needs_static_linker(self) -> bool:
return False
@@ -586,8 +617,19 @@ class CudaCompiler(Compiler):
return opts
def _to_host_compiler_options(self, options: 'KeyedOptionDictType') -> 'KeyedOptionDictType':
+ """
+ Convert an NVCC Option set to a host compiler's option set.
+ """
+
+ # We must strip the -std option from the host compiler option set, as NVCC has
+ # its own -std flag that may not agree with the host compiler's.
overrides = {name: opt.value for name, opt in options.items()}
- return OptionOverrideProxy(overrides, self.host_compiler.get_options())
+ overrides.pop(OptionKey('std', machine=self.for_machine,
+ lang=self.host_compiler.language), None)
+ host_options = self.host_compiler.get_options().copy()
+ if 'std' in host_options:
+ del host_options['std'] # type: ignore
+ return OptionOverrideProxy(overrides, host_options)
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = self.get_ccbin_args(options)
diff --git a/test cases/cuda/16 multistd/main.cu b/test cases/cuda/16 multistd/main.cu
new file mode 100644
index 0000000..a2ffba4
--- /dev/null
+++ b/test cases/cuda/16 multistd/main.cu
@@ -0,0 +1,20 @@
+#include <cuda_runtime.h>
+#include <iostream>
+
+auto cuda_devices(void) {
+ int result = 0;
+ cudaGetDeviceCount(&result);
+ return result;
+}
+
+
+int main(void) {
+ int n = cuda_devices();
+ if (n == 0) {
+ std::cout << "No Cuda hardware found. Exiting.\n";
+ return 0;
+ }
+
+ std::cout << "Found " << n << "Cuda devices.\n";
+ return 0;
+}
diff --git a/test cases/cuda/16 multistd/meson.build b/test cases/cuda/16 multistd/meson.build
new file mode 100644
index 0000000..4769a87
--- /dev/null
+++ b/test cases/cuda/16 multistd/meson.build
@@ -0,0 +1,4 @@
+project('C++-CUDA multi-std', 'cpp', 'cuda', version : '1.0.0', default_options : ['cpp_std=c++17', 'cuda_std=c++14'])
+
+exe = executable('prog', 'main.cu')
+test('cudatest', exe)