1
0
Эх сурвалжийг харах

Merge topic 'find-cps-components'

894f256a12 find_package: Find CPS components
ac20cd43c0 find_package: Fix reporting of transitive dependency errors

Acked-by: Kitware Robot <[email protected]>
Merge-request: !10262
Brad King 9 сар өмнө
parent
commit
0c5898558e
34 өөрчлөгдсөн 492 нэмэгдсэн , 42 устгасан
  1. 3 3
      Help/command/find_package.rst
  2. 103 36
      Source/cmFindPackageCommand.cxx
  3. 11 3
      Source/cmFindPackageCommand.h
  4. 12 0
      Source/cmPackageInfoReader.cxx
  5. 1 0
      Source/cmPackageInfoReader.h
  6. 46 0
      Tests/FindPackageCpsTest/CMakeLists.txt
  7. 12 0
      Tests/FindPackageCpsTest/cps/ComponentTest-extra1.cps
  8. 12 0
      Tests/FindPackageCpsTest/cps/ComponentTest-extra2.cps
  9. 15 0
      Tests/FindPackageCpsTest/cps/ComponentTest-extra3.cps
  10. 9 0
      Tests/FindPackageCpsTest/cps/ComponentTest-extra4.cps
  11. 10 0
      Tests/FindPackageCpsTest/cps/ComponentTest.cps
  12. 12 0
      Tests/FindPackageCpsTest/cps/TransitiveDep-extra1.cps
  13. 9 0
      Tests/FindPackageCpsTest/cps/TransitiveDep-extra2.cps
  14. 12 0
      Tests/FindPackageCpsTest/cps/TransitiveDep-extra3.cps
  15. 10 0
      Tests/FindPackageCpsTest/cps/TransitiveDep.cps
  16. 11 0
      Tests/FindPackageCpsTest/cps/TransitiveTest.cps
  17. 1 0
      Tests/RunCMake/find_package/MissingComponent-result.txt
  18. 11 0
      Tests/RunCMake/find_package/MissingComponent-stderr.txt
  19. 19 0
      Tests/RunCMake/find_package/MissingComponent.cmake
  20. 1 0
      Tests/RunCMake/find_package/MissingComponentDependency-result.txt
  21. 22 0
      Tests/RunCMake/find_package/MissingComponentDependency-stderr.txt
  22. 19 0
      Tests/RunCMake/find_package/MissingComponentDependency.cmake
  23. 1 0
      Tests/RunCMake/find_package/MissingTransitiveComponent-result.txt
  24. 17 0
      Tests/RunCMake/find_package/MissingTransitiveComponent-stderr.txt
  25. 19 0
      Tests/RunCMake/find_package/MissingTransitiveComponent.cmake
  26. 1 0
      Tests/RunCMake/find_package/MissingTransitiveComponentDependency-result.txt
  27. 24 0
      Tests/RunCMake/find_package/MissingTransitiveComponentDependency-stderr.txt
  28. 20 0
      Tests/RunCMake/find_package/MissingTransitiveComponentDependency.cmake
  29. 5 0
      Tests/RunCMake/find_package/MissingTransitiveDependency-stderr.txt
  30. 4 0
      Tests/RunCMake/find_package/RunCMakeTest.cmake
  31. 12 0
      Tests/RunCMake/find_package/cps/componenttest-extra.cps
  32. 6 0
      Tests/RunCMake/find_package/cps/componenttest.cps
  33. 11 0
      Tests/RunCMake/find_package/cps/transitiveincomplete.cps
  34. 11 0
      Tests/RunCMake/find_package/cps/transitivemissing.cps

+ 3 - 3
Help/command/find_package.rst

@@ -88,9 +88,9 @@ The command has a few modes by which it searches for packages:
     mode", "package configuration files", and so forth refer equally to both
     CPS and CMake-script files.  However, some features of ``find_package``
     are not supported at this time when a CPS file is found.  In particular,
-    no attempt to validate whether a candidate ``.cps`` file matches
-    ``VERSION`` or ``COMPONENTS`` requirements is performed at this time.
-    (We expect to implement these features in the near future.)
+    if a ``VERSION`` requirement is specified, only ``.cps`` files which do not
+    provide version information will be rejected.  (We expect to implement
+    proper version validation in the near future.)
 
     Search is implemented in a manner that will tend to prefer |CPS| files
     over CMake-script config files in most cases.  Specifying ``CONFIGS``

