Browse Source

find_package: Add minimal support for CPS multiple inclusion

Do not try to load a CPS file if we've already loaded the same file.
This only works if the current `find_package` call selects the same file
as the previous most recent call, and if the user has not meddled with
the `<name>_CONFIG` variable.

Issue: #26731
Matthew Woehlke 8 months ago
parent
commit
b498611902

+ 10 - 2
Source/cmFindPackageCommand.cxx

@@ -1522,6 +1522,7 @@ bool cmFindPackageCommand::HandlePackageMode(
     }
   }
 
+  std::string const fileVar = cmStrCat(this->Name, "_CONFIG");
   std::string const foundVar = cmStrCat(this->Name, "_FOUND");
   std::string const notFoundMessageVar =
     cmStrCat(this->Name, "_NOT_FOUND_MESSAGE");
@@ -1552,7 +1553,15 @@ bool cmFindPackageCommand::HandlePackageMode(
     if (this->CpsReader) {
       // The package has been found.
       found = true;
-      result = this->ReadPackage();
+
+      // Don't read a CPS file if we've already read it.
+      cmValue const& previousFileFound =
+        this->Makefile->GetDefinition(fileVar);
+      if (previousFileFound.Compare(this->FileFound) == 0) {
+        result = true;
+      } else {
+        result = this->ReadPackage();
+      }
     } else if (this->ReadListFile(this->FileFound, DoPolicyScope)) {
       // The package has been found.
       found = true;
@@ -1725,7 +1734,6 @@ bool cmFindPackageCommand::HandlePackageMode(
   this->Makefile->AddDefinition(foundVar, found ? "1" : "0");
 
   // Set a variable naming the configuration file that was found.
-  std::string const fileVar = cmStrCat(this->Name, "_CONFIG");
   if (found) {
     this->Makefile->AddDefinition(fileVar, this->FileFound);
   } else {

+ 6 - 0
Tests/FindPackageCpsTest/CMakeLists.txt

@@ -54,6 +54,12 @@ endfunction()
 find_package(Sample CONFIG)
 test_version(Sample "2.10.11" 3 2 10 11 0)
 
+###############################################################################
+# Test finding a package more than once.
+
+find_package(Repeat REQUIRED)
+find_package(Repeat REQUIRED)
+
 ###############################################################################
 # Test some more complicated version parsing.
 

+ 10 - 0
Tests/FindPackageCpsTest/cps/Repeat.cps

@@ -0,0 +1,10 @@
+{
+  "cps_version": "0.13",
+  "name": "Repeat",
+  "cps_path": "@prefix@/cps",
+  "components": {
+    "Repeat": {
+      "type": "interface"
+    }
+  }
+}