1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmOutputRequiredFilesCommand.cxx,v $
6 Date: $Date: 2008-10-10 14:48:10 $
7 Version: $Revision: 1.17 $
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 "cmOutputRequiredFilesCommand.h"
18 #include "cmMakeDepend.h"
20 class cmLBDepend
: public cmMakeDepend
23 * Compute the depend information for this class.
25 virtual void DependWalk(cmDependInformation
* info
);
28 void cmLBDepend::DependWalk(cmDependInformation
* info
)
30 std::ifstream
fin(info
->FullPath
.c_str());
33 cmSystemTools::Error("error can not open ", info
->FullPath
.c_str());
38 while(cmSystemTools::GetLineFromStream(fin
, line
))
40 if(!strncmp(line
.c_str(), "#include", 8))
42 // if it is an include line then create a string class
43 std::string currentline
= line
;
44 size_t qstart
= currentline
.find('\"', 8);
46 // if a quote is not found look for a <
47 if(qstart
== std::string::npos
)
49 qstart
= currentline
.find('<', 8);
50 // if a < is not found then move on
51 if(qstart
== std::string::npos
)
53 cmSystemTools::Error("unknown include directive ",
54 currentline
.c_str() );
59 qend
= currentline
.find('>', qstart
+1);
64 qend
= currentline
.find('\"', qstart
+1);
66 // extract the file being included
67 std::string includeFile
= currentline
.substr(qstart
+1, qend
- qstart
-1);
68 // see if the include matches the regular expression
69 if(!this->IncludeFileRegularExpression
.find(includeFile
))
73 std::string message
= "Skipping ";
74 message
+= includeFile
;
75 message
+= " for file ";
76 message
+= info
->FullPath
.c_str();
77 cmSystemTools::Error(message
.c_str(), 0);
82 // Add this file and all its dependencies.
83 this->AddDependency(info
, includeFile
.c_str());
84 /// add the cxx file if it exists
85 std::string cxxFile
= includeFile
;
86 std::string::size_type pos
= cxxFile
.rfind('.');
87 if(pos
!= std::string::npos
)
89 std::string root
= cxxFile
.substr(0, pos
);
90 cxxFile
= root
+ ".cxx";
92 // try jumping to .cxx .cpp and .c in order
93 if(cmSystemTools::FileExists(cxxFile
.c_str()))
97 for(std::vector
<std::string
>::iterator i
=
98 this->IncludeDirectories
.begin();
99 i
!= this->IncludeDirectories
.end(); ++i
)
101 std::string path
= *i
;
103 path
= path
+ cxxFile
;
104 if(cmSystemTools::FileExists(path
.c_str()))
111 cxxFile
= root
+ ".cpp";
112 if(cmSystemTools::FileExists(cxxFile
.c_str()))
116 for(std::vector
<std::string
>::iterator i
=
117 this->IncludeDirectories
.begin();
118 i
!= this->IncludeDirectories
.end(); ++i
)
120 std::string path
= *i
;
122 path
= path
+ cxxFile
;
123 if(cmSystemTools::FileExists(path
.c_str()))
131 cxxFile
= root
+ ".c";
132 if(cmSystemTools::FileExists(cxxFile
.c_str()))
136 for(std::vector
<std::string
>::iterator i
=
137 this->IncludeDirectories
.begin();
138 i
!= this->IncludeDirectories
.end(); ++i
)
140 std::string path
= *i
;
142 path
= path
+ cxxFile
;
143 if(cmSystemTools::FileExists(path
.c_str()))
151 cxxFile
= root
+ ".txx";
152 if(cmSystemTools::FileExists(cxxFile
.c_str()))
156 for(std::vector
<std::string
>::iterator i
=
157 this->IncludeDirectories
.begin();
158 i
!= this->IncludeDirectories
.end(); ++i
)
160 std::string path
= *i
;
162 path
= path
+ cxxFile
;
163 if(cmSystemTools::FileExists(path
.c_str()))
171 this->AddDependency(info
, cxxFile
.c_str());
178 // cmOutputRequiredFilesCommand
179 bool cmOutputRequiredFilesCommand
180 ::InitialPass(std::vector
<std::string
> const& args
, cmExecutionStatus
&)
182 if(args
.size() != 2 )
184 this->SetError("called with incorrect number of arguments");
188 // store the arg for final pass
189 this->File
= args
[0];
190 this->OutputFile
= args
[1];
192 // compute the list of files
194 md
.SetMakefile(this->Makefile
);
195 md
.AddSearchPath(this->Makefile
->GetStartDirectory());
196 // find the depends for a file
197 const cmDependInformation
*info
= md
.FindDependencies(this->File
.c_str());
201 FILE *fout
= fopen(this->OutputFile
.c_str(),"w");
204 std::string err
= "Can not open output file: ";
205 err
+= this->OutputFile
;
206 this->SetError(err
.c_str());
209 std::set
<cmDependInformation
const*> visited
;
210 this->ListDependencies(info
,fout
, &visited
);
217 void cmOutputRequiredFilesCommand::
218 ListDependencies(cmDependInformation
const *info
,
220 std::set
<cmDependInformation
const*> *visited
)
222 // add info to the visited set
223 visited
->insert(info
);
224 // now recurse with info's dependencies
225 for(cmDependInformation::DependencySetType::const_iterator d
=
226 info
->DependencySet
.begin();
227 d
!= info
->DependencySet
.end(); ++d
)
229 if (visited
->find(*d
) == visited
->end())
231 if(info
->FullPath
!= "")
233 std::string tmp
= (*d
)->FullPath
;
234 std::string::size_type pos
= tmp
.rfind('.');
235 if(pos
!= std::string::npos
&& (tmp
.substr(pos
) != ".h"))
237 tmp
= tmp
.substr(0, pos
);
238 fprintf(fout
,"%s\n",(*d
)->FullPath
.c_str());
241 this->ListDependencies(*d
,fout
,visited
);