浏览代码

Diagnose object library self-reference

The code

    add_library(A OBJECT a.c)
    target_sources(A PRIVATE $<TARGET_OBJECTS:A>)

used to crash CMake via infinite recursion while evaluating the
generator expression.  Then the change in commit v3.9.0-rc1~266^2~1
(cmGeneratorTarget: Replace source classifier implementation,
2017-04-07) avoided the infinite recursion because GetKindedSources now
creates a map entry and initializes it once.  If it is called again on
the same target during that initialization, the partially computed
results are returned.  This is still wrong but does not crash.
Detect and diagnose this case instead.

Co-Author: Ben Boeckel <[email protected]>
Fixes: #16578
Brad King 8 年之前
父节点
当前提交
d89e10cd58

+ 11 - 0
Source/cmGeneratorTarget.cxx

@@ -1025,12 +1025,23 @@ cmGeneratorTarget::KindedSources const& cmGeneratorTarget::GetKindedSources(
   std::string const key = cmSystemTools::UpperCase(config);
   KindedSourcesMapType::iterator it = this->KindedSourcesMap.find(key);
   if (it != this->KindedSourcesMap.end()) {
+    if (!it->second.Initialized) {
+      std::ostringstream e;
+      e << "The SOURCES of \"" << this->GetName()
+        << "\" use a generator expression that depends on the "
+           "SOURCES themselves.";
+      this->GlobalGenerator->GetCMakeInstance()->IssueMessage(
+        cmake::FATAL_ERROR, e.str(), this->GetBacktrace());
+      static KindedSources empty;
+      return empty;
+    }
     return it->second;
   }
 
   // Add an entry to the map for this configuration.
   KindedSources& files = this->KindedSourcesMap[key];
   this->ComputeKindedSources(files, config);
+  files.Initialized = true;
   return files;
 }
 

+ 5 - 0
Source/cmGeneratorTarget.h

@@ -107,6 +107,11 @@ public:
     std::set<std::string> ExpectedResxHeaders;
     std::set<std::string> ExpectedXamlHeaders;
     std::set<std::string> ExpectedXamlSources;
+    bool Initialized;
+    KindedSources()
+      : Initialized(false)
+    {
+    }
   };
 
   /** Get all sources needed for a configuration with kinds assigned.  */

+ 1 - 0
Tests/RunCMake/ObjectLibrary/OwnSources-result.txt

@@ -0,0 +1 @@
+1

+ 5 - 0
Tests/RunCMake/ObjectLibrary/OwnSources-stderr.txt

@@ -0,0 +1,5 @@
+^CMake Error at OwnSources.cmake:[0-9]+ \(add_library\):
+  The SOURCES of "A" use a generator expression that depends on the SOURCES
+  themselves.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$

+ 2 - 0
Tests/RunCMake/ObjectLibrary/OwnSources.cmake

@@ -0,0 +1,2 @@
+add_library(A OBJECT a.c)
+target_sources(A PRIVATE $<TARGET_OBJECTS:A>)

+ 1 - 0
Tests/RunCMake/ObjectLibrary/RunCMakeTest.cmake

@@ -19,6 +19,7 @@ run_cmake(LinkObjRHS1)
 run_cmake(LinkObjRHS2)
 run_cmake(MissingSource)
 run_cmake(ObjWithObj)
+run_cmake(OwnSources)
 run_cmake(PostBuild)
 run_cmake(PreBuild)
 run_cmake(PreLink)