1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmOutputRequiredFilesCommand.cxx,v $
6 <<<<<<< cmOutputRequiredFilesCommand.cxx
7 Date: $Date: 2008/01/23 15:27:59 $
8 Version: $Revision: 1.16 $
10 Date: $Date: 2008-10-10 14:48:10 $
11 Version: $Revision: 1.17 $
14 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
15 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
17 This software is distributed WITHOUT ANY WARRANTY; without even
18 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 PURPOSE. See the above copyright notices for more information.
21 =========================================================================*/
22 #include "cmOutputRequiredFilesCommand.h"
23 #include "cmMakeDepend.h"
25 class cmLBDepend
: public cmMakeDepend
28 * Compute the depend information for this class.
30 virtual void DependWalk(cmDependInformation
* info
);
33 void cmLBDepend::DependWalk(cmDependInformation
* info
)
35 std::ifstream
fin(info
->FullPath
.c_str());
38 cmSystemTools::Error("error can not open ", info
->FullPath
.c_str());
43 while(cmSystemTools::GetLineFromStream(fin
, line
))
45 if(!strncmp(line
.c_str(), "#include", 8))
47 // if it is an include line then create a string class
48 std::string currentline
= line
;
49 size_t qstart
= currentline
.find('\"', 8);
51 // if a quote is not found look for a <
52 if(qstart
== std::string::npos
)
54 qstart
= currentline
.find('<', 8);
55 // if a < is not found then move on
56 if(qstart
== std::string::npos
)
58 cmSystemTools::Error("unknown include directive ",
59 currentline
.c_str() );
64 qend
= currentline
.find('>', qstart
+1);
69 qend
= currentline
.find('\"', qstart
+1);
71 // extract the file being included
72 std::string includeFile
= currentline
.substr(qstart
+1, qend
- qstart
-1);
73 // see if the include matches the regular expression
74 if(!this->IncludeFileRegularExpression
.find(includeFile
))
78 std::string message
= "Skipping ";
79 message
+= includeFile
;
80 message
+= " for file ";
81 message
+= info
->FullPath
.c_str();
82 cmSystemTools::Error(message
.c_str(), 0);
87 // Add this file and all its dependencies.
88 this->AddDependency(info
, includeFile
.c_str());
89 /// add the cxx file if it exists
90 std::string cxxFile
= includeFile
;
91 std::string::size_type pos
= cxxFile
.rfind('.');
92 if(pos
!= std::string::npos
)
94 std::string root
= cxxFile
.substr(0, pos
);
95 cxxFile
= root
+ ".cxx";
97 // try jumping to .cxx .cpp and .c in order
98 if(cmSystemTools::FileExists(cxxFile
.c_str()))
102 for(std::vector
<std::string
>::iterator i
=
103 this->IncludeDirectories
.begin();
104 i
!= this->IncludeDirectories
.end(); ++i
)
106 std::string path
= *i
;
108 path
= path
+ cxxFile
;
109 if(cmSystemTools::FileExists(path
.c_str()))
116 cxxFile
= root
+ ".cpp";
117 if(cmSystemTools::FileExists(cxxFile
.c_str()))
121 for(std::vector
<std::string
>::iterator i
=
122 this->IncludeDirectories
.begin();
123 i
!= this->IncludeDirectories
.end(); ++i
)
125 std::string path
= *i
;
127 path
= path
+ cxxFile
;
128 if(cmSystemTools::FileExists(path
.c_str()))
136 cxxFile
= root
+ ".c";
137 if(cmSystemTools::FileExists(cxxFile
.c_str()))
141 for(std::vector
<std::string
>::iterator i
=
142 this->IncludeDirectories
.begin();
143 i
!= this->IncludeDirectories
.end(); ++i
)
145 std::string path
= *i
;
147 path
= path
+ cxxFile
;
148 if(cmSystemTools::FileExists(path
.c_str()))
156 cxxFile
= root
+ ".txx";
157 if(cmSystemTools::FileExists(cxxFile
.c_str()))
161 for(std::vector
<std::string
>::iterator i
=
162 this->IncludeDirectories
.begin();
163 i
!= this->IncludeDirectories
.end(); ++i
)
165 std::string path
= *i
;
167 path
= path
+ cxxFile
;
168 if(cmSystemTools::FileExists(path
.c_str()))
176 this->AddDependency(info
, cxxFile
.c_str());
183 // cmOutputRequiredFilesCommand
184 bool cmOutputRequiredFilesCommand
185 ::InitialPass(std::vector
<std::string
> const& args
, cmExecutionStatus
&)
187 if(args
.size() != 2 )
189 this->SetError("called with incorrect number of arguments");
193 // store the arg for final pass
194 this->File
= args
[0];
195 this->OutputFile
= args
[1];
197 // compute the list of files
199 md
.SetMakefile(this->Makefile
);
200 md
.AddSearchPath(this->Makefile
->GetStartDirectory());
201 // find the depends for a file
202 const cmDependInformation
*info
= md
.FindDependencies(this->File
.c_str());
206 FILE *fout
= fopen(this->OutputFile
.c_str(),"w");
209 std::string err
= "Can not open output file: ";
210 err
+= this->OutputFile
;
211 this->SetError(err
.c_str());
214 std::set
<cmDependInformation
const*> visited
;
215 this->ListDependencies(info
,fout
, &visited
);
222 void cmOutputRequiredFilesCommand::
223 ListDependencies(cmDependInformation
const *info
,
225 std::set
<cmDependInformation
const*> *visited
)
227 // add info to the visited set
228 visited
->insert(info
);
229 // now recurse with info's dependencies
230 for(cmDependInformation::DependencySetType::const_iterator d
=
231 info
->DependencySet
.begin();
232 d
!= info
->DependencySet
.end(); ++d
)
234 if (visited
->find(*d
) == visited
->end())
236 if(info
->FullPath
!= "")
238 std::string tmp
= (*d
)->FullPath
;
239 std::string::size_type pos
= tmp
.rfind('.');
240 if(pos
!= std::string::npos
&& (tmp
.substr(pos
) != ".h"))
242 tmp
= tmp
.substr(0, pos
);
243 fprintf(fout
,"%s\n",(*d
)->FullPath
.c_str());
246 this->ListDependencies(*d
,fout
,visited
);