Bläddra i källkod

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.
Brad King 8 år sedan
förälder
incheckning
f2059585e6

+ 25 - 7
Source/cmVisualStudio10TargetGenerator.cxx

@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmVisualStudio10TargetGenerator.h"
 #include "cmVisualStudio10TargetGenerator.h"
 
 
+#include "cmAlgorithms.h"
 #include "cmComputeLinkInformation.h"
 #include "cmComputeLinkInformation.h"
 #include "cmCustomCommandGenerator.h"
 #include "cmCustomCommandGenerator.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
@@ -2227,10 +2228,27 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
       this->Name.c_str());
       this->Name.c_str());
     return false;
     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<std::string> 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_";
     std::string baseFlagVar = "CMAKE_";
-    baseFlagVar += linkLanguage;
+    baseFlagVar += langForClCompile;
     baseFlagVar += "_FLAGS";
     baseFlagVar += "_FLAGS";
     flags =
     flags =
       this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition(
       this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition(
@@ -2241,6 +2259,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
     flags +=
     flags +=
       this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition(
       this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition(
         flagVar.c_str());
         flagVar.c_str());
+    this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
+                                            langForClCompile, configName);
   }
   }
   // set the correct language
   // set the correct language
   if (linkLanguage == "C") {
   if (linkLanguage == "C") {
@@ -2249,10 +2269,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
   if (linkLanguage == "CXX") {
   if (linkLanguage == "CXX") {
     clOptions.AddFlag("CompileAs", "CompileAsCpp");
     clOptions.AddFlag("CompileAs", "CompileAsCpp");
   }
   }
-  if (linkLanguage != "CUDA") {
-    this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
-                                            linkLanguage, configName.c_str());
-  }
 
 
   // Check IPO related warning/error.
   // Check IPO related warning/error.
   this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName);
   this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName);
@@ -2480,6 +2496,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
     std::string(this->Makefile->GetSafeDefinition("CMAKE_CUDA_FLAGS")) +
     std::string(this->Makefile->GetSafeDefinition("CMAKE_CUDA_FLAGS")) +
     std::string(" ") +
     std::string(" ") +
     std::string(this->Makefile->GetSafeDefinition(configFlagsVar));
     std::string(this->Makefile->GetSafeDefinition(configFlagsVar));
+  this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, "CUDA",
+                                          configName);
 
 
   // Get preprocessor definitions for this directory.
   // Get preprocessor definitions for this directory.
   std::string defineFlags =
   std::string defineFlags =

+ 1 - 0
Tests/CudaOnly/WithDefs/CMakeLists.txt

@@ -28,6 +28,7 @@ add_executable(CudaOnlyWithDefs ${main})
 
 
 target_compile_options(CudaOnlyWithDefs
 target_compile_options(CudaOnlyWithDefs
   PRIVATE
   PRIVATE
+    -Xcompiler=-DHOST_DEFINE
     $<$<CONFIG:DEBUG>:$<BUILD_INTERFACE:${debug_compile_flags}>>
     $<$<CONFIG:DEBUG>:$<BUILD_INTERFACE:${debug_compile_flags}>>
   )
   )
 
 

+ 4 - 0
Tests/CudaOnly/WithDefs/main.notcu

@@ -2,6 +2,10 @@
 #include <cuda_runtime.h>
 #include <cuda_runtime.h>
 #include <iostream>
 #include <iostream>
 
 
+#ifndef HOST_DEFINE
+#error "HOST_DEFINE not defined!"
+#endif
+
 #ifndef PACKED_DEFINE
 #ifndef PACKED_DEFINE
 #error "PACKED_DEFINE not defined!"
 #error "PACKED_DEFINE not defined!"
 #endif
 #endif