[Cmake-commits] [cmake-commits] king committed cmExportCommand.cxx 1.11 1.12 cmExportCommand.h 1.9 1.10
cmake-commits at cmake.org
cmake-commits at cmake.org
Tue Sep 1 14:04:55 EDT 2009
Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv27149/Source
Modified Files:
cmExportCommand.cxx cmExportCommand.h
Log Message:
Teach export(PACKAGE) to fill the package registry
We define the export(PACKAGE) command mode to store the location of the
build tree in the user package registry. This will help find_package
locate the package in the build tree. It simplies user workflow for
manually building a series of dependent projects.
Index: cmExportCommand.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmExportCommand.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -C 2 -d -r1.9 -r1.10
*** cmExportCommand.h 30 Jan 2008 22:25:52 -0000 1.9
--- cmExportCommand.h 1 Sep 2009 18:04:53 -0000 1.10
***************
*** 85,89 ****
"should never be installed. "
"See the install(EXPORT) command to export targets from an "
! "installation tree.";
}
--- 85,101 ----
"should never be installed. "
"See the install(EXPORT) command to export targets from an "
! "installation tree."
! "\n"
! " export(PACKAGE <name>)\n"
! "Store the current build directory in the CMake user package registry "
! "for package <name>. "
! "The find_package command may consider the directory while searching "
! "for package <name>. "
! "This helps dependent projects find and use a package from the "
! "current project's build tree without help from the user. "
! "Note that the entry in the package registry that this command "
! "creates works only in conjunction with a package configuration "
! "file (<name>Config.cmake) that works with the build tree."
! ;
}
***************
*** 99,102 ****
--- 111,122 ----
friend class cmExportBuildFileGenerator;
std::string ErrorMessage;
+
+ bool HandlePackage(std::vector<std::string> const& args);
+ void StorePackageRegistryWin(std::string const& package,
+ const char* content, const char* hash);
+ void StorePackageRegistryDir(std::string const& package,
+ const char* content, const char* hash);
+ void ReportRegistryError(std::string const& msg, std::string const& key,
+ long err);
};
Index: cmExportCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmExportCommand.cxx,v
retrieving revision 1.11
retrieving revision 1.12
diff -C 2 -d -r1.11 -r1.12
*** cmExportCommand.cxx 6 Feb 2008 19:20:35 -0000 1.11
--- cmExportCommand.cxx 1 Sep 2009 18:04:53 -0000 1.12
***************
*** 21,24 ****
--- 21,26 ----
#include "cmake.h"
+ #include <cmsys/RegularExpression.hxx>
+
#include "cmExportBuildFileGenerator.h"
***************
*** 48,51 ****
--- 50,58 ----
}
+ if(args[0] == "PACKAGE")
+ {
+ return this->HandlePackage(args);
+ }
+
std::vector<std::string> unknownArgs;
this->Helper.Parse(&args, &unknownArgs);
***************
*** 185,186 ****
--- 192,335 ----
return true;
}
+
+ //----------------------------------------------------------------------------
+ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
+ {
+ // Parse PACKAGE mode arguments.
+ enum Doing { DoingNone, DoingPackage };
+ Doing doing = DoingPackage;
+ std::string package;
+ for(unsigned int i=1; i < args.size(); ++i)
+ {
+ if(doing == DoingPackage)
+ {
+ package = args[i];
+ doing = DoingNone;
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "PACKAGE given unknown argumsnt: " << args[i];
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ }
+
+ // Verify the package name.
+ if(package.empty())
+ {
+ this->SetError("PACKAGE must be given a package name.");
+ return false;
+ }
+ const char* packageExpr = "^[A-Za-z0-9_.-]+$";
+ cmsys::RegularExpression packageRegex(packageExpr);
+ if(!packageRegex.find(package.c_str()))
+ {
+ cmOStringStream e;
+ e << "PACKAGE given invalid package name \"" << package << "\". "
+ << "Package names must match \"" << packageExpr << "\".";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ // We store the current build directory in the registry as a value
+ // named by a hash of its own content. This is deterministic and is
+ // unique with high probability.
+ const char* outDir = this->Makefile->GetCurrentOutputDirectory();
+ std::string hash = cmSystemTools::ComputeStringMD5(outDir);
+ #if defined(_WIN32) && !defined(__CYGWIN__)
+ this->StorePackageRegistryWin(package, outDir, hash.c_str());
+ #else
+ this->StorePackageRegistryDir(package, outDir, hash.c_str());
+ #endif
+
+ return true;
+ }
+
+ #if defined(_WIN32) && !defined(__CYGWIN__)
+ # include <windows.h>
+ # undef GetCurrentDirectory
+ //----------------------------------------------------------------------------
+ void cmExportCommand::ReportRegistryError(std::string const& msg,
+ std::string const& key,
+ long err)
+ {
+ cmOStringStream e;
+ e << msg << "\n"
+ << " HKEY_CURRENT_USER\\" << key << "\n";
+ char winmsg[1024];
+ if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, 0, err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ winmsg, 1024, 0) > 0)
+ {
+ e << "Windows reported:\n"
+ << " " << winmsg;
+ }
+ this->Makefile->IssueMessage(cmake::WARNING, e.str());
+ }
+
+ //----------------------------------------------------------------------------
+ void cmExportCommand::StorePackageRegistryWin(std::string const& package,
+ const char* content,
+ const char* hash)
+ {
+ std::string key = "Software\\Kitware\\CMake\\Packages\\";
+ key += package;
+ HKEY hKey;
+ LONG err = RegCreateKeyEx(HKEY_CURRENT_USER,
+ key.c_str(), 0, 0, REG_OPTION_NON_VOLATILE,
+ KEY_SET_VALUE, 0, &hKey, 0);
+ if(err != ERROR_SUCCESS)
+ {
+ this->ReportRegistryError(
+ "Cannot create/open registry key", key, err);
+ return;
+ }
+ err = RegSetValueEx(hKey, hash, 0, REG_SZ, (BYTE const*)content,
+ static_cast<DWORD>(strlen(content)+1));
+ RegCloseKey(hKey);
+ if(err != ERROR_SUCCESS)
+ {
+ cmOStringStream msg;
+ msg << "Cannot set registry value \"" << hash << "\" under key";
+ this->ReportRegistryError(msg.str(), key, err);
+ return;
+ }
+ }
+ #else
+ //----------------------------------------------------------------------------
+ void cmExportCommand::StorePackageRegistryDir(std::string const& package,
+ const char* content,
+ const char* hash)
+ {
+ const char* home = cmSystemTools::GetEnv("HOME");
+ if(!home)
+ {
+ return;
+ }
+ std::string fname = home;
+ cmSystemTools::ConvertToUnixSlashes(fname);
+ fname += "/.cmake/packages/";
+ fname += package;
+ cmSystemTools::MakeDirectory(fname.c_str());
+ fname += "/";
+ fname += hash;
+ if(!cmSystemTools::FileExists(fname.c_str()))
+ {
+ cmGeneratedFileStream entry(fname.c_str(), true);
+ if(entry)
+ {
+ entry << content << "\n";
+ }
+ else
+ {
+ cmOStringStream e;
+ e << "Cannot create package registry file:\n"
+ << " " << fname << "\n"
+ << cmSystemTools::GetLastSystemError() << "\n";
+ this->Makefile->IssueMessage(cmake::WARNING, e.str());
+ }
+ }
+ }
+ #endif
More information about the Cmake-commits
mailing list