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(
49 this->GenericDocumentation,
50 "XXX_EXTRA_PREFIX_ENTRY",
51 " <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and\n");
52 cmSystemTools::ReplaceString(this->GenericDocumentation,
53 "CMAKE_FIND_ROOT_PATH_MODE_XXX",
54 "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE");
55 if(!this->IncludeFileInPath)
57 this->GenericDocumentation +=
59 "When searching for frameworks, if the file is specified as "
60 "A/b.h, then the framework search will look for "
61 "A.framework/Headers/b.h. "
62 "If that is found the path will be set to the path to the framework. "
63 "CMake will convert this to the correct -F option to include the "
69 bool cmFindPathCommand
70 ::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &)
72 this->VariableDocumentation = "Path to a file.";
73 this->CMakePathName = "INCLUDE";
74 if(!this->ParseArguments(argsIn))
78 if(this->AlreadyInCache)
80 // If the user specifies the entry on the command line without a
81 // type we should add the type and docstring but keep the original
83 if(this->AlreadyInCacheWithoutMetaInfo)
85 this->Makefile->AddCacheDefinition(
86 this->VariableName.c_str(), "",
87 this->VariableDocumentation.c_str(),
88 (this->IncludeFileInPath ?
89 cmCacheManager::FILEPATH :cmCacheManager::PATH)
95 std::string result = this->FindHeader();
96 if(result.size() != 0)
98 this->Makefile->AddCacheDefinition
99 (this->VariableName.c_str(), result.c_str(),
100 this->VariableDocumentation.c_str(),
101 (this->IncludeFileInPath) ?
102 cmCacheManager::FILEPATH :cmCacheManager::PATH);
105 this->Makefile->AddCacheDefinition
106 (this->VariableName.c_str(),
107 (this->VariableName + "-NOTFOUND").c_str(),
108 this->VariableDocumentation.c_str(),
109 (this->IncludeFileInPath) ?
110 cmCacheManager::FILEPATH :cmCacheManager::PATH);
114 //----------------------------------------------------------------------------
115 std::string cmFindPathCommand::FindHeader()
118 if(this->SearchFrameworkFirst || this->SearchFrameworkOnly)
120 header = this->FindFrameworkHeader();
122 if(header.empty() && !this->SearchFrameworkOnly)
124 header = this->FindNormalHeader();
126 if(header.empty() && this->SearchFrameworkLast)
128 header = this->FindFrameworkHeader();
134 cmFindPathCommand::FindHeaderInFramework(std::string const& file,
135 std::string const& dir)
137 cmStdString fileName = file;
138 cmStdString frameWorkName;
139 cmStdString::size_type pos = fileName.find("/");
140 // if there is a / in the name try to find the header as a framework
141 // For example bar/foo.h would look for:
142 // bar.framework/Headers/foo.h
143 if(pos != fileName.npos)
145 // remove the name from the slash;
146 fileName = fileName.substr(pos+1);
147 frameWorkName = file;
149 frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1);
150 // if the framework has a path in it then just use the filename
151 if(frameWorkName.find("/") != frameWorkName.npos)
156 if(frameWorkName.size())
158 std::string fpath = dir;
159 fpath += frameWorkName;
160 fpath += ".framework";
161 std::string intPath = fpath;
162 intPath += "/Headers/";
164 if(cmSystemTools::FileExists(intPath.c_str()))
166 if(this->IncludeFileInPath)
174 // if it is not found yet or not a framework header, then do a glob search
175 // for all frameworks in the directory: dir/*.framework/Headers/<file>
176 cmStdString glob = dir;
177 glob += "*.framework/Headers/";
180 globIt.FindFiles(glob);
181 std::vector<std::string> files = globIt.GetFiles();
184 cmStdString fheader = cmSystemTools::CollapseFullPath(files[0].c_str());
185 if(this->IncludeFileInPath)
189 fheader = cmSystemTools::GetFilenamePath(fheader);
195 //----------------------------------------------------------------------------
196 std::string cmFindPathCommand::FindNormalHeader()
199 for(std::vector<std::string>::const_iterator ni = this->Names.begin();
200 ni != this->Names.end() ; ++ni)
202 for(std::vector<std::string>::const_iterator
203 p = this->SearchPaths.begin();
204 p != this->SearchPaths.end(); ++p)
208 if(cmSystemTools::FileExists(tryPath.c_str()))
210 if(this->IncludeFileInPath)
224 //----------------------------------------------------------------------------
225 std::string cmFindPathCommand::FindFrameworkHeader()
227 for(std::vector<std::string>::const_iterator ni = this->Names.begin();
228 ni != this->Names.end() ; ++ni)
230 for(std::vector<std::string>::const_iterator
231 p = this->SearchPaths.begin();
232 p != this->SearchPaths.end(); ++p)
234 std::string fwPath = this->FindHeaderInFramework(*ni, *p);