From f2059585e6302446707560b123c7b785df5f5859 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 21 Jun 2017 13:44:43 -0400 Subject: VS: Fix target_compile_options for CUDA Fix the VS generator to honor `COMPILE_OPTIONS` for CUDA. The exclusion added by commit v3.9.0-rc1~431^2~7 (VS: Do not pass CUDA compile options to C compiler, 2017-03-07) was correct but we need additional logic to pass the CUDA compile options to the CUDA compiler. Also we should still pass the CXX or C options to MSVC (ClCompile) when those languages are enabled even if the link language is CUDA. --- Source/cmVisualStudio10TargetGenerator.cxx | 32 +++++++++++++++++++++++------- Tests/CudaOnly/WithDefs/CMakeLists.txt | 1 + Tests/CudaOnly/WithDefs/main.notcu | 4 ++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 238c9e8..2a7d96b 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmVisualStudio10TargetGenerator.h" +#include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmCustomCommandGenerator.h" #include "cmGeneratedFileStream.h" @@ -2227,10 +2228,27 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( this->Name.c_str()); return false; } - if (linkLanguage == "C" || linkLanguage == "CXX" || - linkLanguage == "Fortran" || linkLanguage == "CSharp") { + + // Choose a language whose flags to use for ClCompile. + static const char* clLangs[] = { "CXX", "C", "Fortran", "CSharp" }; + std::string langForClCompile; + if (std::find(cmArrayBegin(clLangs), cmArrayEnd(clLangs), linkLanguage) != + cmArrayEnd(clLangs)) { + langForClCompile = linkLanguage; + } else { + std::set languages; + this->GeneratorTarget->GetLanguages(languages, configName); + for (const char* const* l = cmArrayBegin(clLangs); + l != cmArrayEnd(clLangs); ++l) { + if (languages.find(*l) != languages.end()) { + langForClCompile = *l; + break; + } + } + } + if (!langForClCompile.empty()) { std::string baseFlagVar = "CMAKE_"; - baseFlagVar += linkLanguage; + baseFlagVar += langForClCompile; baseFlagVar += "_FLAGS"; flags = this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition( @@ -2241,6 +2259,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( flags += this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition( flagVar.c_str()); + this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, + langForClCompile, configName); } // set the correct language if (linkLanguage == "C") { @@ -2249,10 +2269,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( if (linkLanguage == "CXX") { clOptions.AddFlag("CompileAs", "CompileAsCpp"); } - if (linkLanguage != "CUDA") { - this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, - linkLanguage, configName.c_str()); - } // Check IPO related warning/error. this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName); @@ -2480,6 +2496,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( std::string(this->Makefile->GetSafeDefinition("CMAKE_CUDA_FLAGS")) + std::string(" ") + std::string(this->Makefile->GetSafeDefinition(configFlagsVar)); + this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, "CUDA", + configName); // Get preprocessor definitions for this directory. std::string defineFlags = diff --git a/Tests/CudaOnly/WithDefs/CMakeLists.txt b/Tests/CudaOnly/WithDefs/CMakeLists.txt index 38f2a44..e25f141 100644 --- a/Tests/CudaOnly/WithDefs/CMakeLists.txt +++ b/Tests/CudaOnly/WithDefs/CMakeLists.txt @@ -28,6 +28,7 @@ add_executable(CudaOnlyWithDefs ${main}) target_compile_options(CudaOnlyWithDefs PRIVATE + -Xcompiler=-DHOST_DEFINE $<$:$> ) diff --git a/Tests/CudaOnly/WithDefs/main.notcu b/Tests/CudaOnly/WithDefs/main.notcu index 80ed3a5..d2eff3f 100644 --- a/Tests/CudaOnly/WithDefs/main.notcu +++ b/Tests/CudaOnly/WithDefs/main.notcu @@ -2,6 +2,10 @@ #include #include +#ifndef HOST_DEFINE +#error "HOST_DEFINE not defined!" +#endif + #ifndef PACKED_DEFINE #error "PACKED_DEFINE not defined!" #endif -- cgit v0.12 From 3b75421515835b2fc6713be3015cc3f7324bb5a8 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 21 Jun 2017 14:15:23 -0400 Subject: VS: Improve workaround for CUDA -Xcompiler placement bug In commit v3.9.0-rc1~431^2~6 (VS: Place CUDA host compiler options in proper project file fields, 2017-03-07) we worked around a bug in the CUDA VS integration by dropping `AdditionalCompilerOptions`. However, this silently drops `-Xcompiler=` options given by the user that don't map to one of CudaCompile's dedicated settings. Improve the workaround to instead put the remaining `AdditionalCompilerOptions` into the `AdditionalOptions` field behind `-Xcompiler=` ourselves. --- Source/cmVisualStudio10TargetGenerator.cxx | 13 ++++++++++--- Tests/CudaOnly/SeparateCompilation/CMakeLists.txt | 4 ++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 2a7d96b..32ece3f 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2523,9 +2523,16 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( cudaOptions.AddTable(gg->GetCudaHostFlagTable()); cudaOptions.Reparse("AdditionalCompilerOptions"); - // `CUDA 8.0.targets` places these before nvcc! Just drop whatever - // did not parse and hope it works. - cudaOptions.RemoveFlag("AdditionalCompilerOptions"); + // `CUDA 8.0.targets` places AdditionalCompilerOptions before nvcc! + // Pass them through -Xcompiler in AdditionalOptions instead. + if (const char* acoPtr = cudaOptions.GetFlag("AdditionalCompilerOptions")) { + std::string aco = acoPtr; + cudaOptions.RemoveFlag("AdditionalCompilerOptions"); + if (!aco.empty()) { + aco = this->LocalGenerator->EscapeForShell(aco, false); + cudaOptions.AppendFlag("AdditionalOptions", "-Xcompiler=" + aco); + } + } cudaOptions.FixCudaCodeGeneration(); diff --git a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt index 0a2542a..f42324e 100644 --- a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt +++ b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt @@ -15,6 +15,10 @@ set(CMAKE_CUDA_STANDARD 11) add_library(CUDASeparateLibA STATIC file1.cu file2.cu file3.cu) +if(CMAKE_CUDA_SIMULATE_ID STREQUAL "MSVC") + target_compile_options(CUDASeparateLibA PRIVATE -Xcompiler=-bigobj) +endif() + #Having file4/file5 in a shared library causes serious problems #with the nvcc linker and it will generate bad entries that will #cause a segv when trying to run the executable -- cgit v0.12