From 37823b366f3fe02572c799acd9c39a7108bdb4cc Mon Sep 17 00:00:00 2001 From: Matthew Woehlke Date: Tue, 1 Apr 2025 16:16:52 -0400 Subject: [PATCH] find_package: Restore component requirements in nested calls Fix logic to populate required and optional components from CMake variables when `find_package` is called in a nested context. This was broken in commit e2a6416622 (find_package: Refactor in support of recursion, 2024-11-29, v4.0.0-rc1~356^2), which promoted the component sets from locals (in cmFindPackageCommand::InitialPass) to member variables. Previously, in a nested context, these sets were simply not filled, and we relied on the variables indicating component requirement to already be set. When logic was added to properly fill the sets (which is needed for CPS), it blindly dumped all components into the required set, without actually checking whether the context had marked the components as required or optional. Fixes: #26824 --- Source/cmFindPackageCommand.cxx | 12 +++++++++--- .../find_package/ComponentRecursion-stdout.txt | 3 +++ Tests/RunCMake/find_package/ComponentRecursion.cmake | 2 ++ .../RunCMake/find_package/ComponentTestConfig.cmake | 5 +++++ Tests/RunCMake/find_package/FindComponentTest.cmake | 2 ++ Tests/RunCMake/find_package/RunCMakeTest.cmake | 1 + 6 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 Tests/RunCMake/find_package/ComponentRecursion-stdout.txt create mode 100644 Tests/RunCMake/find_package/ComponentRecursion.cmake create mode 100644 Tests/RunCMake/find_package/ComponentTestConfig.cmake create mode 100644 Tests/RunCMake/find_package/FindComponentTest.cmake diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index ce2f53625e..88cbc40ee6 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -911,10 +911,16 @@ bool cmFindPackageCommand::InitialPass(std::vector const& args) this->VersionExact = this->Makefile->IsOn(exact); } if (this->Components.empty()) { - std::string const components_var = this->Name + "_FIND_COMPONENTS"; - this->Components = this->Makefile->GetSafeDefinition(components_var); + std::string const componentsVar = this->Name + "_FIND_COMPONENTS"; + this->Components = this->Makefile->GetSafeDefinition(componentsVar); for (auto const& component : cmList{ this->Components }) { - this->RequiredComponents.insert(component); + std::string const crVar = + cmStrCat(this->Name, "_FIND_REQUIRED_"_s, component); + if (this->Makefile->GetDefinition(crVar).IsOn()) { + this->RequiredComponents.insert(component); + } else { + this->OptionalComponents.insert(component); + } } } } diff --git a/Tests/RunCMake/find_package/ComponentRecursion-stdout.txt b/Tests/RunCMake/find_package/ComponentRecursion-stdout.txt new file mode 100644 index 0000000000..9e7273d7f8 --- /dev/null +++ b/Tests/RunCMake/find_package/ComponentRecursion-stdout.txt @@ -0,0 +1,3 @@ +-- ComponentTest_FIND_REQUIRED_A '1' +-- ComponentTest_FIND_REQUIRED_B '0' +-- ComponentTest_FIND_REQUIRED_C '0' diff --git a/Tests/RunCMake/find_package/ComponentRecursion.cmake b/Tests/RunCMake/find_package/ComponentRecursion.cmake new file mode 100644 index 0000000000..3faa6dc002 --- /dev/null +++ b/Tests/RunCMake/find_package/ComponentRecursion.cmake @@ -0,0 +1,2 @@ +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) +find_package(ComponentTest MODULE REQUIRED COMPONENTS A OPTIONAL_COMPONENTS B C) diff --git a/Tests/RunCMake/find_package/ComponentTestConfig.cmake b/Tests/RunCMake/find_package/ComponentTestConfig.cmake new file mode 100644 index 0000000000..02354bd243 --- /dev/null +++ b/Tests/RunCMake/find_package/ComponentTestConfig.cmake @@ -0,0 +1,5 @@ +foreach(c IN LISTS ComponentTest_FIND_COMPONENTS) + message(STATUS + "ComponentTest_FIND_REQUIRED_${c} " + "'${ComponentTest_FIND_REQUIRED_${c}}'") +endforeach() diff --git a/Tests/RunCMake/find_package/FindComponentTest.cmake b/Tests/RunCMake/find_package/FindComponentTest.cmake new file mode 100644 index 0000000000..833e75cbe4 --- /dev/null +++ b/Tests/RunCMake/find_package/FindComponentTest.cmake @@ -0,0 +1,2 @@ +find_package(ComponentTest CONFIG + NO_DEFAULT_PATH PATHS ${CMAKE_CURRENT_LIST_DIR}) diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake index 0552535e61..64f6b37323 100644 --- a/Tests/RunCMake/find_package/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake @@ -2,6 +2,7 @@ include(RunCMake) run_cmake(CMP0074-WARN) run_cmake(CMP0074-OLD) +run_cmake(ComponentRecursion) run_cmake(ComponentRequiredAndOptional) run_cmake(EmptyRoots) run_cmake(FromPATHEnv)