diff options
author | Brad King <brad.king@kitware.com> | 2003-01-21 22:15:22 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2003-01-21 22:15:22 (GMT) |
commit | 259a49aaacb9de1a0d19ad6959d09a7000eb9bca (patch) | |
tree | 86f57e5b7fc2ec4b77c705fbe9f147bca94141e2 /Source/cmFindPackageCommand.cxx | |
parent | 7418ed1a6796f18c3fab71ec8f60a897f93472ee (diff) | |
download | CMake-259a49aaacb9de1a0d19ad6959d09a7000eb9bca.zip CMake-259a49aaacb9de1a0d19ad6959d09a7000eb9bca.tar.gz CMake-259a49aaacb9de1a0d19ad6959d09a7000eb9bca.tar.bz2 |
ENH: Added FIND_PACKAGE command prototyp.
Diffstat (limited to 'Source/cmFindPackageCommand.cxx')
-rw-r--r-- | Source/cmFindPackageCommand.cxx | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx new file mode 100644 index 0000000..c61cde2 --- /dev/null +++ b/Source/cmFindPackageCommand.cxx @@ -0,0 +1,231 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmFindPackageCommand.h" + +//---------------------------------------------------------------------------- +bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) +{ + if(args.size() < 1) + { + this->SetError("called with incorrect number of arguments"); + return false; + } + + this->Name = args[0]; + this->UpperName = cmSystemTools::UpperCase(this->Name); + + // See if there is a Find<name>.cmake module. + bool foundModule = false; + if(!this->FindModule(foundModule)) + { + return false; + } + if(foundModule) + { + return true; + } + // No find module. Assume the project has a CMake config file. Use + // a <NAME>_DIR cache variable to locate it. + this->Variable = this->UpperName; + this->Variable += "_DIR"; + this->Config = this->Name; + this->Config += "Config.cmake"; + const char* def = m_Makefile->GetDefinition(this->Variable.c_str()); + if(cmSystemTools::IsOff(def)) + { + if(!this->FindConfig()) + { + return false; + } + } + + // If the config file was found, load it. + bool result = true; + bool found = false; + def = m_Makefile->GetDefinition(this->Variable.c_str()); + if(!cmSystemTools::IsOff(def)) + { + std::string f = def; + f += "/"; + f += this->Config; + if(cmSystemTools::FileExists(f.c_str())) + { + if(this->ReadListFile(f.c_str())) + { + found = true; + } + else + { + result = false; + } + } + else + { + cmOStringStream e; + e << this->Variable << " is set to \"" << def << "\", which is " + << "not a directory containing " << this->Config; + cmSystemTools::Error(e.str().c_str()); + result = true; + } + } + else + { + cmOStringStream e; + e << this->Variable << " is not set. It must be set to the directory " + << "containing " << this->Config << " so in order to use " + << this->Name << "."; + cmSystemTools::Error(e.str().c_str()); + result = true; + } + + std::string foundVar = this->UpperName; + foundVar += "_FOUND"; + m_Makefile->AddDefinition(foundVar.c_str(), found? "1":"0"); + return result; +} + +//---------------------------------------------------------------------------- +bool cmFindPackageCommand::FindModule(bool& found) +{ + // If there is a find module, use it. + std::string module = m_Makefile->GetDefinition("CMAKE_ROOT"); + module += "/Modules/Find"; + module += this->Name; + module += ".cmake"; + found = false; + // TODO: CMAKE_PACKAGE_PATH for looking for Find<name>.cmake + // modules? + if(cmSystemTools::FileExists(module.c_str())) + { + found = true; + return this->ReadListFile(module.c_str()); + } + return true; +} + +//---------------------------------------------------------------------------- +bool cmFindPackageCommand::FindConfig() +{ + std::string help = "The directory containing "; + help += this->Config; + help += "."; + + // Construct the list of relative paths to each prefix to be + // searched. + std::string rel = "/lib/"; + rel += cmSystemTools::LowerCase(this->Name); + this->Relatives.push_back(rel); + rel = "/lib/"; + rel += this->Name; + this->Relatives.push_back(rel); + + // It is likely that CMake will have recently built the project. + for(int i=1; i <= 10; ++i) + { + cmOStringStream r; + r << "[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild" + << i << "]"; + std::string entry = r.str(); + cmSystemTools::ExpandRegistryValues(entry); + cmSystemTools::ConvertToUnixSlashes(entry); + if(cmSystemTools::FileIsDirectory(entry.c_str())) + { + this->Builds.push_back(entry); + } + } + + // The project may be installed. Use the system search path to + // construct a list of possible install prefixes. + std::vector<std::string> systemPath; + cmSystemTools::GetPath(systemPath); + for(std::vector<std::string>::iterator i = systemPath.begin(); + i != systemPath.end(); ++i) + { + *i += "/.."; + if(cmSystemTools::FileIsDirectory(i->c_str())) + { + this->Prefixes.push_back(cmSystemTools::CollapseFullPath(i->c_str())); + } + } +#if !defined(WIN32) || defined(__CYGWIN__) + this->Prefixes.push_back("/usr/local"); + this->Prefixes.push_back("/usr"); +#endif + + // Look for the project's configuration file. + std::string init = this->SearchForConfig(); + + // Store the entry in the cache so it can be set by the user. + m_Makefile->AddCacheDefinition(this->Variable.c_str(), + init.c_str(), + help.c_str(), + cmCacheManager::PATH); + return true; +} + +//---------------------------------------------------------------------------- +std::string cmFindPackageCommand::SearchForConfig() const +{ + // Search the build directories. + for(std::vector<cmStdString>::const_iterator b = this->Builds.begin(); + b != this->Builds.end(); ++b) + { + std::string f = *b; + f += "/"; + f += this->Config; + if(cmSystemTools::FileExists(f.c_str())) + { + return *b; + } + } + + // Search paths relative to each installation prefix. + for(std::vector<cmStdString>::const_iterator p = this->Prefixes.begin(); + p != this->Prefixes.end(); ++p) + { + std::string prefix = *p; + for(std::vector<cmStdString>::const_iterator r = this->Relatives.begin(); + r != this->Relatives.end(); ++r) + { + std::string dir = prefix; + dir += *r; + std::string f = dir; + f += "/"; + f += this->Config; + if(cmSystemTools::FileExists(f.c_str())) + { + return dir; + } + } + } + + return "NOTFOUND"; +} + +//---------------------------------------------------------------------------- +bool cmFindPackageCommand::ReadListFile(const char* f) +{ + if(m_Makefile->ReadListFile(m_Makefile->GetCurrentListFile(), f)) + { + return true; + } + std::string e = "Error reading CMake code from \""; + e += f; + e += "\"."; + this->SetError(e.c_str()); + return false; +} |