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.
This commit is contained in:
Brad King 2008-10-03 10:40:07 -04:00
parent 75f8d5aab7
commit 79e9b75558
6 changed files with 54 additions and 3 deletions

View File

@ -129,7 +129,8 @@ cmFindPackageCommand::cmFindPackageCommand()
" NO_CMAKE_FIND_ROOT_PATH])\n" " NO_CMAKE_FIND_ROOT_PATH])\n"
"The NO_MODULE option may be used to skip Module mode explicitly. " "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 " "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" "\n"
"Config mode attempts to locate a configuration file provided by the " "Config mode attempts to locate a configuration file provided by the "
"package to be found. A cache entry called <package>_DIR is created to " "package to be found. A cache entry called <package>_DIR is created to "
@ -160,6 +161,10 @@ cmFindPackageCommand::cmFindPackageCommand()
"version (format is major[.minor[.patch[.tweak]]]). " "version (format is major[.minor[.patch[.tweak]]]). "
"If the EXACT option is given only a version of the package claiming " "If the EXACT option is given only a version of the package claiming "
"an exact match of the requested version may be found. " "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 " "CMake does not establish any convention for the meaning of version "
"numbers. " "numbers. "
"Package version numbers are checked by \"version\" files provided by " "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."); cmake::AUTHOR_WARNING, "Ignoring EXACT since no version is requested.");
} }
if(!this->NoModule || this->Version.empty())
{
// Check whether we are recursing inside "Find<name>.cmake" within
// another find_package(<name>) 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()) if(!this->Version.empty())
{ {
// Try to parse the version number and store the results that were // 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()); std::string mfile = this->Makefile->GetModulesFile(module.c_str());
if ( mfile.size() ) if ( mfile.size() )
{ {
// Load the module we found. // Load the module we found, and set "<name>_FIND_MODULE" to true
// while inside it.
found = true; 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; return true;
} }

View File

@ -38,6 +38,7 @@ SET(PACKAGES
foo Foo Bar TFramework Tframework TApp Tapp Special foo Foo Bar TFramework Tframework TApp Tapp Special
VersionedA VersionedB VersionedA VersionedB
wibbleA wibbleB wibbleA wibbleB
RecursiveA RecursiveB RecursiveC
) )
FOREACH(p ${PACKAGES}) FOREACH(p ${PACKAGES})
SET(${p}_DIR "" CACHE FILEPATH "Wipe out find results for testing." FORCE) 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(wibbleA NAMES wibble PATHS B)
FIND_PACKAGE(wibbleB NAMES wibble HINTS 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. # 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/foo-config.cmake")
SET(Foo_EXPECTED "lib/foo-1.2/CMake/FooConfig.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(VersionedB_EXPECTED "lib/zot-3.1/zot-config.cmake")
SET(wibbleA_EXPECTED "A/wibble-config.cmake") SET(wibbleA_EXPECTED "A/wibble-config.cmake")
SET(wibbleB_EXPECTED "B/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. # Check the results.
FOREACH(p ${PACKAGES}) FOREACH(p ${PACKAGES})

View File

@ -0,0 +1 @@
FIND_PACKAGE(RecursiveA)

View File

@ -0,0 +1 @@
FIND_PACKAGE(RecursiveB NAMES zot)

View File

@ -0,0 +1 @@
FIND_PACKAGE(RecursiveC NAMES zot)

View File

@ -0,0 +1 @@
# Test config file.