find_package: Search a "system package registry"

Generalize the "user package registry" created by commit ed0650f6 (Teach
find_package to search a "package registry", 2009-09-01).  Define a
corresponding "system" registry key under HKEY_LOCAL_MACHINE.  This
gives package installers a place to create a registry value that points
at the right location for find_package() to locate the package.
This commit is contained in:
Brad King 2011-04-13 13:14:41 -04:00
parent 549458f280
commit a0d76c10a7
2 changed files with 39 additions and 14 deletions

View File

@ -55,6 +55,7 @@ cmFindPackageCommand::cmFindPackageCommand()
this->Quiet = false; this->Quiet = false;
this->Required = false; this->Required = false;
this->NoUserRegistry = false; this->NoUserRegistry = false;
this->NoSystemRegistry = false;
this->NoBuilds = false; this->NoBuilds = false;
this->NoModule = false; this->NoModule = false;
this->DebugMode = false; this->DebugMode = false;
@ -140,6 +141,7 @@ void cmFindPackageCommand::GenerateDocumentation()
" [NO_CMAKE_PACKAGE_REGISTRY]\n" " [NO_CMAKE_PACKAGE_REGISTRY]\n"
" [NO_CMAKE_BUILDS_PATH]\n" " [NO_CMAKE_BUILDS_PATH]\n"
" [NO_CMAKE_SYSTEM_PATH]\n" " [NO_CMAKE_SYSTEM_PATH]\n"
" [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]\n"
" [CMAKE_FIND_ROOT_PATH_BOTH |\n" " [CMAKE_FIND_ROOT_PATH_BOTH |\n"
" ONLY_CMAKE_FIND_ROOT_PATH |\n" " ONLY_CMAKE_FIND_ROOT_PATH |\n"
" NO_CMAKE_FIND_ROOT_PATH])\n" " NO_CMAKE_FIND_ROOT_PATH])\n"
@ -316,7 +318,15 @@ void cmFindPackageCommand::GenerateDocumentation()
" CMAKE_SYSTEM_PREFIX_PATH\n" " CMAKE_SYSTEM_PREFIX_PATH\n"
" CMAKE_SYSTEM_FRAMEWORK_PATH\n" " CMAKE_SYSTEM_FRAMEWORK_PATH\n"
" CMAKE_SYSTEM_APPBUNDLE_PATH\n" " CMAKE_SYSTEM_APPBUNDLE_PATH\n"
"8. Search paths specified by the PATHS option. " "8. Search paths stored in the CMake system package registry. "
"This can be skipped if NO_CMAKE_SYSTEM_PACKAGE_REGISTRY is passed. "
"On Windows a <package> may appear under registry key\n"
" HKEY_LOCAL_MACHINE\\Software\\Kitware\\CMake\\Packages\\<package>\n"
"as a REG_SZ value, with arbitrary name, that specifies the directory "
"containing the package configuration file. "
"There is no system package registry on non-Windows platforms."
"\n"
"9. Search paths specified by the PATHS option. "
"These are typically hard-coded guesses.\n" "These are typically hard-coded guesses.\n"
; ;
this->CommandDocumentation += this->GenericDocumentationMacPolicy; this->CommandDocumentation += this->GenericDocumentationMacPolicy;
@ -456,6 +466,13 @@ bool cmFindPackageCommand
this->Compatibility_1_6 = false; this->Compatibility_1_6 = false;
doing = DoingNone; doing = DoingNone;
} }
else if(args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY")
{
this->NoSystemRegistry = true;
this->NoModule = true;
this->Compatibility_1_6 = false;
doing = DoingNone;
}
else if(args[i] == "NO_CMAKE_BUILDS_PATH") else if(args[i] == "NO_CMAKE_BUILDS_PATH")
{ {
this->NoBuilds = true; this->NoBuilds = true;
@ -1191,6 +1208,7 @@ void cmFindPackageCommand::ComputePrefixes()
this->AddPrefixesUserRegistry(); this->AddPrefixesUserRegistry();
this->AddPrefixesBuilds(); this->AddPrefixesBuilds();
this->AddPrefixesCMakeSystemVariable(); this->AddPrefixesCMakeSystemVariable();
this->AddPrefixesSystemRegistry();
this->AddPrefixesUserGuess(); this->AddPrefixesUserGuess();
this->ComputeFinalPrefixes(); this->ComputeFinalPrefixes();
} }
@ -1264,7 +1282,7 @@ void cmFindPackageCommand::AddPrefixesUserRegistry()
} }
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
this->LoadPackageRegistryWin(); this->LoadPackageRegistryWin(true);
#elif defined(__HAIKU__) #elif defined(__HAIKU__)
BPath dir; BPath dir;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &dir) == B_OK) if (find_directory(B_USER_SETTINGS_DIRECTORY, &dir) == B_OK)
@ -1284,17 +1302,30 @@ void cmFindPackageCommand::AddPrefixesUserRegistry()
#endif #endif
} }
//----------------------------------------------------------------------------
void cmFindPackageCommand::AddPrefixesSystemRegistry()
{
if(this->NoSystemRegistry || this->NoDefaultPath)
{
return;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
this->LoadPackageRegistryWin(false);
#endif
}
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
# include <windows.h> # include <windows.h>
# undef GetCurrentDirectory # undef GetCurrentDirectory
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmFindPackageCommand::LoadPackageRegistryWin() void cmFindPackageCommand::LoadPackageRegistryWin(bool user)
{ {
std::string key = "Software\\Kitware\\CMake\\Packages\\"; std::string key = "Software\\Kitware\\CMake\\Packages\\";
key += this->Name; key += this->Name;
std::set<cmStdString> bad; std::set<cmStdString> bad;
HKEY hKey; HKEY hKey;
if(RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(), if(RegOpenKeyEx(user? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, key.c_str(),
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
{ {
DWORD valueType = REG_NONE; DWORD valueType = REG_NONE;
@ -1332,7 +1363,7 @@ void cmFindPackageCommand::LoadPackageRegistryWin()
} }
// Remove bad values if possible. // Remove bad values if possible.
if(!bad.empty() && if(user && !bad.empty() &&
RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(), RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(),
0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS)
{ {
@ -2292,11 +2323,3 @@ bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
} }
// TODO: Debug cmsys::Glob double slash problem. // TODO: Debug cmsys::Glob double slash problem.
// TODO: Add registry entries after cmake system search path?
// Currently the user must specify them with the PATHS option.
//
// [HKEY_CURRENT_USER\Software\*\Foo*;InstallDir]
// [HKEY_CURRENT_USER\Software\*\*\Foo*;InstallDir]
// [HKEY_LOCAL_MACHINE\Software\*\Foo*;InstallDir]
// [HKEY_LOCAL_MACHINE\Software\*\*\Foo*;InstallDir]

View File

@ -88,13 +88,14 @@ private:
void AddPrefixesCMakeVariable(); void AddPrefixesCMakeVariable();
void AddPrefixesSystemEnvironment(); void AddPrefixesSystemEnvironment();
void AddPrefixesUserRegistry(); void AddPrefixesUserRegistry();
void AddPrefixesSystemRegistry();
void AddPrefixesBuilds(); void AddPrefixesBuilds();
void AddPrefixesCMakeSystemVariable(); void AddPrefixesCMakeSystemVariable();
void AddPrefixesUserGuess(); void AddPrefixesUserGuess();
void AddPrefixesUserHints(); void AddPrefixesUserHints();
void ComputeFinalPrefixes(); void ComputeFinalPrefixes();
void LoadPackageRegistryDir(std::string const& dir); void LoadPackageRegistryDir(std::string const& dir);
void LoadPackageRegistryWin(); void LoadPackageRegistryWin(bool user);
bool CheckPackageRegistryEntry(std::istream& is); bool CheckPackageRegistryEntry(std::istream& is);
bool SearchDirectory(std::string const& dir); bool SearchDirectory(std::string const& dir);
bool CheckDirectory(std::string const& dir); bool CheckDirectory(std::string const& dir);
@ -133,6 +134,7 @@ private:
bool Compatibility_1_6; bool Compatibility_1_6;
bool NoModule; bool NoModule;
bool NoUserRegistry; bool NoUserRegistry;
bool NoSystemRegistry;
bool NoBuilds; bool NoBuilds;
bool DebugMode; bool DebugMode;
bool UseLib64Paths; bool UseLib64Paths;