1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmFindPathCommand.cxx,v $
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
,
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 "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
+=
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 "
67 this->ExtraDocAdded
= true;
69 return this->GenericDocumentation
.c_str();
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
))
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
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
)
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
);
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
);
118 //----------------------------------------------------------------------------
119 std::string
cmFindPathCommand::FindHeader()
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();
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
;
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
)
160 if(frameWorkName
.size())
162 std::string fpath
= dir
;
163 fpath
+= frameWorkName
;
164 fpath
+= ".framework";
165 std::string intPath
= fpath
;
166 intPath
+= "/Headers/";
168 if(cmSystemTools::FileExists(intPath
.c_str()))
170 if(this->IncludeFileInPath
)
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/";
184 globIt
.FindFiles(glob
);
185 std::vector
<std::string
> files
= globIt
.GetFiles();
188 cmStdString fheader
= cmSystemTools::CollapseFullPath(files
[0].c_str());
189 if(this->IncludeFileInPath
)
193 fheader
= cmSystemTools::GetFilenamePath(fheader
);
199 //----------------------------------------------------------------------------
200 std::string
cmFindPathCommand::FindNormalHeader()
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
)
212 if(cmSystemTools::FileExists(tryPath
.c_str()))
214 if(this->IncludeFileInPath
)
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
);