Fix Xcode project references to the source tree
[cmake.git] / Source / cmFindPathCommand.cxx
blob4a16920edd6dddd75710b114b289340d14b99e45
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmFindPathCommand.cxx,v $
5 Language: C++
6 Date: $Date: 2008-06-09 16:51:01 $
7 Version: $Revision: 1.44 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmFindPathCommand.h"
18 #include "cmCacheManager.h"
20 #include <cmsys/Glob.hxx>
22 cmFindPathCommand::cmFindPathCommand()
24 this->EnvironmentPath = "INCLUDE";
25 this->IncludeFileInPath = false;
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,
31 "CMAKE_XXX_MAC_PATH",
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,
42 "SEARCH_XXX_DESC",
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 "CMAKE_FIND_ROOT_PATH_MODE_XXX",
50 "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE");
52 this->ExtraDocAdded = false;
55 const char* cmFindPathCommand::GetFullDocumentation()
57 if(!this->ExtraDocAdded && !this->IncludeFileInPath)
59 this->GenericDocumentation +=
60 "\n"
61 "When searching for frameworks, if the file is specified as "
62 "A/b.h, then the framework search will look for "
63 "A.framework/Headers/b.h. "
64 "If that is found the path will be set to the path to the framework. "
65 "CMake will convert this to the correct -F option to include the "
66 "file. ";
67 this->ExtraDocAdded = true;
69 return this->GenericDocumentation.c_str();
72 // cmFindPathCommand
73 bool cmFindPathCommand
74 ::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
76 this->VariableDocumentation = "Path to a file.";
77 this->CMakePathName = "INCLUDE";
78 if(!this->ParseArguments(argsIn))
80 return false;
82 if(this->AlreadyInCache)
84 // If the user specifies the entry on the command line without a
85 // type we should add the type and docstring but keep the original
86 // value.
87 if(this->AlreadyInCacheWithoutMetaInfo)
89 this->Makefile->AddCacheDefinition(
90 this->VariableName.c_str(), "",
91 this->VariableDocumentation.c_str(),
92 (this->IncludeFileInPath ?
93 cmCacheManager::FILEPATH :cmCacheManager::PATH)
96 return true;
99 std::string result = this->FindHeader();
100 if(result.size() != 0)
102 this->Makefile->AddCacheDefinition
103 (this->VariableName.c_str(), result.c_str(),
104 this->VariableDocumentation.c_str(),
105 (this->IncludeFileInPath) ?
106 cmCacheManager::FILEPATH :cmCacheManager::PATH);
107 return true;
109 this->Makefile->AddCacheDefinition
110 (this->VariableName.c_str(),
111 (this->VariableName + "-NOTFOUND").c_str(),
112 this->VariableDocumentation.c_str(),
113 (this->IncludeFileInPath) ?
114 cmCacheManager::FILEPATH :cmCacheManager::PATH);
115 return true;
118 //----------------------------------------------------------------------------
119 std::string cmFindPathCommand::FindHeader()
121 std::string header;
122 if(this->SearchFrameworkFirst || this->SearchFrameworkOnly)
124 header = this->FindFrameworkHeader();
126 if(header.empty() && !this->SearchFrameworkOnly)
128 header = this->FindNormalHeader();
130 if(header.empty() && this->SearchFrameworkLast)
132 header = this->FindFrameworkHeader();
134 return header;
137 std::string
138 cmFindPathCommand::FindHeaderInFramework(std::string const& file,
139 std::string const& dir)
141 cmStdString fileName = file;
142 cmStdString frameWorkName;
143 cmStdString::size_type pos = fileName.find("/");
144 // if there is a / in the name try to find the header as a framework
145 // For example bar/foo.h would look for:
146 // bar.framework/Headers/foo.h
147 if(pos != fileName.npos)
149 // remove the name from the slash;
150 fileName = fileName.substr(pos+1);
151 frameWorkName = file;
152 frameWorkName =
153 frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1);
154 // if the framework has a path in it then just use the filename
155 if(frameWorkName.find("/") != frameWorkName.npos)
157 fileName = file;
158 frameWorkName = "";
160 if(frameWorkName.size())
162 std::string fpath = dir;
163 fpath += frameWorkName;
164 fpath += ".framework";
165 std::string intPath = fpath;
166 intPath += "/Headers/";
167 intPath += fileName;
168 if(cmSystemTools::FileExists(intPath.c_str()))
170 if(this->IncludeFileInPath)
172 return intPath;
174 return fpath;
178 // if it is not found yet or not a framework header, then do a glob search
179 // for all frameworks in the directory: dir/*.framework/Headers/<file>
180 cmStdString glob = dir;
181 glob += "*.framework/Headers/";
182 glob += file;
183 cmsys::Glob globIt;
184 globIt.FindFiles(glob);
185 std::vector<std::string> files = globIt.GetFiles();
186 if(files.size())
188 cmStdString fheader = cmSystemTools::CollapseFullPath(files[0].c_str());
189 if(this->IncludeFileInPath)
191 return fheader;
193 fheader = cmSystemTools::GetFilenamePath(fheader);
194 return fheader;
196 return "";
199 //----------------------------------------------------------------------------
200 std::string cmFindPathCommand::FindNormalHeader()
202 std::string tryPath;
203 for(std::vector<std::string>::const_iterator ni = this->Names.begin();
204 ni != this->Names.end() ; ++ni)
206 for(std::vector<std::string>::const_iterator
207 p = this->SearchPaths.begin();
208 p != this->SearchPaths.end(); ++p)
210 tryPath = *p;
211 tryPath += *ni;
212 if(cmSystemTools::FileExists(tryPath.c_str()))
214 if(this->IncludeFileInPath)
216 return tryPath;
218 else
220 return *p;
225 return "";
228 //----------------------------------------------------------------------------
229 std::string cmFindPathCommand::FindFrameworkHeader()
231 for(std::vector<std::string>::const_iterator ni = this->Names.begin();
232 ni != this->Names.end() ; ++ni)
234 for(std::vector<std::string>::const_iterator
235 p = this->SearchPaths.begin();
236 p != this->SearchPaths.end(); ++p)
238 std::string fwPath = this->FindHeaderInFramework(*ni, *p);
239 if(!fwPath.empty())
241 return fwPath;
245 return "";