From 894f256a12605eb0ca0f8aa982241438e07c01e5 Mon Sep 17 00:00:00 2001 From: Matthew Woehlke Date: Thu, 30 Jan 2025 14:12:27 -0500 Subject: find_package: Find CPS components Implement finding components of CPS packages. Specifically, reject any candidate packages that don't provide all required components, and ignore appendices that don't provide requested (required or optional) components. This applies to both top-level searches and also searching for package dependencies. --- Help/command/find_package.rst | 6 +- Source/cmFindPackageCommand.cxx | 137 +++++++++++++++------ Source/cmFindPackageCommand.h | 14 ++- Source/cmPackageInfoReader.cxx | 12 ++ Source/cmPackageInfoReader.h | 1 + Tests/FindPackageCpsTest/CMakeLists.txt | 46 +++++++ .../cps/ComponentTest-extra1.cps | 12 ++ .../cps/ComponentTest-extra2.cps | 12 ++ .../cps/ComponentTest-extra3.cps | 15 +++ .../cps/ComponentTest-extra4.cps | 9 ++ Tests/FindPackageCpsTest/cps/ComponentTest.cps | 10 ++ .../cps/TransitiveDep-extra1.cps | 12 ++ .../cps/TransitiveDep-extra2.cps | 9 ++ .../cps/TransitiveDep-extra3.cps | 12 ++ Tests/FindPackageCpsTest/cps/TransitiveDep.cps | 10 ++ Tests/FindPackageCpsTest/cps/TransitiveTest.cps | 11 ++ .../find_package/MissingComponent-result.txt | 1 + .../find_package/MissingComponent-stderr.txt | 11 ++ Tests/RunCMake/find_package/MissingComponent.cmake | 19 +++ .../MissingComponentDependency-result.txt | 1 + .../MissingComponentDependency-stderr.txt | 22 ++++ .../find_package/MissingComponentDependency.cmake | 19 +++ .../MissingTransitiveComponent-result.txt | 1 + .../MissingTransitiveComponent-stderr.txt | 17 +++ .../find_package/MissingTransitiveComponent.cmake | 19 +++ ...MissingTransitiveComponentDependency-result.txt | 1 + ...MissingTransitiveComponentDependency-stderr.txt | 24 ++++ .../MissingTransitiveComponentDependency.cmake | 20 +++ Tests/RunCMake/find_package/RunCMakeTest.cmake | 4 + .../find_package/cps/componenttest-extra.cps | 12 ++ Tests/RunCMake/find_package/cps/componenttest.cps | 6 + .../find_package/cps/transitiveincomplete.cps | 11 ++ .../find_package/cps/transitivemissing.cps | 11 ++ 33 files changed, 485 insertions(+), 42 deletions(-) create mode 100644 Tests/FindPackageCpsTest/cps/ComponentTest-extra1.cps create mode 100644 Tests/FindPackageCpsTest/cps/ComponentTest-extra2.cps create mode 100644 Tests/FindPackageCpsTest/cps/ComponentTest-extra3.cps create mode 100644 Tests/FindPackageCpsTest/cps/ComponentTest-extra4.cps create mode 100644 Tests/FindPackageCpsTest/cps/ComponentTest.cps create mode 100644 Tests/FindPackageCpsTest/cps/TransitiveDep-extra1.cps create mode 100644 Tests/FindPackageCpsTest/cps/TransitiveDep-extra2.cps create mode 100644 Tests/FindPackageCpsTest/cps/TransitiveDep-extra3.cps create mode 100644 Tests/FindPackageCpsTest/cps/TransitiveDep.cps create mode 100644 Tests/FindPackageCpsTest/cps/TransitiveTest.cps create mode 100644 Tests/RunCMake/find_package/MissingComponent-result.txt create mode 100644 Tests/RunCMake/find_package/MissingComponent-stderr.txt create mode 100644 Tests/RunCMake/find_package/MissingComponent.cmake create mode 100644 Tests/RunCMake/find_package/MissingComponentDependency-result.txt create mode 100644 Tests/RunCMake/find_package/MissingComponentDependency-stderr.txt create mode 100644 Tests/RunCMake/find_package/MissingComponentDependency.cmake create mode 100644 Tests/RunCMake/find_package/MissingTransitiveComponent-result.txt create mode 100644 Tests/RunCMake/find_package/MissingTransitiveComponent-stderr.txt create mode 100644 Tests/RunCMake/find_package/MissingTransitiveComponent.cmake create mode 100644 Tests/RunCMake/find_package/MissingTransitiveComponentDependency-result.txt create mode 100644 Tests/RunCMake/find_package/MissingTransitiveComponentDependency-stderr.txt create mode 100644 Tests/RunCMake/find_package/MissingTransitiveComponentDependency.cmake create mode 100644 Tests/RunCMake/find_package/cps/componenttest-extra.cps create mode 100644 Tests/RunCMake/find_package/cps/componenttest.cps create mode 100644 Tests/RunCMake/find_package/cps/transitiveincomplete.cps create mode 100644 Tests/RunCMake/find_package/cps/transitivemissing.cps diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst index 6ad5202..98d0b00 100644 --- a/Help/command/find_package.rst +++ b/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`` diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 62e70ea..cd1938e 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/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 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 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 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; } } @@ -2689,29 +2720,63 @@ bool cmFindPackageCommand::CheckVersion(std::string const& config_file) cm::optional 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 const& versionParts = reader->ParseVersion(); - this->VersionFoundCount = static_cast(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 allComponents; + + std::vector 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 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 const& versionParts = reader->ParseVersion(); + this->VersionFoundCount = static_cast(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. diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index 4ced5d3..75a4243 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -141,9 +141,16 @@ private: bool ReadListFile(std::string const& f, PolicyScopeRule psr); bool ReadPackage(); - using AppendixMap = - std::map>; - AppendixMap FindAppendices(std::string const& base) const; + struct Appendix + { + std::unique_ptr Reader; + std::vector Components; + + operator cmPackageInfoReader&() const { return *this->Reader; } + }; + using AppendixMap = std::map; + 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 ConsideredConfigs; std::unique_ptr CpsReader; + AppendixMap CpsAppendices; friend struct std::hash; }; diff --git a/Source/cmPackageInfoReader.cxx b/Source/cmPackageInfoReader.cxx index ceefb6f..a5349ca 100644 --- a/Source/cmPackageInfoReader.cxx +++ b/Source/cmPackageInfoReader.cxx @@ -481,6 +481,18 @@ std::vector cmPackageInfoReader::GetRequirements() const return requirements; } +std::vector cmPackageInfoReader::GetComponentNames() const +{ + std::vector 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); diff --git a/Source/cmPackageInfoReader.h b/Source/cmPackageInfoReader.h index bcecd0e..d31cee9 100644 --- a/Source/cmPackageInfoReader.h +++ b/Source/cmPackageInfoReader.h @@ -50,6 +50,7 @@ public: std::vector ParseVersion() const; std::vector GetRequirements() const; + std::vector GetComponentNames() const; /// Create targets for components specified in the CPS file. bool ImportTargets(cmMakefile* makefile, cmExecutionStatus& status); diff --git a/Tests/FindPackageCpsTest/CMakeLists.txt b/Tests/FindPackageCpsTest/CMakeLists.txt index 19f1bf3..58de268 100644 --- a/Tests/FindPackageCpsTest/CMakeLists.txt +++ b/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() diff --git a/Tests/FindPackageCpsTest/cps/ComponentTest-extra1.cps b/Tests/FindPackageCpsTest/cps/ComponentTest-extra1.cps new file mode 100644 index 0000000..267ee49 --- /dev/null +++ b/Tests/FindPackageCpsTest/cps/ComponentTest-extra1.cps @@ -0,0 +1,12 @@ +{ + "cps_version": "0.13", + "name": "ComponentTest", + "components": { + "Target2": { + "type": "interface" + }, + "Target3": { + "type": "interface" + } + } +} diff --git a/Tests/FindPackageCpsTest/cps/ComponentTest-extra2.cps b/Tests/FindPackageCpsTest/cps/ComponentTest-extra2.cps new file mode 100644 index 0000000..a1072c8 --- /dev/null +++ b/Tests/FindPackageCpsTest/cps/ComponentTest-extra2.cps @@ -0,0 +1,12 @@ +{ + "cps_version": "0.13", + "name": "ComponentTest", + "components": { + "Target4": { + "type": "interface" + }, + "Target5": { + "type": "interface" + } + } +} diff --git a/Tests/FindPackageCpsTest/cps/ComponentTest-extra3.cps b/Tests/FindPackageCpsTest/cps/ComponentTest-extra3.cps new file mode 100644 index 0000000..683911f --- /dev/null +++ b/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" + } + } +} diff --git a/Tests/FindPackageCpsTest/cps/ComponentTest-extra4.cps b/Tests/FindPackageCpsTest/cps/ComponentTest-extra4.cps new file mode 100644 index 0000000..badd41a --- /dev/null +++ b/Tests/FindPackageCpsTest/cps/ComponentTest-extra4.cps @@ -0,0 +1,9 @@ +{ + "cps_version": "0.13", + "name": "ComponentTest", + "components": { + "Target8": { + "type": "interface" + } + } +} diff --git a/Tests/FindPackageCpsTest/cps/ComponentTest.cps b/Tests/FindPackageCpsTest/cps/ComponentTest.cps new file mode 100644 index 0000000..763d60e --- /dev/null +++ b/Tests/FindPackageCpsTest/cps/ComponentTest.cps @@ -0,0 +1,10 @@ +{ + "cps_version": "0.13", + "name": "ComponentTest", + "cps_path": "@prefix@/cps", + "components": { + "Target1": { + "type": "interface" + } + } +} diff --git a/Tests/FindPackageCpsTest/cps/TransitiveDep-extra1.cps b/Tests/FindPackageCpsTest/cps/TransitiveDep-extra1.cps new file mode 100644 index 0000000..312a804 --- /dev/null +++ b/Tests/FindPackageCpsTest/cps/TransitiveDep-extra1.cps @@ -0,0 +1,12 @@ +{ + "cps_version": "0.13", + "name": "TransitiveDep", + "components": { + "Target2": { + "type": "interface" + }, + "Target3": { + "type": "interface" + } + } +} diff --git a/Tests/FindPackageCpsTest/cps/TransitiveDep-extra2.cps b/Tests/FindPackageCpsTest/cps/TransitiveDep-extra2.cps new file mode 100644 index 0000000..b1dd4bd --- /dev/null +++ b/Tests/FindPackageCpsTest/cps/TransitiveDep-extra2.cps @@ -0,0 +1,9 @@ +{ + "cps_version": "0.13", + "name": "TransitiveDep", + "components": { + "Target4": { + "type": "interface" + } + } +} diff --git a/Tests/FindPackageCpsTest/cps/TransitiveDep-extra3.cps b/Tests/FindPackageCpsTest/cps/TransitiveDep-extra3.cps new file mode 100644 index 0000000..6c307ba --- /dev/null +++ b/Tests/FindPackageCpsTest/cps/TransitiveDep-extra3.cps @@ -0,0 +1,12 @@ +{ + "cps_version": "0.13", + "name": "ComponentTest", + "requires": { + "DoesNotExist": null + }, + "components": { + "Target5": { + "type": "interface" + } + } +} diff --git a/Tests/FindPackageCpsTest/cps/TransitiveDep.cps b/Tests/FindPackageCpsTest/cps/TransitiveDep.cps new file mode 100644 index 0000000..1af27bb --- /dev/null +++ b/Tests/FindPackageCpsTest/cps/TransitiveDep.cps @@ -0,0 +1,10 @@ +{ + "cps_version": "0.13", + "name": "TransitiveDep", + "cps_path": "@prefix@/cps", + "components": { + "Target1": { + "type": "interface" + } + } +} diff --git a/Tests/FindPackageCpsTest/cps/TransitiveTest.cps b/Tests/FindPackageCpsTest/cps/TransitiveTest.cps new file mode 100644 index 0000000..4c5e31e --- /dev/null +++ b/Tests/FindPackageCpsTest/cps/TransitiveTest.cps @@ -0,0 +1,11 @@ +{ + "cps_version": "0.13", + "name": "TransitiveTest", + "cps_path": "@prefix@/cps", + "requires": { + "TransitiveDep": { + "components": [ "Target2" ] + } + }, + "components": {} +} diff --git a/Tests/RunCMake/find_package/MissingComponent-result.txt b/Tests/RunCMake/find_package/MissingComponent-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/find_package/MissingComponent-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_package/MissingComponent-stderr.txt b/Tests/RunCMake/find_package/MissingComponent-stderr.txt new file mode 100644 index 0000000..3386c30 --- /dev/null +++ b/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\) diff --git a/Tests/RunCMake/find_package/MissingComponent.cmake b/Tests/RunCMake/find_package/MissingComponent.cmake new file mode 100644 index 0000000..215b131 --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/find_package/MissingComponentDependency-result.txt b/Tests/RunCMake/find_package/MissingComponentDependency-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/find_package/MissingComponentDependency-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_package/MissingComponentDependency-stderr.txt b/Tests/RunCMake/find_package/MissingComponentDependency-stderr.txt new file mode 100644 index 0000000..939a094 --- /dev/null +++ b/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\) diff --git a/Tests/RunCMake/find_package/MissingComponentDependency.cmake b/Tests/RunCMake/find_package/MissingComponentDependency.cmake new file mode 100644 index 0000000..576debf --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/find_package/MissingTransitiveComponent-result.txt b/Tests/RunCMake/find_package/MissingTransitiveComponent-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/find_package/MissingTransitiveComponent-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_package/MissingTransitiveComponent-stderr.txt b/Tests/RunCMake/find_package/MissingTransitiveComponent-stderr.txt new file mode 100644 index 0000000..fea5855 --- /dev/null +++ b/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\) diff --git a/Tests/RunCMake/find_package/MissingTransitiveComponent.cmake b/Tests/RunCMake/find_package/MissingTransitiveComponent.cmake new file mode 100644 index 0000000..d0b623b --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/find_package/MissingTransitiveComponentDependency-result.txt b/Tests/RunCMake/find_package/MissingTransitiveComponentDependency-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/find_package/MissingTransitiveComponentDependency-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_package/MissingTransitiveComponentDependency-stderr.txt b/Tests/RunCMake/find_package/MissingTransitiveComponentDependency-stderr.txt new file mode 100644 index 0000000..98814d4 --- /dev/null +++ b/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\) diff --git a/Tests/RunCMake/find_package/MissingTransitiveComponentDependency.cmake b/Tests/RunCMake/find_package/MissingTransitiveComponentDependency.cmake new file mode 100644 index 0000000..df40186 --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake index d5a7f8b..27b0c1a 100644 --- a/Tests/RunCMake/find_package/RunCMakeTest.cmake +++ b/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) diff --git a/Tests/RunCMake/find_package/cps/componenttest-extra.cps b/Tests/RunCMake/find_package/cps/componenttest-extra.cps new file mode 100644 index 0000000..7cca03e --- /dev/null +++ b/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" + } + } +} diff --git a/Tests/RunCMake/find_package/cps/componenttest.cps b/Tests/RunCMake/find_package/cps/componenttest.cps new file mode 100644 index 0000000..ef49af4 --- /dev/null +++ b/Tests/RunCMake/find_package/cps/componenttest.cps @@ -0,0 +1,6 @@ +{ + "cps_version": "0.13", + "name": "ComponentTest", + "cps_path": "@prefix@/cps", + "components": {} +} diff --git a/Tests/RunCMake/find_package/cps/transitiveincomplete.cps b/Tests/RunCMake/find_package/cps/transitiveincomplete.cps new file mode 100644 index 0000000..9d0f8c2 --- /dev/null +++ b/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": {} +} diff --git a/Tests/RunCMake/find_package/cps/transitivemissing.cps b/Tests/RunCMake/find_package/cps/transitivemissing.cps new file mode 100644 index 0000000..2a294aa --- /dev/null +++ b/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": {} +} -- cgit v0.12