From 79e9b7555827ba0afe6e6b7d97c81002685ef519 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 3 Oct 2008 10:40:07 -0400 Subject: [PATCH] ENH: Help recursive find_package calls in modules These changes teach find_package to behave nicely when invoked recursively inside a find-module for the same package. The module will never be recursively loaded again. Version arguments are automatically forwarded. --- Source/cmFindPackageCommand.cxx | 44 +++++++++++++++++-- Tests/FindPackageTest/CMakeLists.txt | 9 ++++ Tests/FindPackageTest/FindRecursiveA.cmake | 1 + Tests/FindPackageTest/FindRecursiveB.cmake | 1 + Tests/FindPackageTest/FindRecursiveC.cmake | 1 + .../lib/RecursiveA/recursivea-config.cmake | 1 + 6 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 Tests/FindPackageTest/FindRecursiveA.cmake create mode 100644 Tests/FindPackageTest/FindRecursiveB.cmake create mode 100644 Tests/FindPackageTest/FindRecursiveC.cmake create mode 100644 Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index b1c989d0a..61595df50 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -129,7 +129,8 @@ cmFindPackageCommand::cmFindPackageCommand() " NO_CMAKE_FIND_ROOT_PATH])\n" "The NO_MODULE option may be used to skip Module mode explicitly. " "It is also implied by use of options not specified in the reduced " - "signature. " + "signature, or when the command is invoked recursively inside a " + "find-module for the package." "\n" "Config mode attempts to locate a configuration file provided by the " "package to be found. A cache entry called _DIR is created to " @@ -160,6 +161,10 @@ cmFindPackageCommand::cmFindPackageCommand() "version (format is major[.minor[.patch[.tweak]]]). " "If the EXACT option is given only a version of the package claiming " "an exact match of the requested version may be found. " + "If no [version] is given to a recursive invocation inside a " + "find-module, the [version] and EXACT arguments are forwarded " + "automatically from the outer call." + "\n" "CMake does not establish any convention for the meaning of version " "numbers. " "Package version numbers are checked by \"version\" files provided by " @@ -476,6 +481,33 @@ bool cmFindPackageCommand cmake::AUTHOR_WARNING, "Ignoring EXACT since no version is requested."); } + if(!this->NoModule || this->Version.empty()) + { + // Check whether we are recursing inside "Find.cmake" within + // another find_package() call. + std::string mod = this->Name; + mod += "_FIND_MODULE"; + if(this->Makefile->IsOn(mod.c_str())) + { + // Avoid recursing back into the module. + this->NoModule = true; + + // Get version information from the outer call if necessary. + if(this->Version.empty()) + { + // Requested version string. + std::string ver = this->Name; + ver += "_FIND_VERSION"; + this->Version = this->Makefile->GetSafeDefinition(ver.c_str()); + + // Whether an exact version is required. + std::string exact = this->Name; + exact += "_FIND_VERSION_EXACT"; + this->VersionExact = this->Makefile->IsOn(exact.c_str()); + } + } + } + if(!this->Version.empty()) { // Try to parse the version number and store the results that were @@ -611,9 +643,15 @@ bool cmFindPackageCommand::FindModule(bool& found) std::string mfile = this->Makefile->GetModulesFile(module.c_str()); if ( mfile.size() ) { - // Load the module we found. + // Load the module we found, and set "_FIND_MODULE" to true + // while inside it. found = true; - return this->ReadListFile(mfile.c_str()); + std::string var = this->Name; + var += "_FIND_MODULE"; + this->Makefile->AddDefinition(var.c_str(), "1"); + bool result = this->ReadListFile(mfile.c_str()); + this->Makefile->RemoveDefinition(var.c_str()); + return result; } return true; } diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt index 1703fe7af..62a4dc758 100644 --- a/Tests/FindPackageTest/CMakeLists.txt +++ b/Tests/FindPackageTest/CMakeLists.txt @@ -38,6 +38,7 @@ SET(PACKAGES foo Foo Bar TFramework Tframework TApp Tapp Special VersionedA VersionedB wibbleA wibbleB + RecursiveA RecursiveB RecursiveC ) FOREACH(p ${PACKAGES}) SET(${p}_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE) @@ -65,6 +66,11 @@ LIST(INSERT CMAKE_SYSTEM_PREFIX_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/A") FIND_PACKAGE(wibbleA NAMES wibble PATHS B) FIND_PACKAGE(wibbleB NAMES wibble HINTS B) +# Look for package with recursive find-modules. +FIND_PACKAGE(RecursiveA) +FIND_PACKAGE(RecursiveB 2) +FIND_PACKAGE(RecursiveC 3.1 EXACT) + # Expected locations at which packages should be found. SET(foo_EXPECTED "lib/foo-1.2/foo-config.cmake") SET(Foo_EXPECTED "lib/foo-1.2/CMake/FooConfig.cmake") @@ -82,6 +88,9 @@ SET(VersionedA_EXPECTED "lib/zot-2.0/zot-config.cmake") SET(VersionedB_EXPECTED "lib/zot-3.1/zot-config.cmake") SET(wibbleA_EXPECTED "A/wibble-config.cmake") SET(wibbleB_EXPECTED "B/wibble-config.cmake") +SET(RecursiveA_EXPECTED "lib/RecursiveA/recursivea-config.cmake") +SET(RecursiveB_EXPECTED "lib/zot-2.0/zot-config.cmake") +SET(RecursiveC_EXPECTED "lib/zot-3.1/zot-config.cmake") # Check the results. FOREACH(p ${PACKAGES}) diff --git a/Tests/FindPackageTest/FindRecursiveA.cmake b/Tests/FindPackageTest/FindRecursiveA.cmake new file mode 100644 index 000000000..17d687183 --- /dev/null +++ b/Tests/FindPackageTest/FindRecursiveA.cmake @@ -0,0 +1 @@ +FIND_PACKAGE(RecursiveA) diff --git a/Tests/FindPackageTest/FindRecursiveB.cmake b/Tests/FindPackageTest/FindRecursiveB.cmake new file mode 100644 index 000000000..c609ab127 --- /dev/null +++ b/Tests/FindPackageTest/FindRecursiveB.cmake @@ -0,0 +1 @@ +FIND_PACKAGE(RecursiveB NAMES zot) diff --git a/Tests/FindPackageTest/FindRecursiveC.cmake b/Tests/FindPackageTest/FindRecursiveC.cmake new file mode 100644 index 000000000..018cc7302 --- /dev/null +++ b/Tests/FindPackageTest/FindRecursiveC.cmake @@ -0,0 +1 @@ +FIND_PACKAGE(RecursiveC NAMES zot) diff --git a/Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake b/Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake new file mode 100644 index 000000000..deffa5729 --- /dev/null +++ b/Tests/FindPackageTest/lib/RecursiveA/recursivea-config.cmake @@ -0,0 +1 @@ +# Test config file.