Merge topic 'find_package-system-registry'
08b9397 find_package: Fix system package registry test path conversion 93021ad find_package: Test system package registry when possible b95f3ca find_package: Check both 32-bit and 64-bit registry views a0d76c1 find_package: Search a "system package registry" 549458f find_package: Document user package registry locations c9563db find_package: Cleanup user package registry less aggressively 4df1197 find_package: Rename implementation of user package registry
This commit is contained in:
commit
19a4b8856d
@ -54,7 +54,8 @@ cmFindPackageCommand::cmFindPackageCommand()
|
|||||||
this->CMakePathName = "PACKAGE";
|
this->CMakePathName = "PACKAGE";
|
||||||
this->Quiet = false;
|
this->Quiet = false;
|
||||||
this->Required = false;
|
this->Required = false;
|
||||||
this->NoRegistry = 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"
|
||||||
@ -299,9 +301,16 @@ void cmFindPackageCommand::GenerateDocumentation()
|
|||||||
"dependent projects one after another.\n"
|
"dependent projects one after another.\n"
|
||||||
"6. Search paths stored in the CMake user package registry. "
|
"6. Search paths stored in the CMake user package registry. "
|
||||||
"This can be skipped if NO_CMAKE_PACKAGE_REGISTRY is passed. "
|
"This can be skipped if NO_CMAKE_PACKAGE_REGISTRY is passed. "
|
||||||
"Paths are stored in the registry when CMake configures a project "
|
"On Windows a <package> may appear under registry key\n"
|
||||||
"that invokes export(PACKAGE <name>). "
|
" HKEY_CURRENT_USER\\Software\\Kitware\\CMake\\Packages\\<package>\n"
|
||||||
"See the export(PACKAGE) command documentation for more details."
|
"as a REG_SZ value, with arbitrary name, that specifies the directory "
|
||||||
|
"containing the package configuration file. "
|
||||||
|
"On UNIX platforms a <package> may appear under the directory\n"
|
||||||
|
" ~/.cmake/packages/<package>\n"
|
||||||
|
"as a file, with arbitrary name, whose content specifies the directory "
|
||||||
|
"containing the package configuration file. "
|
||||||
|
"See the export(PACKAGE) command to create user package registry entries "
|
||||||
|
"for project build trees."
|
||||||
"\n"
|
"\n"
|
||||||
"7. Search cmake variables defined in the Platform files "
|
"7. Search cmake variables defined in the Platform files "
|
||||||
"for the current system. This can be skipped if NO_CMAKE_SYSTEM_PATH "
|
"for the current system. This can be skipped if NO_CMAKE_SYSTEM_PATH "
|
||||||
@ -309,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;
|
||||||
@ -444,7 +461,14 @@ bool cmFindPackageCommand
|
|||||||
}
|
}
|
||||||
else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY")
|
else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY")
|
||||||
{
|
{
|
||||||
this->NoRegistry = true;
|
this->NoUserRegistry = true;
|
||||||
|
this->NoModule = true;
|
||||||
|
this->Compatibility_1_6 = false;
|
||||||
|
doing = DoingNone;
|
||||||
|
}
|
||||||
|
else if(args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY")
|
||||||
|
{
|
||||||
|
this->NoSystemRegistry = true;
|
||||||
this->NoModule = true;
|
this->NoModule = true;
|
||||||
this->Compatibility_1_6 = false;
|
this->Compatibility_1_6 = false;
|
||||||
doing = DoingNone;
|
doing = DoingNone;
|
||||||
@ -1181,9 +1205,10 @@ void cmFindPackageCommand::ComputePrefixes()
|
|||||||
this->AddPrefixesCMakeEnvironment();
|
this->AddPrefixesCMakeEnvironment();
|
||||||
this->AddPrefixesUserHints();
|
this->AddPrefixesUserHints();
|
||||||
this->AddPrefixesSystemEnvironment();
|
this->AddPrefixesSystemEnvironment();
|
||||||
this->AddPrefixesRegistry();
|
this->AddPrefixesUserRegistry();
|
||||||
this->AddPrefixesBuilds();
|
this->AddPrefixesBuilds();
|
||||||
this->AddPrefixesCMakeSystemVariable();
|
this->AddPrefixesCMakeSystemVariable();
|
||||||
|
this->AddPrefixesSystemRegistry();
|
||||||
this->AddPrefixesUserGuess();
|
this->AddPrefixesUserGuess();
|
||||||
this->ComputeFinalPrefixes();
|
this->ComputeFinalPrefixes();
|
||||||
}
|
}
|
||||||
@ -1249,15 +1274,15 @@ void cmFindPackageCommand::AddPrefixesSystemEnvironment()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmFindPackageCommand::AddPrefixesRegistry()
|
void cmFindPackageCommand::AddPrefixesUserRegistry()
|
||||||
{
|
{
|
||||||
if(this->NoRegistry || this->NoDefaultPath)
|
if(this->NoUserRegistry || this->NoDefaultPath)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
this->LoadPackageRegistryWin();
|
this->LoadPackageRegistryWinUser();
|
||||||
#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)
|
||||||
@ -1277,18 +1302,63 @@ void cmFindPackageCommand::AddPrefixesRegistry()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmFindPackageCommand::AddPrefixesSystemRegistry()
|
||||||
|
{
|
||||||
|
if(this->NoSystemRegistry || this->NoDefaultPath)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
this->LoadPackageRegistryWinSystem();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# undef GetCurrentDirectory
|
# undef GetCurrentDirectory
|
||||||
|
// http://msdn.microsoft.com/en-us/library/aa384253%28v=vs.85%29.aspx
|
||||||
|
# if !defined(KEY_WOW64_32KEY)
|
||||||
|
# define KEY_WOW64_32KEY 0x0200
|
||||||
|
# endif
|
||||||
|
# if !defined(KEY_WOW64_64KEY)
|
||||||
|
# define KEY_WOW64_64KEY 0x0100
|
||||||
|
# endif
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmFindPackageCommand::LoadPackageRegistryWin()
|
void cmFindPackageCommand::LoadPackageRegistryWinUser()
|
||||||
|
{
|
||||||
|
// HKEY_CURRENT_USER\\Software shares 32-bit and 64-bit views.
|
||||||
|
this->LoadPackageRegistryWin(true, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmFindPackageCommand::LoadPackageRegistryWinSystem()
|
||||||
|
{
|
||||||
|
// HKEY_LOCAL_MACHINE\\SOFTWARE has separate 32-bit and 64-bit views.
|
||||||
|
// Prefer the target platform view first.
|
||||||
|
if(this->Makefile->PlatformIs64Bit())
|
||||||
|
{
|
||||||
|
this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY);
|
||||||
|
this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY);
|
||||||
|
this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmFindPackageCommand::LoadPackageRegistryWin(bool user,
|
||||||
|
unsigned int view)
|
||||||
{
|
{
|
||||||
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|view, &hKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
DWORD valueType = REG_NONE;
|
DWORD valueType = REG_NONE;
|
||||||
char name[16384];
|
char name[16384];
|
||||||
@ -1308,13 +1378,12 @@ void cmFindPackageCommand::LoadPackageRegistryWin()
|
|||||||
{
|
{
|
||||||
data[dataSize] = 0;
|
data[dataSize] = 0;
|
||||||
cmsys_ios::stringstream ss(&data[0]);
|
cmsys_ios::stringstream ss(&data[0]);
|
||||||
if(this->CheckPackageRegistryEntry(ss))
|
if(!this->CheckPackageRegistryEntry(ss))
|
||||||
{
|
{
|
||||||
// The entry is okay.
|
// The entry is invalid.
|
||||||
continue;
|
bad.insert(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bad.insert(name);
|
|
||||||
break;
|
break;
|
||||||
case ERROR_MORE_DATA:
|
case ERROR_MORE_DATA:
|
||||||
data.resize(dataSize+1);
|
data.resize(dataSize+1);
|
||||||
@ -1326,9 +1395,9 @@ 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|view, &hKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
for(std::set<cmStdString>::const_iterator vi = bad.begin();
|
for(std::set<cmStdString>::const_iterator vi = bad.begin();
|
||||||
vi != bad.end(); ++vi)
|
vi != bad.end(); ++vi)
|
||||||
@ -2286,11 +2355,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]
|
|
||||||
|
@ -87,14 +87,17 @@ private:
|
|||||||
void AddPrefixesCMakeEnvironment();
|
void AddPrefixesCMakeEnvironment();
|
||||||
void AddPrefixesCMakeVariable();
|
void AddPrefixesCMakeVariable();
|
||||||
void AddPrefixesSystemEnvironment();
|
void AddPrefixesSystemEnvironment();
|
||||||
void AddPrefixesRegistry();
|
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 LoadPackageRegistryWinUser();
|
||||||
|
void LoadPackageRegistryWinSystem();
|
||||||
|
void LoadPackageRegistryWin(bool user, unsigned int view);
|
||||||
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);
|
||||||
@ -132,7 +135,8 @@ private:
|
|||||||
bool Required;
|
bool Required;
|
||||||
bool Compatibility_1_6;
|
bool Compatibility_1_6;
|
||||||
bool NoModule;
|
bool NoModule;
|
||||||
bool NoRegistry;
|
bool NoUserRegistry;
|
||||||
|
bool NoSystemRegistry;
|
||||||
bool NoBuilds;
|
bool NoBuilds;
|
||||||
bool DebugMode;
|
bool DebugMode;
|
||||||
bool UseLib64Paths;
|
bool UseLib64Paths;
|
||||||
|
@ -37,6 +37,38 @@ FIND_PACKAGE(VersionTestB 1.2)
|
|||||||
FIND_PACKAGE(VersionTestC 1.2.3)
|
FIND_PACKAGE(VersionTestC 1.2.3)
|
||||||
FIND_PACKAGE(VersionTestD 1.2.3.4)
|
FIND_PACKAGE(VersionTestD 1.2.3.4)
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
# Test system package registry if possible.
|
||||||
|
SET(CMakeTestSystemPackage "")
|
||||||
|
IF(WIN32 AND NOT CYGWIN)
|
||||||
|
# Try writing a value to the system package registry.
|
||||||
|
SET(_data "${FindPackageTest_SOURCE_DIR}/SystemPackage")
|
||||||
|
SET(_key "HKLM\\Software\\Kitware\\CMake\\Packages\\CMakeTestSystemPackage")
|
||||||
|
SET(_file "${FindPackageTest_BINARY_DIR}/CMakeTestSystemPackage.data")
|
||||||
|
FILE(WRITE ${_file} "${_data}\n")
|
||||||
|
EXECUTE_PROCESS(
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E md5sum ${_file}
|
||||||
|
OUTPUT_VARIABLE _output ERROR_VARIABLE _error RESULT_VARIABLE _failed
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
STRING(REGEX REPLACE " .*" "" _value "${_output}")
|
||||||
|
IF(NOT _failed AND _value)
|
||||||
|
EXECUTE_PROCESS(
|
||||||
|
COMMAND reg add "${_key}" /v "${_value}" /t REG_SZ /d "${_data}" /f
|
||||||
|
OUTPUT_VARIABLE _output ERROR_VARIABLE _output RESULT_VARIABLE _failed
|
||||||
|
)
|
||||||
|
ENDIF()
|
||||||
|
# If the above worked, add the rest of the test and a rule to
|
||||||
|
# cleanup the value.
|
||||||
|
IF(NOT _failed)
|
||||||
|
MESSAGE(STATUS "HKLM is writable: enabling CMakeTestSystemPackage")
|
||||||
|
SET(CMakeTestSystemPackage_CLEANUP reg delete "${_key}" /v "${_value}" /f)
|
||||||
|
SET(CMakeTestSystemPackage CMakeTestSystemPackage)
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS "HKLM is readonly: disabling CMakeTestSystemPackage")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#SET(CMAKE_FIND_DEBUG_MODE 1)
|
#SET(CMAKE_FIND_DEBUG_MODE 1)
|
||||||
@ -49,6 +81,7 @@ SET(PACKAGES
|
|||||||
wibbleA wibbleB
|
wibbleA wibbleB
|
||||||
RecursiveA RecursiveB RecursiveC
|
RecursiveA RecursiveB RecursiveC
|
||||||
EnvA EnvB
|
EnvA EnvB
|
||||||
|
${CMakeTestSystemPackage}
|
||||||
)
|
)
|
||||||
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)
|
||||||
@ -116,6 +149,13 @@ SET(ENV{EnvA_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/lib/zot-3.1")
|
|||||||
FIND_PACKAGE(EnvA 3.1 EXACT QUIET NAMES zot) # Should Work
|
FIND_PACKAGE(EnvA 3.1 EXACT QUIET NAMES zot) # Should Work
|
||||||
FIND_PACKAGE(EnvB 3.1 EXACT QUIET NAMES zot) # Should Fail
|
FIND_PACKAGE(EnvB 3.1 EXACT QUIET NAMES zot) # Should Fail
|
||||||
|
|
||||||
|
# Test system package registry if available.
|
||||||
|
IF(CMakeTestSystemPackage)
|
||||||
|
FIND_PACKAGE(CMakeTestSystemPackage)
|
||||||
|
EXECUTE_PROCESS(COMMAND ${CMakeTestSystemPackage_CLEANUP}
|
||||||
|
OUTPUT_VARIABLE _output ERROR_VARIABLE _error)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
# 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")
|
||||||
@ -145,6 +185,7 @@ SET(RecursiveB_EXPECTED "lib/zot-2.0/zot-config.cmake")
|
|||||||
SET(RecursiveC_EXPECTED "lib/zot-3.1/zot-config.cmake")
|
SET(RecursiveC_EXPECTED "lib/zot-3.1/zot-config.cmake")
|
||||||
SET(EnvA_EXPECTED "lib/zot-3.1/zot-config.cmake")
|
SET(EnvA_EXPECTED "lib/zot-3.1/zot-config.cmake")
|
||||||
SET(EnvB_MISSING "EnvB_DIR-NOTFOUND")
|
SET(EnvB_MISSING "EnvB_DIR-NOTFOUND")
|
||||||
|
SET(CMakeTestSystemPackage_EXPECTED "SystemPackage/CMakeTestSystemPackageConfig.cmake")
|
||||||
|
|
||||||
# Check the results.
|
# Check the results.
|
||||||
FOREACH(p ${PACKAGES})
|
FOREACH(p ${PACKAGES})
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
# Test config file.
|
Loading…
x
Reference in New Issue
Block a user