Przeglądaj źródła

Merge topic 'safe-target-file-import'

bf2ddce Generate an early-return guard in target Export files.
David Cole 13 lat temu
rodzic
commit
8a581696ef

+ 14 - 0
Source/cmExportBuildFileGenerator.cxx

@@ -22,6 +22,20 @@ cmExportBuildFileGenerator::cmExportBuildFileGenerator()
 //----------------------------------------------------------------------------
 bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
 {
+  {
+  std::string expectedTargets;
+  std::string sep;
+  for(std::vector<cmTarget*>::const_iterator
+        tei = this->Exports->begin();
+      tei != this->Exports->end(); ++tei)
+    {
+    expectedTargets += sep + this->Namespace + (*tei)->GetName();
+    sep = " ";
+    }
+
+  this->GenerateExpectedTargetsCode(os, expectedTargets);
+  }
+
   // Create all the imported targets.
   for(std::vector<cmTarget*>::const_iterator
         tei = this->Exports->begin();

+ 31 - 0
Source/cmExportFileGenerator.cxx

@@ -286,6 +286,37 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os)
      << "\n";
 }
 
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::GenerateExpectedTargetsCode(std::ostream& os,
+                                            const std::string &expectedTargets)
+{
+  os << "SET(_targetsDefined)\n"
+        "SET(_targetsNotDefined)\n"
+        "SET(_expectedTargets)\n"
+        "FOREACH(_expectedTarget " << expectedTargets << ")\n"
+        "  LIST(APPEND _expectedTargets ${_expectedTarget})\n"
+        "  IF(NOT TARGET ${_expectedTarget})\n"
+        "    LIST(APPEND _targetsNotDefined ${_expectedTarget})\n"
+        "  ENDIF(NOT TARGET ${_expectedTarget})\n"
+        "  IF(TARGET ${_expectedTarget})\n"
+        "    LIST(APPEND _targetsDefined ${_expectedTarget})\n"
+        "  ENDIF(TARGET ${_expectedTarget})\n"
+        "ENDFOREACH(_expectedTarget)\n"
+        "IF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
+        "  SET(CMAKE_IMPORT_FILE_VERSION)\n"
+        "  CMAKE_POLICY(POP)\n"
+        "  RETURN()\n"
+        "ENDIF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
+        "IF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
+        "  MESSAGE(FATAL_ERROR \"Some (but not all) targets in this export "
+        "set were already defined.\\nTargets Defined: ${_targetsDefined}\\n"
+        "Targets not yet defined: ${_targetsNotDefined}\\n\")\n"
+        "ENDIF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
+        "UNSET(_targetsDefined)\n"
+        "UNSET(_targetsNotDefined)\n"
+        "UNSET(_expectedTargets)\n"
+        "\n\n";
+}
 //----------------------------------------------------------------------------
 void
 cmExportFileGenerator

+ 2 - 0
Source/cmExportFileGenerator.h

@@ -63,6 +63,8 @@ protected:
   void GenerateMissingTargetsCheckCode(std::ostream& os,
                                const std::vector<std::string>& missingTargets);
 
+  void GenerateExpectedTargetsCode(std::ostream& os,
+                                          const std::string &expectedTargets);
 
   // Collect properties with detailed information about targets beyond
   // their location on disk.

+ 14 - 0
Source/cmExportInstallFileGenerator.cxx

@@ -39,6 +39,20 @@ std::string cmExportInstallFileGenerator::GetConfigImportFileGlob()
 //----------------------------------------------------------------------------
 bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
 {
+  {
+  std::string expectedTargets;
+  std::string sep;
+  for(std::vector<cmTargetExport*>::const_iterator
+        tei = this->IEGen->GetExportSet()->GetTargetExports()->begin();
+      tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei)
+    {
+    expectedTargets += sep + this->Namespace + (*tei)->Target->GetName();
+    sep = " ";
+    }
+
+  this->GenerateExpectedTargetsCode(os, expectedTargets);
+  }
+
   // Create all the imported targets.
   for(std::vector<cmTargetExport*>::const_iterator
         tei = this->IEGen->GetExportSet()->GetTargetExports()->begin();