+ 103 - 36
Source/cmFindPackageCommand.cxx

@@ -1846,7 +1846,7 @@ bool cmFindPackageCommand::FindEnvironmentConfig()
 }
 
 cmFindPackageCommand::AppendixMap cmFindPackageCommand::FindAppendices(
-  std::string const& base) const
+  std::string const& base, cmPackageInfoReader const& baseReader) const
 {
   AppendixMap appendices;
 
@@ -1865,9 +1865,11 @@ cmFindPackageCommand::AppendixMap cmFindPackageCommand::FindAppendices(
       }
 
       std::unique_ptr<cmPackageInfoReader> reader =
-        cmPackageInfoReader::Read(extra, this->CpsReader.get());
+        cmPackageInfoReader::Read(extra, &baseReader);
       if (reader && reader->GetName() == this->Name) {
-        appendices.emplace(extra, std::move(reader));
+        std::vector<std::string> components = reader->GetComponentNames();
+        Appendix appendix{ std::move(reader), std::move(components) };
+        appendices.emplace(extra, std::move(appendix));
       }
     }
   }
@@ -1894,27 +1896,55 @@ bool cmFindPackageCommand::ReadListFile(std::string const& f,
 
 bool cmFindPackageCommand::ReadPackage()
 {
-  // Resolve any transitive dependencies.
+  // Resolve any transitive dependencies for the root file.
   if (!FindPackageDependencies(this->FileFound, *this->CpsReader,
                                this->Required)) {
     return false;
   }
 
+  auto const hasComponentsRequested =
+    !this->RequiredComponents.empty() || !this->OptionalComponents.empty();
+
   cmMakefile::CallRAII scope{ this->Makefile, this->FileFound, this->Status };
 
-  // Locate appendices.
-  cmFindPackageCommand::AppendixMap appendices =
-    this->FindAppendices(this->FileFound);
+  // Loop over appendices.
+  auto iter = this->CpsAppendices.begin();
+  while (iter != this->CpsAppendices.end()) {
+    bool required = false;
+    bool important = false;
+
+    // Check if this appendix provides any requested components.
+    if (hasComponentsRequested) {
+      auto providesAny = [&iter](
+                           std::set<std::string> const& desiredComponents) {
+        return std::any_of(iter->second.Components.begin(),
+                           iter->second.Components.end(),
+                           [&desiredComponents](std::string const& component) {
+                             return cm::contains(desiredComponents, component);
+                           });
+      };
+
+      if (providesAny(this->RequiredComponents)) {
+        important = true;
+        required = this->Required;
+      } else if (!providesAny(this->OptionalComponents)) {
+        // This appendix doesn't provide any requested components; remove it
+        // from the set to be imported.
+        iter = this->CpsAppendices.erase(iter);
+        continue;
+      }
+    }
 
-  auto iter = appendices.begin();
-  while (iter != appendices.end()) {
-    bool providesRequiredComponents = false; // TODO
-    bool required = providesRequiredComponents && this->Required;
-    if (!this->FindPackageDependencies(iter->first, *iter->second, required)) {
-      if (providesRequiredComponents) {
+    // Resolve any transitive dependencies for the appendix.
+    if (!this->FindPackageDependencies(iter->first, iter->second, required)) {
+      if (important) {
+        // Some dependencies are missing, and we need(ed) this appendix; fail.
         return false;
       }
-      iter = appendices.erase(iter);
+
+      // Some dependencies are missing, but we don't need this appendix; remove
+      // it from the set to be imported.
+      iter = this->CpsAppendices.erase(iter);
     } else {
       ++iter;
     }
@@ -1926,10 +1956,11 @@ bool cmFindPackageCommand::ReadPackage()
   }
 
   // Import targets from appendices.
-  for (auto const& appendix : appendices) {
+  // NOLINTNEXTLINE(readability-use-anyofallof)
+  for (auto const& appendix : this->CpsAppendices) {
     cmMakefile::CallRAII appendixScope{ this->Makefile, appendix.first,
                                         this->Status };
-    if (!this->ImportPackageTargets(appendix.first, *appendix.second)) {
+    if (!this->ImportPackageTargets(appendix.first, appendix.second)) {
       return false;
     }
   }
@@ -1969,6 +2000,8 @@ bool cmFindPackageCommand::FindPackageDependencies(
 
     // Try to find the requirement; fail if we can't.
     if (!fp.FindPackage() || fp.FileFound.empty()) {
+      this->SetError(cmStrCat("could not find "_s, dep.Name,
+                              ", required by "_s, this->Name, '.'));
       return false;
     }
   }
@@ -2687,29 +2720,63 @@ bool cmFindPackageCommand::CheckVersion(std::string const& config_file)
       cm::optional<std::string> cpsVersion = reader->GetVersion();
       if (cpsVersion) {
         // TODO: Implement version check for CPS
-        this->VersionFound = (version = std::move(*cpsVersion));
+        result = true;
+      } else {
+        result = this->Version.empty();
+      }
 
-        std::vector<unsigned> const& versionParts = reader->ParseVersion();
-        this->VersionFoundCount = static_cast<unsigned>(versionParts.size());
-        switch (this->VersionFoundCount) {
-          case 4:
-            this->VersionFoundTweak = versionParts[3];
-            CM_FALLTHROUGH;
-          case 3:
-            this->VersionFoundPatch = versionParts[2];
-            CM_FALLTHROUGH;
-          case 2:
-            this->VersionFoundMinor = versionParts[1];
-            CM_FALLTHROUGH;
-          case 1:
-            this->VersionFoundMajor = versionParts[0];
-            CM_FALLTHROUGH;
-          default:
-            break;
+      if (result) {
+        // Locate appendices.
+        cmFindPackageCommand::AppendixMap appendices =
+          this->FindAppendices(config_file, *reader);
+
+        // Collect available components.
+        std::set<std::string> allComponents;
+
+        std::vector<std::string> const& rootComponents =
+          reader->GetComponentNames();
+        allComponents.insert(rootComponents.begin(), rootComponents.end());
+
+        for (auto const& appendix : appendices) {
+          allComponents.insert(appendix.second.Components.begin(),
+                               appendix.second.Components.end());
+        }
+
+        // Verify that all required components are available.
+        std::vector<std::string> missingComponents;
+        std::set_difference(this->RequiredComponents.begin(),
+                            this->RequiredComponents.end(),
+                            allComponents.begin(), allComponents.end(),
+                            std::back_inserter(missingComponents));
+        if (!missingComponents.empty()) {
+          result = false;
         }
+
+        if (result && cpsVersion) {
+          this->VersionFound = (version = std::move(*cpsVersion));
+
+          std::vector<unsigned> const& versionParts = reader->ParseVersion();
+          this->VersionFoundCount = static_cast<unsigned>(versionParts.size());
+          switch (this->VersionFoundCount) {
+            case 4:
+              this->VersionFoundTweak = versionParts[3];
+              CM_FALLTHROUGH;
+            case 3:
+              this->VersionFoundPatch = versionParts[2];
+              CM_FALLTHROUGH;
+            case 2:
+              this->VersionFoundMinor = versionParts[1];
+              CM_FALLTHROUGH;
+            case 1:
+              this->VersionFoundMajor = versionParts[0];
+              CM_FALLTHROUGH;
+            default:
+              break;
+          }
+        }
+        this->CpsReader = std::move(reader);
+        this->CpsAppendices = std::move(appendices);
       }
-      this->CpsReader = std::move(reader);
-      result = true;
     }
   } else {
     // Get the filename without the .cmake extension.

+ 11 - 3
Source/cmFindPackageCommand.h

@@ -141,9 +141,16 @@ private:
   bool ReadListFile(std::string const& f, PolicyScopeRule psr);
   bool ReadPackage();
 
-  using AppendixMap =
-    std::map<std::string, std::unique_ptr<cmPackageInfoReader>>;
-  AppendixMap FindAppendices(std::string const& base) const;
+  struct Appendix
+  {
+    std::unique_ptr<cmPackageInfoReader> Reader;
+    std::vector<std::string> Components;
+
+    operator cmPackageInfoReader&() const { return *this->Reader; }
+  };
+  using AppendixMap = std::map<std::string, Appendix>;
+  AppendixMap FindAppendices(std::string const& base,
+                             cmPackageInfoReader const& baseReader) const;
   bool FindPackageDependencies(std::string const& fileName,
                                cmPackageInfoReader const& reader,
                                bool required);
@@ -299,6 +306,7 @@ private:
   std::vector<ConfigFileInfo> ConsideredConfigs;
 
   std::unique_ptr<cmPackageInfoReader> CpsReader;
+  AppendixMap CpsAppendices;
 
   friend struct std::hash<ConfigFileInfo>;
 };

+ 12 - 0
Source/cmPackageInfoReader.cxx

@@ -481,6 +481,18 @@ std::vector<cmPackageRequirement> cmPackageInfoReader::GetRequirements() const
   return requirements;
 }
 
+std::vector<std::string> cmPackageInfoReader::GetComponentNames() const
+{
+  std::vector<std::string> componentNames;
+
+  Json::Value const& components = this->Data["components"];
+  for (auto ci = components.begin(), ce = components.end(); ci != ce; ++ci) {
+    componentNames.emplace_back(ci.name());
+  }
+
+  return componentNames;
+}
+
 std::string cmPackageInfoReader::ResolvePath(std::string path) const
 {
   cmSystemTools::ConvertToUnixSlashes(path);

+ 1 - 0
Source/cmPackageInfoReader.h

@@ -50,6 +50,7 @@ public:
   std::vector<unsigned> ParseVersion() const;
 
   std::vector<cmPackageRequirement> GetRequirements() const;
+  std::vector<std::string> GetComponentNames() const;
 
   /// Create targets for components specified in the CPS file.
   bool ImportTargets(cmMakefile* makefile, cmExecutionStatus& status);

+ 46 - 0
Tests/FindPackageCpsTest/CMakeLists.txt

@@ -185,3 +185,49 @@ elseif(NOT TARGET Bar::Target1)
 elseif(NOT TARGET Bar::Target2)
   message(SEND_ERROR "Bar::Target2 missing !")
 endif()
+
+###############################################################################
+# Test requesting components from a package.
+
+find_package(ComponentTest
+  COMPONENTS Target1 Target2
+  OPTIONAL_COMPONENTS Target4 Target6)
+if(NOT ComponentTest_FOUND)
+  message(SEND_ERROR "ComponentTest not found !")
+elseif(NOT TARGET ComponentTest::Target1)
+  message(SEND_ERROR "ComponentTest::Target1 missing !")
+elseif(NOT TARGET ComponentTest::Target2)
+  message(SEND_ERROR "ComponentTest::Target2 missing !")
+elseif(NOT TARGET ComponentTest::Target3)
+  message(SEND_ERROR "ComponentTest::Target3 missing !")
+elseif(NOT TARGET ComponentTest::Target4)
+  message(SEND_ERROR "ComponentTest::Target4 missing !")
+elseif(NOT TARGET ComponentTest::Target5)
+  message(SEND_ERROR "ComponentTest::Target5 missing !")
+elseif(TARGET ComponentTest::Target6)
+  message(SEND_ERROR "ComponentTest::Target6 exists ?!")
+elseif(TARGET ComponentTest::Target7)
+  message(SEND_ERROR "ComponentTest::Target7 exists ?!")
+elseif(TARGET ComponentTest::Target8)
+  message(SEND_ERROR "ComponentTest::Target8 exists ?!")
+endif()
+
+###############################################################################
+# Test requesting components from a dependency.
+
+find_package(TransitiveTest)
+if(NOT TransitiveTest_FOUND)
+  message(SEND_ERROR "TransitiveTest not found !")
+elseif(NOT TransitiveDep_FOUND)
+  message(SEND_ERROR "TransitiveTest's TransitiveDep not found !")
+elseif(NOT TARGET TransitiveDep::Target1)
+  message(SEND_ERROR "TransitiveDep::Target1 missing !")
+elseif(NOT TARGET TransitiveDep::Target2)
+  message(SEND_ERROR "TransitiveDep::Target2 missing !")
+elseif(NOT TARGET TransitiveDep::Target3)
+  message(SEND_ERROR "TransitiveDep::Target3 missing !")
+elseif(TARGET TransitiveDep::Target4)
+  message(SEND_ERROR "TransitiveDep::Target4 exists ?!")
+elseif(TARGET TransitiveDep::Target5)
+  message(SEND_ERROR "TransitiveDep::Target5 exists ?!")
+endif()

+ 12 - 0
Tests/FindPackageCpsTest/cps/ComponentTest-extra1.cps

@@ -0,0 +1,12 @@
+{
+  "cps_version": "0.13",
+  "name": "ComponentTest",
+  "components": {
+    "Target2": {
+      "type": "interface"
+    },
+    "Target3": {
+      "type": "interface"
+    }
+  }
+}

+ 12 - 0
Tests/FindPackageCpsTest/cps/ComponentTest-extra2.cps

@@ -0,0 +1,12 @@
+{
+  "cps_version": "0.13",
+  "name": "ComponentTest",
+  "components": {
+    "Target4": {
+      "type": "interface"
+    },
+    "Target5": {
+      "type": "interface"
+    }
+  }
+}

+ 15 - 0
Tests/FindPackageCpsTest/cps/ComponentTest-extra3.cps

@@ -0,0 +1,15 @@
+{
+  "cps_version": "0.13",
+  "name": "ComponentTest",
+  "requires": {
+    "DoesNotExist": null
+  },
+  "components": {
+    "Target6": {
+      "type": "interface"
+    },
+    "Target7": {
+      "type": "interface"
+    }
+  }
+}

+ 9 - 0
Tests/FindPackageCpsTest/cps/ComponentTest-extra4.cps

@@ -0,0 +1,9 @@
+{
+  "cps_version": "0.13",
+  "name": "ComponentTest",
+  "components": {
+    "Target8": {
+      "type": "interface"
+    }
+  }
+}

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

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

+ 12 - 0
Tests/FindPackageCpsTest/cps/TransitiveDep-extra1.cps

@@ -0,0 +1,12 @@
+{
+  "cps_version": "0.13",
+  "name": "TransitiveDep",
+  "components": {
+    "Target2": {
+      "type": "interface"
+    },
+    "Target3": {
+      "type": "interface"
+    }
+  }
+}

+ 9 - 0
Tests/FindPackageCpsTest/cps/TransitiveDep-extra2.cps

@@ -0,0 +1,9 @@
+{
+  "cps_version": "0.13",
+  "name": "TransitiveDep",
+  "components": {
+    "Target4": {
+      "type": "interface"
+    }
+  }
+}

+ 12 - 0
Tests/FindPackageCpsTest/cps/TransitiveDep-extra3.cps

@@ -0,0 +1,12 @@
+{
+  "cps_version": "0.13",
+  "name": "ComponentTest",
+  "requires": {
+    "DoesNotExist": null
+  },
+  "components": {
+    "Target5": {
+      "type": "interface"
+    }
+  }
+}

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

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

+ 11 - 0
Tests/FindPackageCpsTest/cps/TransitiveTest.cps

@@ -0,0 +1,11 @@
+{
+  "cps_version": "0.13",
+  "name": "TransitiveTest",
+  "cps_path": "@prefix@/cps",
+  "requires": {
+    "TransitiveDep": {
+      "components": [ "Target2" ]
+    }
+  },
+  "components": {}
+}

+ 1 - 0
Tests/RunCMake/find_package/MissingComponent-result.txt

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

+ 11 - 0
Tests/RunCMake/find_package/MissingComponent-stderr.txt

@@ -0,0 +1,11 @@
+CMake Error at MissingComponent.cmake:[0-9]+ \(find_package\):
+  Could not find a configuration file for package "ComponentTest" that is
+  compatible with requested version ""\.
+
+  The following configuration files were considered but not accepted:
+(
+    [^
+]*/Tests/RunCMake/find_package/cps/[Cc]omponent[Tt]est\.cps, version: unknown)+
+
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)

+ 19 - 0
Tests/RunCMake/find_package/MissingComponent.cmake

@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.31)
+
+set(CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES "e82e467b-f997-4464-8ace-b00808fff261")
+
+# Protect tests from running inside the default install prefix.
+set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/NotDefaultPrefix")
+
+# Disable built-in search paths.
+set(CMAKE_FIND_USE_PACKAGE_ROOT_PATH OFF)
+set(CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH OFF)
+set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH OFF)
+set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH OFF)
+set(CMAKE_FIND_USE_INSTALL_PREFIX OFF)
+
+set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+###############################################################################
+# Test requesting unavailable components from a package.
+find_package(ComponentTest REQUIRED COMPONENTS DoesNotExist)

+ 1 - 0
Tests/RunCMake/find_package/MissingComponentDependency-result.txt

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

+ 22 - 0
Tests/RunCMake/find_package/MissingComponentDependency-stderr.txt

@@ -0,0 +1,22 @@
+CMake Error in cps/componenttest-extra\.cps:
+  Could not find a package configuration file provided by "DoesNotExist" with
+  any of the following names:
+
+    DoesNotExist\.cps
+    doesnotexist\.cps
+    DoesNotExistConfig\.cmake
+    doesnotexist-config\.cmake
+
+  Add the installation prefix of "DoesNotExist" to CMAKE_PREFIX_PATH or set
+  "DoesNotExist_DIR" to a directory containing one of the above files\.  If
+  "DoesNotExist" provides a separate development package or SDK, be sure it
+  has been installed\.
+Call Stack \(most recent call first\):
+  cps/[Cc]omponent[Tt]est\.cps
+  MissingComponentDependency\.cmake:[0-9]+ \(find_package\)
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at MissingComponentDependency.cmake:[0-9]+ \(find_package\):
+  find_package could not find DoesNotExist, required by ComponentTest\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)

+ 19 - 0
Tests/RunCMake/find_package/MissingComponentDependency.cmake

@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.31)
+
+set(CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES "e82e467b-f997-4464-8ace-b00808fff261")
+
+# Protect tests from running inside the default install prefix.
+set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/NotDefaultPrefix")
+
+# Disable built-in search paths.
+set(CMAKE_FIND_USE_PACKAGE_ROOT_PATH OFF)
+set(CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH OFF)
+set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH OFF)
+set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH OFF)
+set(CMAKE_FIND_USE_INSTALL_PREFIX OFF)
+
+set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+###############################################################################
+# Test requesting components with missing dependencies from a package.
+find_package(ComponentTest REQUIRED COMPONENTS Incomplete)

