From 424b6ecc0626bf4fa1590d84d1c062789d3bd6e5 Mon Sep 17 00:00:00 2001 From: Olexa Bilaniuk Date: Tue, 16 Feb 2021 10:44:06 -0500 Subject: [PATCH] Add optional -Dcuda_ccbindir= option and -ccbin flag to CUDA compiler. Closes #8110. --- docs/markdown/Builtin-options.md | 1 + mesonbuild/compilers/cuda.py | 37 +++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md index 2d7c01caeca8..e3805ac0049f 100644 --- a/docs/markdown/Builtin-options.md +++ b/docs/markdown/Builtin-options.md @@ -194,6 +194,7 @@ or compiler being used: | cpp_thread_count | 4 | integer value ≥ 0 | Number of threads to use with emcc when using threads | | cpp_winlibs | see below | free-form comma-separated list | Standard Windows libs to link against | | fortran_std | none | [none, legacy, f95, f2003, f2008, f2018] | Fortran language standard to use | +| cuda_ccbindir | | filesystem path | CUDA non-default toolchain directory to use (-ccbin) *(Added in 0.57.1)* | The default values of `c_winlibs` and `cpp_winlibs` are in compiler-specific argument forms, but the libraries are: kernel32, diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 7baf5e540589..472cbb3e046a 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -477,7 +477,7 @@ def needs_static_linker(self) -> bool: def thread_link_flags(self, environment: 'Environment') -> T.List[str]: return self._to_host_flags(self.host_compiler.thread_link_flags(environment), _Phase.LINKER) - def sanity_check(self, work_dir: str, environment: 'Environment') -> None: + def sanity_check(self, work_dir: str, env: 'Environment') -> None: mlog.debug('Sanity testing ' + self.get_display_language() + ' compiler:', ' '.join(self.exelist)) mlog.debug('Is cross compiler: %s.' % str(self.is_cross)) @@ -521,7 +521,18 @@ def sanity_check(self, work_dir: str, environment: 'Environment') -> None: # environment set up properly. Of course, this only works for native # builds; For cross builds we must still use the exe_wrapper (if any). self.detected_cc = '' - flags = ['-w', '-cudart', 'static', source_name] + flags = [] + + # Disable warnings, compile with statically-linked runtime for minimum + # reliance on the system. + flags += ['-w', '-cudart', 'static', source_name] + + # Use the -ccbin option, if available, even during sanity checking. + # Otherwise, on systems where CUDA does not support the default compiler, + # NVCC becomes unusable. + flags += self.get_ccbin_args(env.coredata.options) + + # If cross-compiling, we can't run the sanity check, only compile it. if self.is_cross and self.exe_wrapper is None: # Linking cross built apps is painful. You can't really # tell if you should use -nostdlib or not and for example @@ -601,10 +612,14 @@ def has_header_symbol(self, hname: str, symbol: str, prefix: str, def get_options(self) -> 'KeyedOptionDictType': opts = super().get_options() - key = OptionKey('std', machine=self.for_machine, lang=self.language) - opts.update({key: coredata.UserComboOption('C++ language standard to use with cuda', - ['none', 'c++03', 'c++11', 'c++14'], - 'none')}) + std_key = OptionKey('std', machine=self.for_machine, lang=self.language) + ccbindir_key = OptionKey('ccbindir', machine=self.for_machine, lang=self.language) + opts.update({ + std_key: coredata.UserComboOption('C++ language standard to use with CUDA', + ['none', 'c++03', 'c++11', 'c++14', 'c++17'], 'none'), + ccbindir_key: coredata.UserStringOption('CUDA non-default toolchain directory to use (-ccbin)', + ''), + }) return opts def _to_host_compiler_options(self, options: 'KeyedOptionDictType') -> 'KeyedOptionDictType': @@ -612,7 +627,7 @@ def _to_host_compiler_options(self, options: 'KeyedOptionDictType') -> 'KeyedOpt return OptionOverrideProxy(overrides, self.host_compiler.get_options()) def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args = self.get_ccbin_args(options) # On Windows, the version of the C++ standard used by nvcc is dictated by # the combination of CUDA version and MSVC version; the --std= is thus ignored # and attempting to use it will result in a warning: https://stackoverflow.com/a/51272091/741027 @@ -625,7 +640,8 @@ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str] return args + self._to_host_flags(self.host_compiler.get_option_compile_args(self._to_host_compiler_options(options))) def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - return self._to_host_flags(self.host_compiler.get_option_link_args(self._to_host_compiler_options(options)), _Phase.LINKER) + args = self.get_ccbin_args(options) + return args + self._to_host_flags(self.host_compiler.get_option_link_args(self._to_host_compiler_options(options)), _Phase.LINKER) def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str, suffix: str, soversion: str, @@ -726,3 +742,8 @@ def get_dependency_compile_args(self, dep: 'Dependency') -> T.List[str]: def get_dependency_link_args(self, dep: 'Dependency') -> T.List[str]: return self._to_host_flags(super().get_dependency_link_args(dep), _Phase.LINKER) + + def get_ccbin_args(self, options: 'KeyedOptionDictType') -> T.List[str]: + key = OptionKey('ccbindir', machine=self.for_machine, lang=self.language) + ccbindir: str = options[key].value + return [self._shield_nvcc_list_arg('-ccbin='+ccbindir, False)] if ccbindir else []