1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #include "cmFindPathCommand.h"
13 #include "cmCacheManager.h"
15 #include <cmsys/Glob.hxx>
17 cmFindPathCommand::cmFindPathCommand()
19 this->EnvironmentPath = "INCLUDE";
20 this->IncludeFileInPath = false;
23 void cmFindPathCommand::GenerateDocumentation()
25 this->cmFindBase::GenerateDocumentation();
26 cmSystemTools::ReplaceString(this->GenericDocumentation,
27 "FIND_XXX", "find_path");
28 cmSystemTools::ReplaceString(this->GenericDocumentation,
29 "CMAKE_XXX_PATH", "CMAKE_INCLUDE_PATH");
30 cmSystemTools::ReplaceString(this->GenericDocumentation,
32 "CMAKE_FRAMEWORK_PATH");
33 cmSystemTools::ReplaceString(this->GenericDocumentation,
34 "CMAKE_SYSTEM_XXX_MAC_PATH",
35 "CMAKE_SYSTEM_FRAMEWORK_PATH");
36 cmSystemTools::ReplaceString(this->GenericDocumentation,
37 "XXX_SYSTEM", "INCLUDE");
38 cmSystemTools::ReplaceString(this->GenericDocumentation,
39 "CMAKE_SYSTEM_XXX_PATH",
40 "CMAKE_SYSTEM_INCLUDE_PATH");
41 cmSystemTools::ReplaceString(this->GenericDocumentation,
43 "directory containing the named file");
44 cmSystemTools::ReplaceString(this->GenericDocumentation,
45 "SEARCH_XXX", "file in a directory");
46 cmSystemTools::ReplaceString(this->GenericDocumentation,
47 "XXX_SUBDIR", "include");
48 cmSystemTools::ReplaceString(this->GenericDocumentation,
49 "XXX_EXTRA_PREFIX_ENTRY", "");
50 cmSystemTools::ReplaceString(this->GenericDocumentation,
51 "CMAKE_FIND_ROOT_PATH_MODE_XXX",
52 "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE");
53 if(!this->IncludeFileInPath)
55 this->GenericDocumentation +=
57 "When searching for frameworks, if the file is specified as "
58 "A/b.h, then the framework search will look for "
59 "A.framework/Headers/b.h. "
60 "If that is found the path will be set to the path to the framework. "
61 "CMake will convert this to the correct -F option to include the "
67 bool cmFindPathCommand
68 ::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
70 this->VariableDocumentation = "Path to a file.";
71 this->CMakePathName = "INCLUDE";
72 if(!this->ParseArguments(argsIn))
76 if(this->AlreadyInCache)
78 // If the user specifies the entry on the command line without a
79 // type we should add the type and docstring but keep the original
81 if(this->AlreadyInCacheWithoutMetaInfo)
83 this->Makefile->AddCacheDefinition(
84 this->VariableName.c_str(), "",
85 this->VariableDocumentation.c_str(),
86 (this->IncludeFileInPath ?
87 cmCacheManager::FILEPATH :cmCacheManager::PATH)
93 std::string result = this->FindHeader();
94 if(result.size() != 0)
96 this->Makefile->AddCacheDefinition
97 (this->VariableName.c_str(), result.c_str(),
98 this->VariableDocumentation.c_str(),
99 (this->IncludeFileInPath) ?
100 cmCacheManager::FILEPATH :cmCacheManager::PATH);
103 this->Makefile->AddCacheDefinition
104 (this->VariableName.c_str(),
105 (this->VariableName + "-NOTFOUND").c_str(),
106 this->VariableDocumentation.c_str(),
107 (this->IncludeFileInPath) ?
108 cmCacheManager::FILEPATH :cmCacheManager::PATH);
112 //----------------------------------------------------------------------------
113 std::string cmFindPathCommand::FindHeader()
116 if(this->SearchFrameworkFirst || this->SearchFrameworkOnly)
118 header = this->FindFrameworkHeader();
120 if(header.empty() && !this->SearchFrameworkOnly)
122 header = this->FindNormalHeader();
124 if(header.empty() && this->SearchFrameworkLast)
126 header = this->FindFrameworkHeader();
132 cmFindPathCommand::FindHeaderInFramework(std::string const& file,
133 std::string const& dir)
135 cmStdString fileName = file;
136 cmStdString frameWorkName;
137 cmStdString::size_type pos = fileName.find("/");
138 // if there is a / in the name try to find the header as a framework
139 // For example bar/foo.h would look for:
140 // bar.framework/Headers/foo.h
141 if(pos != fileName.npos)
143 // remove the name from the slash;
144 fileName = fileName.substr(pos+1);
145 frameWorkName = file;
147 frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1);
148 // if the framework has a path in it then just use the filename
149 if(frameWorkName.find("/") != frameWorkName.npos)
154 if(frameWorkName.size())
156 std::string fpath = dir;
157 fpath += frameWorkName;
158 fpath += ".framework";
159 std::string intPath = fpath;
160 intPath += "/Headers/";
162 if(cmSystemTools::FileExists(intPath.c_str()))
164 if(this->IncludeFileInPath)
172 // if it is not found yet or not a framework header, then do a glob search
173 // for all frameworks in the directory: dir/*.framework/Headers/<file>
174 cmStdString glob = dir;
175 glob += "*.framework/Headers/";
178 globIt.FindFiles(glob);
179 std::vector<std::string> files = globIt.GetFiles();
182 cmStdString fheader = cmSystemTools::CollapseFullPath(files[0].c_str());
183 if(this->IncludeFileInPath)
187 fheader = cmSystemTools::GetFilenamePath(fheader);
193 //----------------------------------------------------------------------------
194 std::string cmFindPathCommand::FindNormalHeader()
197 for(std::vector<std::string>::const_iterator ni = this->Names.begin();
198 ni != this->Names.end() ; ++ni)
200 for(std::vector<std::string>::const_iterator
201 p = this->SearchPaths.begin();
202 p != this->SearchPaths.end(); ++p)
206 if(cmSystemTools::FileExists(tryPath.c_str()))
208 if(this->IncludeFileInPath)
222 //----------------------------------------------------------------------------
223 std::string cmFindPathCommand::FindFrameworkHeader()
225 for(std::vector<std::string>::const_iterator ni = this->Names.begin();
226 ni != this->Names.end() ; ++ni)
228 for(std::vector<std::string>::const_iterator
229 p = this->SearchPaths.begin();
230 p != this->SearchPaths.end(); ++p)
232 std::string fwPath = this->FindHeaderInFramework(*ni, *p);