+ 1 - 0
Tests/RunCMake/find_package/MissingTransitiveComponent-result.txt

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

+ 17 - 0
Tests/RunCMake/find_package/MissingTransitiveComponent-stderr.txt

@@ -0,0 +1,17 @@
+CMake Error in cps/[Tt]ransitive[Mm]issing\.cps:
+  Could not find a configuration file for package "ComponentTest" that is
+  compatible with requested version ""\.
+
+  The following configuration files were considered but not accepted:
+(
+    [^
+]*/Tests/RunCMake/find_package/cps/[Cc]omponent[Tt]est\.cps, version: unknown)+
+
+Call Stack \(most recent call first\):
+  MissingTransitiveComponent\.cmake:[0-9]+ \(find_package\)
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at MissingTransitiveComponent\.cmake:[0-9]+ \(find_package\):
+  find_package could not find ComponentTest, required by TransitiveMissing\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)

+ 19 - 0
Tests/RunCMake/find_package/MissingTransitiveComponent.cmake

@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.31)
+
+set(CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES "e82e467b-f997-4464-8ace-b00808fff261")
+
+# Protect tests from running inside the default install prefix.
+set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/NotDefaultPrefix")
+
+# Disable built-in search paths.
+set(CMAKE_FIND_USE_PACKAGE_ROOT_PATH OFF)
+set(CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH OFF)
+set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH OFF)
+set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH OFF)
+set(CMAKE_FIND_USE_INSTALL_PREFIX OFF)
+
+set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+###############################################################################
+# Test depending on components of another package which are unavailable.
+find_package(TransitiveMissing REQUIRED)

