BUG: fix some bad changes in progress calc
[cmake.git] / Source / cmFindPathCommand.cxx
blob8eb93c871431e65b62919ab817cafb22172db97f
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmFindPathCommand.cxx,v $
5 Language: C++
6 Date: $Date: 2008-01-23 15:27:59 $
7 Version: $Revision: 1.41 $
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;
98 std::string ff = this->Makefile->GetSafeDefinition("CMAKE_FIND_FRAMEWORK");
99 bool supportFrameworks = true;
100 if( ff.size() == 0 || ff == "NEVER" )
102 supportFrameworks = false;
104 std::string framework;
105 // Add a trailing slash to all paths to aid the search process.
106 for(std::vector<std::string>::iterator i = this->SearchPaths.begin();
107 i != this->SearchPaths.end(); ++i)
109 std::string& p = *i;
110 if(p.empty() || p[p.size()-1] != '/')
112 p += "/";
115 // Use the search path to find the file.
116 unsigned int k;
117 std::string result;
118 for(k=0; k < this->SearchPaths.size(); k++)
120 for(unsigned int j =0; j < this->Names.size(); ++j)
122 // if frameworks are supported try to find the header in a framework
123 std::string tryPath;
124 if(supportFrameworks)
126 tryPath = this->FindHeaderInFramework(this->Names[j],
127 this->SearchPaths[k]);
128 if(tryPath.size())
130 result = tryPath;
133 if(result.size() == 0)
135 tryPath = this->SearchPaths[k];
136 tryPath += this->Names[j];
137 if(cmSystemTools::FileExists(tryPath.c_str()))
139 if(this->IncludeFileInPath)
141 result = tryPath;
143 else
145 result = this->SearchPaths[k];
149 if(result.size() != 0)
151 this->Makefile->AddCacheDefinition
152 (this->VariableName.c_str(), result.c_str(),
153 this->VariableDocumentation.c_str(),
154 (this->IncludeFileInPath) ?
155 cmCacheManager::FILEPATH :cmCacheManager::PATH);
156 return true;
160 this->Makefile->AddCacheDefinition
161 (this->VariableName.c_str(),
162 (this->VariableName + "-NOTFOUND").c_str(),
163 this->VariableDocumentation.c_str(),
164 (this->IncludeFileInPath) ?
165 cmCacheManager::FILEPATH :cmCacheManager::PATH);
166 return true;
169 std::string cmFindPathCommand::FindHeaderInFramework(std::string& file,
170 std::string& dir)
172 cmStdString fileName = file;
173 cmStdString frameWorkName;
174 cmStdString::size_type pos = fileName.find("/");
175 // if there is a / in the name try to find the header as a framework
176 // For example bar/foo.h would look for:
177 // bar.framework/Headers/foo.h
178 if(pos != fileName.npos)
180 // remove the name from the slash;
181 fileName = fileName.substr(pos+1);
182 frameWorkName = file;
183 frameWorkName =
184 frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1);
185 // if the framework has a path in it then just use the filename
186 if(frameWorkName.find("/") != frameWorkName.npos)
188 fileName = file;
189 frameWorkName = "";
191 if(frameWorkName.size())
193 std::string fpath = dir;
194 fpath += frameWorkName;
195 fpath += ".framework";
196 std::string intPath = fpath;
197 intPath += "/Headers/";
198 intPath += fileName;
199 if(cmSystemTools::FileExists(intPath.c_str()))
201 if(this->IncludeFileInPath)
203 return intPath;
205 return fpath;
209 // if it is not found yet or not a framework header, then do a glob search
210 // for all files in dir/*/Headers/
211 cmStdString glob = dir;
212 glob += "*/Headers/";
213 glob += file;
214 cmsys::Glob globIt;
215 globIt.FindFiles(glob);
216 std::vector<std::string> files = globIt.GetFiles();
217 if(files.size())
219 cmStdString fheader = cmSystemTools::CollapseFullPath(files[0].c_str());
220 if(this->IncludeFileInPath)
222 return fheader;
224 fheader = cmSystemTools::GetFilenamePath(fheader);
225 return fheader;
227 return "";