diff options
Diffstat (limited to 'Source/cmFindPathCommand.cxx')
-rw-r--r-- | Source/cmFindPathCommand.cxx | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx new file mode 100644 index 0000000..6a43298 --- /dev/null +++ b/Source/cmFindPathCommand.cxx @@ -0,0 +1,242 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmFindPathCommand.h" +#include "cmCacheManager.h" + +#include <cmsys/Glob.hxx> + +cmFindPathCommand::cmFindPathCommand() +{ + this->EnvironmentPath = "INCLUDE"; + this->IncludeFileInPath = false; +} + +void cmFindPathCommand::GenerateDocumentation() +{ + this->cmFindBase::GenerateDocumentation(); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "FIND_XXX", "find_path"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "CMAKE_XXX_PATH", "CMAKE_INCLUDE_PATH"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "CMAKE_XXX_MAC_PATH", + "CMAKE_FRAMEWORK_PATH"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "CMAKE_SYSTEM_XXX_MAC_PATH", + "CMAKE_SYSTEM_FRAMEWORK_PATH"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "XXX_SYSTEM", "INCLUDE"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "CMAKE_SYSTEM_XXX_PATH", + "CMAKE_SYSTEM_INCLUDE_PATH"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "SEARCH_XXX_DESC", + "directory containing the named file"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "SEARCH_XXX", "file in a directory"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "XXX_SUBDIR", "include"); + cmSystemTools::ReplaceString( + this->GenericDocumentation, + "XXX_EXTRA_PREFIX_ENTRY", + " <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and\n"); + cmSystemTools::ReplaceString(this->GenericDocumentation, + "CMAKE_FIND_ROOT_PATH_MODE_XXX", + "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE"); + if(!this->IncludeFileInPath) + { + this->GenericDocumentation += + "\n" + "When searching for frameworks, if the file is specified as " + "A/b.h, then the framework search will look for " + "A.framework/Headers/b.h. " + "If that is found the path will be set to the path to the framework. " + "CMake will convert this to the correct -F option to include the " + "file. "; + } +} + +// cmFindPathCommand +bool cmFindPathCommand +::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &) +{ + this->VariableDocumentation = "Path to a file."; + this->CMakePathName = "INCLUDE"; + if(!this->ParseArguments(argsIn)) + { + return false; + } + if(this->AlreadyInCache) + { + // If the user specifies the entry on the command line without a + // type we should add the type and docstring but keep the original + // value. + if(this->AlreadyInCacheWithoutMetaInfo) + { + this->Makefile->AddCacheDefinition( + this->VariableName.c_str(), "", + this->VariableDocumentation.c_str(), + (this->IncludeFileInPath ? + cmCacheManager::FILEPATH :cmCacheManager::PATH) + ); + } + return true; + } + + std::string result = this->FindHeader(); + if(result.size() != 0) + { + this->Makefile->AddCacheDefinition + (this->VariableName.c_str(), result.c_str(), + this->VariableDocumentation.c_str(), + (this->IncludeFileInPath) ? + cmCacheManager::FILEPATH :cmCacheManager::PATH); + return true; + } + this->Makefile->AddCacheDefinition + (this->VariableName.c_str(), + (this->VariableName + "-NOTFOUND").c_str(), + this->VariableDocumentation.c_str(), + (this->IncludeFileInPath) ? + cmCacheManager::FILEPATH :cmCacheManager::PATH); + return true; +} + +//---------------------------------------------------------------------------- +std::string cmFindPathCommand::FindHeader() +{ + std::string header; + if(this->SearchFrameworkFirst || this->SearchFrameworkOnly) + { + header = this->FindFrameworkHeader(); + } + if(header.empty() && !this->SearchFrameworkOnly) + { + header = this->FindNormalHeader(); + } + if(header.empty() && this->SearchFrameworkLast) + { + header = this->FindFrameworkHeader(); + } + return header; +} + +std::string +cmFindPathCommand::FindHeaderInFramework(std::string const& file, + std::string const& dir) +{ + cmStdString fileName = file; + cmStdString frameWorkName; + cmStdString::size_type pos = fileName.find("/"); + // if there is a / in the name try to find the header as a framework + // For example bar/foo.h would look for: + // bar.framework/Headers/foo.h + if(pos != fileName.npos) + { + // remove the name from the slash; + fileName = fileName.substr(pos+1); + frameWorkName = file; + frameWorkName = + frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1); + // if the framework has a path in it then just use the filename + if(frameWorkName.find("/") != frameWorkName.npos) + { + fileName = file; + frameWorkName = ""; + } + if(frameWorkName.size()) + { + std::string fpath = dir; + fpath += frameWorkName; + fpath += ".framework"; + std::string intPath = fpath; + intPath += "/Headers/"; + intPath += fileName; + if(cmSystemTools::FileExists(intPath.c_str())) + { + if(this->IncludeFileInPath) + { + return intPath; + } + return fpath; + } + } + } + // if it is not found yet or not a framework header, then do a glob search + // for all frameworks in the directory: dir/*.framework/Headers/<file> + cmStdString glob = dir; + glob += "*.framework/Headers/"; + glob += file; + cmsys::Glob globIt; + globIt.FindFiles(glob); + std::vector<std::string> files = globIt.GetFiles(); + if(files.size()) + { + cmStdString fheader = cmSystemTools::CollapseFullPath(files[0].c_str()); + if(this->IncludeFileInPath) + { + return fheader; + } + fheader = cmSystemTools::GetFilenamePath(fheader); + return fheader; + } + return ""; +} + +//---------------------------------------------------------------------------- +std::string cmFindPathCommand::FindNormalHeader() +{ + std::string tryPath; + for(std::vector<std::string>::const_iterator ni = this->Names.begin(); + ni != this->Names.end() ; ++ni) + { + for(std::vector<std::string>::const_iterator + p = this->SearchPaths.begin(); + p != this->SearchPaths.end(); ++p) + { + tryPath = *p; + tryPath += *ni; + if(cmSystemTools::FileExists(tryPath.c_str())) + { + if(this->IncludeFileInPath) + { + return tryPath; + } + else + { + return *p; + } + } + } + } + return ""; +} + +//---------------------------------------------------------------------------- +std::string cmFindPathCommand::FindFrameworkHeader() +{ + for(std::vector<std::string>::const_iterator ni = this->Names.begin(); + ni != this->Names.end() ; ++ni) + { + for(std::vector<std::string>::const_iterator + p = this->SearchPaths.begin(); + p != this->SearchPaths.end(); ++p) + { + std::string fwPath = this->FindHeaderInFramework(*ni, *p); + if(!fwPath.empty()) + { + return fwPath; + } + } + } + return ""; +} |