+ 1 - 0
Tests/RunCMake/find_package/MissingTransitiveComponentDependency-result.txt

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

+ 24 - 0
Tests/RunCMake/find_package/MissingTransitiveComponentDependency-stderr.txt

@@ -0,0 +1,24 @@
+CMake Error in cps/componenttest-extra\.cps:
+  Could not find a package configuration file provided by "DoesNotExist" with
+  any of the following names:
+
+    DoesNotExist\.cps
+    doesnotexist\.cps
+    DoesNotExistConfig\.cmake
+    doesnotexist-config\.cmake
+
+  Add the installation prefix of "DoesNotExist" to CMAKE_PREFIX_PATH or set
+  "DoesNotExist_DIR" to a directory containing one of the above files\.  If
+  "DoesNotExist" provides a separate development package or SDK, be sure it
+  has been installed\.
+Call Stack \(most recent call first\):
+  cps/[Cc]omponent[Tt]est\.cps
+  cps/[Tt]ransitive[Ii]ncomplete\.cps
+  MissingTransitiveComponentDependency\.cmake:[0-9]+ \(find_package\)
+  CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at MissingTransitiveComponentDependency\.cmake:[0-9]+ \(find_package\):
+  find_package could not find ComponentTest, required by
+  TransitiveIncomplete\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)

