summaryrefslogtreecommitdiff
path: root/Source/cmFindPathCommand.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmFindPathCommand.cxx')
-rw-r--r--Source/cmFindPathCommand.cxx240
1 files changed, 240 insertions, 0 deletions
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
new file mode 100644
index 000000000..846d187cb
--- /dev/null
+++ b/Source/cmFindPathCommand.cxx
@@ -0,0 +1,240 @@
+/*============================================================================
+ 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", "");
+ 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 "";
+}