CMake/Source/cmOutputRequiredFilesCommand.cxx

245 lines
7.2 KiB
C++
Raw Normal View History

/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
2001-06-12 15:08:25 +00:00
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
2001-06-12 15:08:25 +00:00
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
2001-06-12 15:08:25 +00:00
#include "cmOutputRequiredFilesCommand.h"
#include "cmMakeDepend.h"
#include <cmsys/FStream.hxx>
2001-06-12 15:08:25 +00:00
class cmLBDepend : public cmMakeDepend
{
/**
* Compute the depend information for this class.
*/
virtual void DependWalk(cmDependInformation* info);
2001-06-12 15:08:25 +00:00
};
void cmLBDepend::DependWalk(cmDependInformation* info)
2001-06-12 15:08:25 +00:00
{
cmsys::ifstream fin(info->FullPath.c_str());
2001-06-12 15:08:25 +00:00
if(!fin)
{
2006-03-15 16:02:08 +00:00
cmSystemTools::Error("error can not open ", info->FullPath.c_str());
2001-06-12 15:08:25 +00:00
return;
}
std::string line;
while(cmSystemTools::GetLineFromStream(fin, line))
2001-06-12 15:08:25 +00:00
{
2013-11-20 01:12:00 +00:00
if(cmHasLiteralPrefix(line.c_str(), "#include"))
2001-06-12 15:08:25 +00:00
{
// 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 ",
2001-06-12 15:08:25 +00:00
currentline.c_str() );
continue;
}
else
{
qend = currentline.find('>', qstart+1);
}
}
2001-06-12 15:08:25 +00:00
else
{
qend = currentline.find('\"', qstart+1);
}
2001-06-12 15:08:25 +00:00
// extract the file being included
std::string includeFile = currentline.substr(qstart+1, qend - qstart-1);
// see if the include matches the regular expression
2006-03-15 16:02:08 +00:00
if(!this->IncludeFileRegularExpression.find(includeFile))
{
2006-03-15 16:02:08 +00:00
if(this->Verbose)
{
2001-06-12 15:08:25 +00:00
std::string message = "Skipping ";
message += includeFile;
message += " for file ";
2006-03-15 16:02:08 +00:00
message += info->FullPath.c_str();
cmSystemTools::Error(message.c_str(), 0);
}
continue;
}
2001-06-12 15:08:25 +00:00
// 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 =
2006-03-15 16:02:08 +00:00
this->IncludeDirectories.begin();
i != this->IncludeDirectories.end(); ++i)
2001-06-12 15:08:25 +00:00
{
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 =
2006-03-15 16:02:08 +00:00
this->IncludeDirectories.begin();
i != this->IncludeDirectories.end(); ++i)
2001-06-12 15:08:25 +00:00
{
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 =
2006-03-15 16:02:08 +00:00
this->IncludeDirectories.begin();
i != this->IncludeDirectories.end(); ++i)
2001-06-12 15:08:25 +00:00
{
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 =
2006-03-15 16:02:08 +00:00
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;
}
}
}
2001-06-12 15:08:25 +00:00
if (found)
{
this->AddDependency(info, cxxFile.c_str());
}
}
}
}
}
// cmOutputRequiredFilesCommand
2006-05-12 17:39:34 +00:00
bool cmOutputRequiredFilesCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
2001-06-12 15:08:25 +00:00
{
if(this->Disallowed(cmPolicies::CMP0032,
"The output_required_files command should not be called; see CMP0032."))
{ return true; }
if(args.size() != 2 )
2001-06-12 15:08:25 +00:00
{
this->SetError("called with incorrect number of arguments");
return false;
}
// store the arg for final pass
2006-03-15 16:02:08 +00:00
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 = cmsys::SystemTools::Fopen(this->OutputFile.c_str(),"w");
if(!fout)
{
std::string err = "Can not open output file: ";
err += this->OutputFile;
this->SetError(err.c_str());
return false;
}
std::set<cmDependInformation const*> visited;
this->ListDependencies(info,fout, &visited);
fclose(fout);
}
2001-06-12 15:08:25 +00:00
return true;
}
2002-12-10 19:10:15 +00:00
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 =
2006-03-15 16:02:08 +00:00
info->DependencySet.begin();
d != info->DependencySet.end(); ++d)
2002-12-10 19:10:15 +00:00
{
if (visited->find(*d) == visited->end())
{
2006-03-15 16:02:08 +00:00
if(info->FullPath != "")
2002-12-10 19:10:15 +00:00
{
2006-03-15 16:02:08 +00:00
std::string tmp = (*d)->FullPath;
2002-12-10 19:10:15 +00:00
std::string::size_type pos = tmp.rfind('.');
if(pos != std::string::npos && (tmp.substr(pos) != ".h"))
2002-12-10 19:10:15 +00:00
{
tmp = tmp.substr(0, pos);
2006-03-15 16:02:08 +00:00
fprintf(fout,"%s\n",(*d)->FullPath.c_str());
2002-12-10 19:10:15 +00:00
}
}
this->ListDependencies(*d,fout,visited);
}
}
}