+ 20 - 0
Tests/RunCMake/find_package/MissingTransitiveComponentDependency.cmake

@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.31)
+
+set(CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES "e82e467b-f997-4464-8ace-b00808fff261")
+
+# Protect tests from running inside the default install prefix.
+set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/NotDefaultPrefix")
+
+# Disable built-in search paths.
+set(CMAKE_FIND_USE_PACKAGE_ROOT_PATH OFF)
+set(CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH OFF)
+set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH OFF)
+set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH OFF)
+set(CMAKE_FIND_USE_INSTALL_PREFIX OFF)
+
+set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+###############################################################################
+# Test depending on components of another package which are missing
+# dependencies.
+find_package(TransitiveIncomplete REQUIRED)

+ 5 - 0
Tests/RunCMake/find_package/MissingTransitiveDependency-stderr.txt

@@ -23,3 +23,8 @@ Call Stack \(most recent call first\):
   cps/[Ii]ncomplete\.cps
   MissingTransitiveDependency\.cmake:[0-9]+ \(find_package\)
   CMakeLists\.txt:[0-9]+ \(include\)
++
+CMake Error at MissingTransitiveDependency\.cmake:[0-9]+ \(find_package\):
+  find_package could not find StillIncomplete, required by Incomplete\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)

+ 4 - 0
Tests/RunCMake/find_package/RunCMakeTest.cmake

