[Cmake-commits] [cmake-commits] king committed cmFindPackageCommand.cxx 1.60 1.61 cmFindPackageCommand.h 1.28 1.29
cmake-commits at cmake.org
cmake-commits at cmake.org
Tue Sep 1 14:04:31 EDT 2009
Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv26918/Source
Modified Files:
cmFindPackageCommand.cxx cmFindPackageCommand.h
Log Message:
Teach find_package to search a "package registry"
A common user workflow is to build a series of dependent projects in
order. Each project locates its dependencies with find_package. We
introduce a "user package registry" to help find_package locate packages
built in non-standard search locations.
The registry explicitly stores locations of build trees providing
instances of a given package. There is no defined order among the
locations specified. These locations should provide package
configuration files (<package>-config.cmake) and package version files
(<package>-config-version.cmake) so that find_package will recognize the
packages and test version numbers.
Index: cmFindPackageCommand.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmFindPackageCommand.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -C 2 -d -r1.28 -r1.29
*** cmFindPackageCommand.h 22 Jan 2009 18:18:39 -0000 1.28
--- cmFindPackageCommand.h 1 Sep 2009 18:04:27 -0000 1.29
***************
*** 91,94 ****
--- 91,95 ----
void AddPrefixesCMakeVariable();
void AddPrefixesSystemEnvironment();
+ void AddPrefixesRegistry();
void AddPrefixesBuilds();
void AddPrefixesCMakeSystemVariable();
***************
*** 96,99 ****
--- 97,103 ----
void AddPrefixesUserHints();
void ComputeFinalPrefixes();
+ void LoadPackageRegistryDir(std::string const& dir);
+ void LoadPackageRegistryWin();
+ bool CheckPackageRegistryEntry(std::istream& is);
bool SearchDirectory(std::string const& dir);
bool CheckDirectory(std::string const& dir);
***************
*** 131,134 ****
--- 135,139 ----
bool Compatibility_1_6;
bool NoModule;
+ bool NoRegistry;
bool NoBuilds;
bool DebugMode;
Index: cmFindPackageCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmFindPackageCommand.cxx,v
retrieving revision 1.60
retrieving revision 1.61
diff -C 2 -d -r1.60 -r1.61
*** cmFindPackageCommand.cxx 5 Aug 2009 13:56:02 -0000 1.60
--- cmFindPackageCommand.cxx 1 Sep 2009 18:04:27 -0000 1.61
***************
*** 16,19 ****
--- 16,21 ----
=========================================================================*/
#include "cmFindPackageCommand.h"
+
+ #include <cmsys/Directory.hxx>
#include <cmsys/RegularExpression.hxx>
***************
*** 61,64 ****
--- 63,67 ----
this->Quiet = false;
this->Required = false;
+ this->NoRegistry = false;
this->NoBuilds = false;
this->NoModule = false;
***************
*** 129,132 ****
--- 132,136 ----
" [NO_CMAKE_PATH]\n"
" [NO_SYSTEM_ENVIRONMENT_PATH]\n"
+ " [NO_CMAKE_PACKAGE_REGISTRY]\n"
" [NO_CMAKE_BUILDS_PATH]\n"
" [NO_CMAKE_SYSTEM_PATH]\n"
***************
*** 282,286 ****
"It is intended for the case when a user is building multiple "
"dependent projects one after another.\n"
! "6. Search cmake variables defined in the Platform files "
"for the current system. This can be skipped if NO_CMAKE_SYSTEM_PATH "
"is passed.\n"
--- 286,296 ----
"It is intended for the case when a user is building multiple "
"dependent projects one after another.\n"
! "6. Search paths stored in the CMake user package registry. "
! "This can be skipped if NO_CMAKE_PACKAGE_REGISTRY is passed. "
! "Paths are stored in the registry when CMake configures a project "
! "that invokes export(PACKAGE <name>). "
! "See the export(PACKAGE) command documentation for more details."
! "\n"
! "7. Search cmake variables defined in the Platform files "
"for the current system. This can be skipped if NO_CMAKE_SYSTEM_PATH "
"is passed.\n"
***************
*** 288,292 ****
" CMAKE_SYSTEM_FRAMEWORK_PATH\n"
" CMAKE_SYSTEM_APPBUNDLE_PATH\n"
! "7. Search paths specified by the PATHS option. "
"These are typically hard-coded guesses.\n"
;
--- 298,302 ----
" CMAKE_SYSTEM_FRAMEWORK_PATH\n"
" CMAKE_SYSTEM_APPBUNDLE_PATH\n"
! "8. Search paths specified by the PATHS option. "
"These are typically hard-coded guesses.\n"
;
***************
*** 421,424 ****
--- 431,441 ----
doing = DoingNone;
}
+ else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY")
+ {
+ this->NoRegistry = true;
+ this->NoModule = true;
+ this->Compatibility_1_6 = false;
+ doing = DoingNone;
+ }
else if(args[i] == "NO_CMAKE_BUILDS_PATH")
{
***************
*** 1066,1069 ****
--- 1083,1087 ----
this->AddPrefixesUserHints();
this->AddPrefixesSystemEnvironment();
+ this->AddPrefixesRegistry();
this->AddPrefixesBuilds();
this->AddPrefixesCMakeSystemVariable();
***************
*** 1133,1136 ****
--- 1151,1320 ----
//----------------------------------------------------------------------------
+ void cmFindPackageCommand::AddPrefixesRegistry()
+ {
+ if(this->NoRegistry || this->NoDefaultPath)
+ {
+ return;
+ }
+
+ #if defined(_WIN32) && !defined(__CYGWIN__)
+ this->LoadPackageRegistryWin();
+ #else
+ if(const char* home = cmSystemTools::GetEnv("HOME"))
+ {
+ std::string dir = home;
+ dir += "/.cmake/packages/";
+ dir += this->Name;
+ this->LoadPackageRegistryDir(dir);
+ }
+ #endif
+ }
+
+ #if defined(_WIN32) && !defined(__CYGWIN__)
+ # include <windows.h>
+ # undef GetCurrentDirectory
+ //----------------------------------------------------------------------------
+ void cmFindPackageCommand::LoadPackageRegistryWin()
+ {
+ std::string key = "Software\\Kitware\\CMake\\Packages\\";
+ key += this->Name;
+ std::set<cmStdString> bad;
+ HKEY hKey;
+ if(RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(),
+ 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ DWORD valueType = REG_NONE;
+ char name[16384];
+ std::vector<char> data(512);
+ bool done = false;
+ DWORD index = 0;
+ while(!done)
+ {
+ DWORD nameSize = static_cast<DWORD>(sizeof(name));
+ DWORD dataSize = static_cast<DWORD>(data.size()-1);
+ switch(RegEnumValue(hKey, index, name, &nameSize,
+ 0, &valueType, (BYTE*)&data[0], &dataSize))
+ {
+ case ERROR_SUCCESS:
+ ++index;
+ if(valueType == REG_SZ)
+ {
+ data[dataSize] = 0;
+ cmsys_ios::stringstream ss(&data[0]);
+ if(this->CheckPackageRegistryEntry(ss))
+ {
+ // The entry is okay.
+ continue;
+ }
+ }
+ bad.insert(name);
+ break;
+ case ERROR_MORE_DATA:
+ data.resize(dataSize+1);
+ break;
+ case ERROR_NO_MORE_ITEMS: default: done = true; break;
+ }
+ }
+ RegCloseKey(hKey);
+ }
+
+ // Remove bad values if possible.
+ if(!bad.empty() &&
+ RegOpenKeyEx(HKEY_CURRENT_USER, key.c_str(),
+ 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS)
+ {
+ for(std::set<cmStdString>::const_iterator vi = bad.begin();
+ vi != bad.end(); ++vi)
+ {
+ RegDeleteValue(hKey, vi->c_str());
+ }
+ RegCloseKey(hKey);
+ }
+ }
+ #else
+ //----------------------------------------------------------------------------
+ class cmFindPackageCommandHoldFile
+ {
+ const char* File;
+ public:
+ cmFindPackageCommandHoldFile(const char* f): File(f) {}
+ ~cmFindPackageCommandHoldFile()
+ { if(this->File) { cmSystemTools::RemoveFile(this->File); } }
+ void Release() { this->File = 0; }
+ };
+
+ //----------------------------------------------------------------------------
+ void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir)
+ {
+ cmsys::Directory files;
+ if(!files.Load(dir.c_str()))
+ {
+ return;
+ }
+
+ std::string fname;
+ for(unsigned long i=0; i < files.GetNumberOfFiles(); ++i)
+ {
+ fname = dir;
+ fname += "/";
+ fname += files.GetFile(i);
+
+ if(!cmSystemTools::FileIsDirectory(fname.c_str()))
+ {
+ // Hold this file hostage until it behaves.
+ cmFindPackageCommandHoldFile holdFile(fname.c_str());
+
+ // Load the file.
+ std::ifstream fin(fname.c_str(), std::ios::in | cmsys_ios_binary);
+ if(fin && this->CheckPackageRegistryEntry(fin))
+ {
+ // The file references an existing package, so release it.
+ holdFile.Release();
+ }
+ }
+ }
+
+ // TODO: Wipe out the directory if it is empty.
+ }
+ #endif
+
+ //----------------------------------------------------------------------------
+ bool cmFindPackageCommand::CheckPackageRegistryEntry(std::istream& is)
+ {
+ // Parse the content of one package registry entry.
+ std::string fname;
+ if(cmSystemTools::GetLineFromStream(is, fname) &&
+ cmSystemTools::FileIsFullPath(fname.c_str()))
+ {
+ // The first line in the stream is the full path to a file or
+ // directory containing the package.
+ if(cmSystemTools::FileExists(fname.c_str()))
+ {
+ // The path exists. Look for the package here.
+ if(!cmSystemTools::FileIsDirectory(fname.c_str()))
+ {
+ fname = cmSystemTools::GetFilenamePath(fname);
+ }
+ this->AddPathInternal(fname, FullPath);
+ return true;
+ }
+ else
+ {
+ // The path does not exist. Assume the stream content is
+ // associated with an old package that no longer exists, and
+ // delete it to keep the package registry clean.
+ return false;
+ }
+ }
+ else
+ {
+ // The first line in the stream is not the full path to a file or
+ // directory. Assume the stream content was created by a future
+ // version of CMake that uses a different format, and leave it.
+ return true;
+ }
+ }
+
+ //----------------------------------------------------------------------------
void cmFindPackageCommand::AddPrefixesBuilds()
{
***************
*** 1397,1401 ****
//----------------------------------------------------------------------------
- #include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>
#include <cmsys/String.h>
--- 1581,1584 ----
More information about the Cmake-commits
mailing list