浏览代码

VS: Don't compute CUDA options unless necessary

In the following scenario (with 3.18 policies):
1. A CXX target is created.
2. CUDA language is enabled.

CMake 3.18 introduced CMP0104, which requires CUDA_ARCHITECTURES to be
set.  Because the CXX target was created before CUDA was enabled it
wouldn't have it set.  The Visual Studio generator would however end up
computing CUDA compile options for the CXX target, which would result in
a fatal error due to the policy violation.

There doesn't seem to be a reason to do this for targets that don't
actually use the CUDA language, so we can skip and generate the CXX
target just fine.

Fixes: #21341
Raul Tambre 5 年之前
父节点
当前提交
dd77dec18d

+ 8 - 0
Source/cmGeneratorTarget.cxx

@@ -6914,6 +6914,14 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
   }
   }
 }
 }
 
 
+bool cmGeneratorTarget::IsLanguageUsed(std::string const& language,
+                                       std::string const& config) const
+{
+  std::set<std::string> languages;
+  this->GetLanguages(languages, config);
+  return languages.count(language);
+}
+
 bool cmGeneratorTarget::IsCSharpOnly() const
 bool cmGeneratorTarget::IsCSharpOnly() const
 {
 {
   // Only certain target types may compile CSharp.
   // Only certain target types may compile CSharp.

+ 2 - 0
Source/cmGeneratorTarget.h

@@ -397,6 +397,8 @@ public:
   // until we have per-target object file properties.
   // until we have per-target object file properties.
   void GetLanguages(std::set<std::string>& languages,
   void GetLanguages(std::set<std::string>& languages,
                     std::string const& config) const;
                     std::string const& config) const;
+  bool IsLanguageUsed(std::string const& language,
+                      std::string const& config) const;
 
 
   bool IsCSharpOnly() const;
   bool IsCSharpOnly() const;
 
 

+ 4 - 2
Source/cmVisualStudio10TargetGenerator.cxx

@@ -3018,7 +3018,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions()
     return true;
     return true;
   }
   }
   for (std::string const& c : this->Configurations) {
   for (std::string const& c : this->Configurations) {
-    if (!this->ComputeCudaOptions(c)) {
+    if (this->GeneratorTarget->IsLanguageUsed("CUDA", c) &&
+        !this->ComputeCudaOptions(c)) {
       return false;
       return false;
     }
     }
   }
   }
@@ -3158,7 +3159,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
 void cmVisualStudio10TargetGenerator::WriteCudaOptions(
 void cmVisualStudio10TargetGenerator::WriteCudaOptions(
   Elem& e1, std::string const& configName)
   Elem& e1, std::string const& configName)
 {
 {
-  if (!this->MSTools || !this->GlobalGenerator->IsCudaEnabled()) {
+  if (!this->MSTools || !this->GlobalGenerator->IsCudaEnabled() ||
+      !this->GeneratorTarget->IsLanguageUsed("CUDA", configName)) {
     return;
     return;
   }
   }
   Elem e2(e1, "CudaCompile");
   Elem e2(e1, "CudaCompile");

+ 4 - 0
Tests/RunCMake/CMP0104/CMP0104-Common.cmake

@@ -1,2 +1,6 @@
+# Make sure CMP0104 isn't issued for CXX targets created prior to enabling CUDA. See #21341.
+enable_language(CXX)
+add_library(cxx main.cxx)
+
 enable_language(CUDA)
 enable_language(CUDA)
 add_library(cuda main.cu)
 add_library(cuda main.cu)

+ 3 - 0
Tests/RunCMake/CMP0104/main.cxx

@@ -0,0 +1,3 @@
+int main()
+{
+}