You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
7.0 KiB
239 lines
7.0 KiB
16 years ago
|
/*=========================================================================
|
||
|
|
||
|
Program: CMake - Cross-Platform Makefile Generator
|
||
|
Module: $RCSfile: cmOutputRequiredFilesCommand.cxx,v $
|
||
|
Language: C++
|
||
|
Date: $Date: 2008-01-23 15:27:59 $
|
||
|
Version: $Revision: 1.16 $
|
||
|
|
||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||
|
|
||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
PURPOSE. See the above copyright notices for more information.
|
||
|
|
||
|
=========================================================================*/
|
||
|
#include "cmOutputRequiredFilesCommand.h"
|
||
|
#include "cmMakeDepend.h"
|
||
|
|
||
|
class cmLBDepend : public cmMakeDepend
|
||
|
{
|
||
|
/**
|
||
|
* Compute the depend information for this class.
|
||
|
*/
|
||
|
virtual void DependWalk(cmDependInformation* info);
|
||
|
};
|
||
|
|
||
|
void cmLBDepend::DependWalk(cmDependInformation* info)
|
||
|
{
|
||
|
std::ifstream fin(info->FullPath.c_str());
|
||
|
if(!fin)
|
||
|
{
|
||
|
cmSystemTools::Error("error can not open ", info->FullPath.c_str());
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
std::string line;
|
||
|
while(cmSystemTools::GetLineFromStream(fin, line))
|
||
|
{
|
||
|
if(!strncmp(line.c_str(), "#include", 8))
|
||
|
{
|
||
|
// if it is an include line then create a string class
|
||
|
std::string currentline = line;
|
||
|
size_t qstart = currentline.find('\"', 8);
|
||
|
size_t qend;
|
||
|
// if a quote is not found look for a <
|
||
|
if(qstart == std::string::npos)
|
||
|
{
|
||
|
qstart = currentline.find('<', 8);
|
||
|
// if a < is not found then move on
|
||
|
if(qstart == std::string::npos)
|
||
|
{
|
||
|
cmSystemTools::Error("unknown include directive ",
|
||
|
currentline.c_str() );
|
||
|
continue;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
qend = currentline.find('>', qstart+1);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
qend = currentline.find('\"', qstart+1);
|
||
|
}
|
||
|
// extract the file being included
|
||
|
std::string includeFile = currentline.substr(qstart+1, qend - qstart-1);
|
||
|
// see if the include matches the regular expression
|
||
|
if(!this->IncludeFileRegularExpression.find(includeFile))
|
||
|
{
|
||
|
if(this->Verbose)
|
||
|
{
|
||
|
std::string message = "Skipping ";
|
||
|
message += includeFile;
|
||
|
message += " for file ";
|
||
|
message += info->FullPath.c_str();
|
||
|
cmSystemTools::Error(message.c_str(), 0);
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// Add this file and all its dependencies.
|
||
|
this->AddDependency(info, includeFile.c_str());
|
||
|
/// add the cxx file if it exists
|
||
|
std::string cxxFile = includeFile;
|
||
|
std::string::size_type pos = cxxFile.rfind('.');
|
||
|
if(pos != std::string::npos)
|
||
|
{
|
||
|
std::string root = cxxFile.substr(0, pos);
|
||
|
cxxFile = root + ".cxx";
|
||
|
bool found = false;
|
||
|
// try jumping to .cxx .cpp and .c in order
|
||
|
if(cmSystemTools::FileExists(cxxFile.c_str()))
|
||
|
{
|
||
|
found = true;
|
||
|
}
|
||
|
for(std::vector<std::string>::iterator i =
|
||
|
this->IncludeDirectories.begin();
|
||
|
i != this->IncludeDirectories.end(); ++i)
|
||
|
{
|
||
|
std::string path = *i;
|
||
|
path = path + "/";
|
||
|
path = path + cxxFile;
|
||
|
if(cmSystemTools::FileExists(path.c_str()))
|
||
|
{
|
||
|
found = true;
|
||
|
}
|
||
|
}
|
||
|
if (!found)
|
||
|
{
|
||
|
cxxFile = root + ".cpp";
|
||
|
if(cmSystemTools::FileExists(cxxFile.c_str()))
|
||
|
{
|
||
|
found = true;
|
||
|
}
|
||
|
for(std::vector<std::string>::iterator i =
|
||
|
this->IncludeDirectories.begin();
|
||
|
i != this->IncludeDirectories.end(); ++i)
|
||
|
{
|
||
|
std::string path = *i;
|
||
|
path = path + "/";
|
||
|
path = path + cxxFile;
|
||
|
if(cmSystemTools::FileExists(path.c_str()))
|
||
|
{
|
||
|
found = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!found)
|
||
|
{
|
||
|
cxxFile = root + ".c";
|
||
|
if(cmSystemTools::FileExists(cxxFile.c_str()))
|
||
|
{
|
||
|
found = true;
|
||
|
}
|
||
|
for(std::vector<std::string>::iterator i =
|
||
|
this->IncludeDirectories.begin();
|
||
|
i != this->IncludeDirectories.end(); ++i)
|
||
|
{
|
||
|
std::string path = *i;
|
||
|
path = path + "/";
|
||
|
path = path + cxxFile;
|
||
|
if(cmSystemTools::FileExists(path.c_str()))
|
||
|
{
|
||
|
found = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!found)
|
||
|
{
|
||
|
cxxFile = root + ".txx";
|
||
|
if(cmSystemTools::FileExists(cxxFile.c_str()))
|
||
|
{
|
||
|
found = true;
|
||
|
}
|
||
|
for(std::vector<std::string>::iterator i =
|
||
|
this->IncludeDirectories.begin();
|
||
|
i != this->IncludeDirectories.end(); ++i)
|
||
|
{
|
||
|
std::string path = *i;
|
||
|
path = path + "/";
|
||
|
path = path + cxxFile;
|
||
|
if(cmSystemTools::FileExists(path.c_str()))
|
||
|
{
|
||
|
found = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (found)
|
||
|
{
|
||
|
this->AddDependency(info, cxxFile.c_str());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// cmOutputRequiredFilesCommand
|
||
|
bool cmOutputRequiredFilesCommand
|
||
|
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
|
||
|
{
|
||
|
if(args.size() != 2 )
|
||
|
{
|
||
|
this->SetError("called with incorrect number of arguments");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// store the arg for final pass
|
||
|
this->File = args[0];
|
||
|
this->OutputFile = args[1];
|
||
|
|
||
|
// compute the list of files
|
||
|
cmLBDepend md;
|
||
|
md.SetMakefile(this->Makefile);
|
||
|
md.AddSearchPath(this->Makefile->GetStartDirectory());
|
||
|
// find the depends for a file
|
||
|
const cmDependInformation *info = md.FindDependencies(this->File.c_str());
|
||
|
if (info)
|
||
|
{
|
||
|
// write them out
|
||
|
FILE *fout = fopen(this->OutputFile.c_str(),"w");
|
||
|
std::set<cmDependInformation const*> visited;
|
||
|
this->ListDependencies(info,fout, &visited);
|
||
|
fclose(fout);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void cmOutputRequiredFilesCommand::
|
||
|
ListDependencies(cmDependInformation const *info,
|
||
|
FILE *fout,
|
||
|
std::set<cmDependInformation const*> *visited)
|
||
|
{
|
||
|
// add info to the visited set
|
||
|
visited->insert(info);
|
||
|
// now recurse with info's dependencies
|
||
|
for(cmDependInformation::DependencySetType::const_iterator d =
|
||
|
info->DependencySet.begin();
|
||
|
d != info->DependencySet.end(); ++d)
|
||
|
{
|
||
|
if (visited->find(*d) == visited->end())
|
||
|
{
|
||
|
if(info->FullPath != "")
|
||
|
{
|
||
|
std::string tmp = (*d)->FullPath;
|
||
|
std::string::size_type pos = tmp.rfind('.');
|
||
|
if(pos != std::string::npos && (tmp.substr(pos) != ".h"))
|
||
|
{
|
||
|
tmp = tmp.substr(0, pos);
|
||
|
fprintf(fout,"%s\n",(*d)->FullPath.c_str());
|
||
|
}
|
||
|
}
|
||
|
this->ListDependencies(*d,fout,visited);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|