@@ -23,6 +23,10 @@ run_cmake(MissingConfigOneName)
 run_cmake(MissingConfigRequired)
 run_cmake(MissingConfigVersion)
 run_cmake(MissingTransitiveDependency)
+run_cmake(MissingComponent)
+run_cmake(MissingComponentDependency)
+run_cmake(MissingTransitiveComponent)
+run_cmake(MissingTransitiveComponentDependency)
 run_cmake(MixedModeOptions)
 run_cmake_with_options(ModuleModeDebugPkg --debug-find-pkg=Foo,Zot)
 run_cmake(PackageRoot)

+ 12 - 0
Tests/RunCMake/find_package/cps/componenttest-extra.cps

@@ -0,0 +1,12 @@
+{
+  "cps_version": "0.13",
+  "name": "ComponentTest",
+  "requires": {
+    "DoesNotExist": null
+  },
+  "components": {
+    "Incomplete": {
+      "type": "interface"
+    }
+  }
+}

+ 6 - 0
Tests/RunCMake/find_package/cps/componenttest.cps

@@ -0,0 +1,6 @@
+{
+  "cps_version": "0.13",
+  "name": "ComponentTest",
+  "cps_path": "@prefix@/cps",
+  "components": {}
+}

+ 11 - 0
Tests/RunCMake/find_package/cps/transitiveincomplete.cps

@@ -0,0 +1,11 @@
+{
+  "cps_version": "0.13",
+  "name": "TransitiveIncomplete",
+  "cps_path": "@prefix@/cps",
+  "requires": {
+    "ComponentTest": {
+      "components": [ "Incomplete" ]
+    }
+  },
+  "components": {}
+}

+ 11 - 0
Tests/RunCMake/find_package/cps/transitivemissing.cps

@@ -0,0 +1,11 @@
+{
+  "cps_version": "0.13",
+  "name": "TransitiveMissing",
+  "cps_path": "@prefix@/cps",
+  "requires": {
+    "ComponentTest": {
+      "components": [ "DoesNotExist" ]
+    }
+  },
+  "components": {}
+}