ENH: Adding support for automatically adding the OBJECT_DEPENDS for generated header files.
This commit is contained in:
parent
b3dd7f1d89
commit
f4920b8369
@ -21,18 +21,21 @@
|
|||||||
#include <ctype.h> // isspace
|
#include <ctype.h> // isspace
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmDependsC::cmDependsC()
|
cmDependsC::cmDependsC():
|
||||||
|
m_IncludePath(0), m_GeneratedFiles(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// yummy look at all those constructor arguments
|
// yummy look at all those constructor arguments
|
||||||
cmDependsC::cmDependsC(std::vector<std::string> const& includes,
|
cmDependsC::cmDependsC(std::vector<std::string> const& includes,
|
||||||
const char* scanRegex, const char* complainRegex):
|
const char* scanRegex, const char* complainRegex,
|
||||||
|
std::set<cmStdString> const& generatedFiles):
|
||||||
m_IncludePath(&includes),
|
m_IncludePath(&includes),
|
||||||
m_IncludeRegexLine("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)([\">])"),
|
m_IncludeRegexLine("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)([\">])"),
|
||||||
m_IncludeRegexScan(scanRegex),
|
m_IncludeRegexScan(scanRegex),
|
||||||
m_IncludeRegexComplain(complainRegex)
|
m_IncludeRegexComplain(complainRegex),
|
||||||
|
m_GeneratedFiles(&generatedFiles)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,13 +84,15 @@ bool cmDependsC::WriteDependencies(const char *src,
|
|||||||
std::string fullName;
|
std::string fullName;
|
||||||
if(first || cmSystemTools::FileIsFullPath(current.FileName.c_str()))
|
if(first || cmSystemTools::FileIsFullPath(current.FileName.c_str()))
|
||||||
{
|
{
|
||||||
if(cmSystemTools::FileExists(current.FileName.c_str()))
|
if(this->FileExistsOrIsGenerated(current.FileName, scanned,
|
||||||
|
dependencies))
|
||||||
{
|
{
|
||||||
fullName = current.FileName;
|
fullName = current.FileName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!current.QuotedLocation.empty() &&
|
else if(!current.QuotedLocation.empty() &&
|
||||||
cmSystemTools::FileExists(current.QuotedLocation.c_str()))
|
this->FileExistsOrIsGenerated(current.QuotedLocation, scanned,
|
||||||
|
dependencies))
|
||||||
{
|
{
|
||||||
// The include statement producing this entry was a double-quote
|
// The include statement producing this entry was a double-quote
|
||||||
// include and the included file is present in the directory of
|
// include and the included file is present in the directory of
|
||||||
@ -113,7 +118,7 @@ bool cmDependsC::WriteDependencies(const char *src,
|
|||||||
temp += current.FileName;
|
temp += current.FileName;
|
||||||
|
|
||||||
// Look for the file in this location.
|
// Look for the file in this location.
|
||||||
if(cmSystemTools::FileExists(temp.c_str()))
|
if(this->FileExistsOrIsGenerated(temp, scanned, dependencies))
|
||||||
{
|
{
|
||||||
fullName = temp;
|
fullName = temp;
|
||||||
break;
|
break;
|
||||||
@ -346,3 +351,28 @@ const char* cmDependsC::ParseFileName(const char* in, std::string& name)
|
|||||||
// Return the ending position.
|
// Return the ending position.
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmDependsC::FileExistsOrIsGenerated(const std::string& fname,
|
||||||
|
std::set<cmStdString>& scanned,
|
||||||
|
std::set<cmStdString>& dependencies)
|
||||||
|
{
|
||||||
|
// Check first for a generated file.
|
||||||
|
if(m_GeneratedFiles &&
|
||||||
|
m_GeneratedFiles->find(fname) != m_GeneratedFiles->end())
|
||||||
|
{
|
||||||
|
// If the file does not really exist yet pretend it has already
|
||||||
|
// been scanned. When it exists later then dependencies will be
|
||||||
|
// rescanned.
|
||||||
|
if(!cmSystemTools::FileExists(fname.c_str()))
|
||||||
|
{
|
||||||
|
scanned.insert(fname);
|
||||||
|
dependencies.insert(fname);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return cmSystemTools::FileExists(fname.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -31,7 +31,8 @@ public:
|
|||||||
relative path from the build directory to the target file. */
|
relative path from the build directory to the target file. */
|
||||||
cmDependsC();
|
cmDependsC();
|
||||||
cmDependsC(std::vector<std::string> const& includes,
|
cmDependsC(std::vector<std::string> const& includes,
|
||||||
const char* scanRegex, const char* complainRegex);
|
const char* scanRegex, const char* complainRegex,
|
||||||
|
std::set<cmStdString> const& generatedFiles);
|
||||||
|
|
||||||
/** Virtual destructor to cleanup subclasses properly. */
|
/** Virtual destructor to cleanup subclasses properly. */
|
||||||
virtual ~cmDependsC();
|
virtual ~cmDependsC();
|
||||||
@ -50,6 +51,11 @@ protected:
|
|||||||
std::string& dependee);
|
std::string& dependee);
|
||||||
const char* ParseFileName(const char* in, std::string& name);
|
const char* ParseFileName(const char* in, std::string& name);
|
||||||
|
|
||||||
|
// Method to test for the existence of a file.
|
||||||
|
bool FileExistsOrIsGenerated(const std::string& fname,
|
||||||
|
std::set<cmStdString>& scanned,
|
||||||
|
std::set<cmStdString>& dependencies);
|
||||||
|
|
||||||
// The include file search path.
|
// The include file search path.
|
||||||
std::vector<std::string> const* m_IncludePath;
|
std::vector<std::string> const* m_IncludePath;
|
||||||
|
|
||||||
@ -60,7 +66,10 @@ protected:
|
|||||||
// recursively and which to complain about not finding.
|
// recursively and which to complain about not finding.
|
||||||
cmsys::RegularExpression m_IncludeRegexScan;
|
cmsys::RegularExpression m_IncludeRegexScan;
|
||||||
cmsys::RegularExpression m_IncludeRegexComplain;
|
cmsys::RegularExpression m_IncludeRegexComplain;
|
||||||
|
|
||||||
|
// Set of generated files available.
|
||||||
|
std::set<cmStdString> const* m_GeneratedFiles;
|
||||||
|
|
||||||
// Data structures for dependency graph walk.
|
// Data structures for dependency graph walk.
|
||||||
struct UnscannedEntry
|
struct UnscannedEntry
|
||||||
{
|
{
|
||||||
|
@ -203,6 +203,8 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
|
|||||||
for(std::vector<std::string>::iterator i = includeDirs.begin();
|
for(std::vector<std::string>::iterator i = includeDirs.begin();
|
||||||
i != includeDirs.end(); ++i)
|
i != includeDirs.end(); ++i)
|
||||||
{
|
{
|
||||||
|
// Note: This path conversion must match that used for
|
||||||
|
// CMAKE_GENERATED_FILES so that the file names match.
|
||||||
infoFileStream
|
infoFileStream
|
||||||
<< " \"" << this->Convert(i->c_str(),HOME_OUTPUT).c_str() << "\"\n";
|
<< " \"" << this->Convert(i->c_str(),HOME_OUTPUT).c_str() << "\"\n";
|
||||||
}
|
}
|
||||||
@ -231,6 +233,30 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
|
|||||||
<< "SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN})\n";
|
<< "SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN})\n";
|
||||||
infoFileStream
|
infoFileStream
|
||||||
<< "SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN})\n";
|
<< "SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN})\n";
|
||||||
|
|
||||||
|
// Store the set of available generated files.
|
||||||
|
infoFileStream
|
||||||
|
<< "\n"
|
||||||
|
<< "# The set of files generated by rules in this directory:\n";
|
||||||
|
infoFileStream
|
||||||
|
<< "SET(CMAKE_GENERATED_FILES\n";
|
||||||
|
for(std::vector<cmSourceFile*>::const_iterator
|
||||||
|
i = m_Makefile->GetSourceFiles().begin();
|
||||||
|
i != m_Makefile->GetSourceFiles().end(); ++i)
|
||||||
|
{
|
||||||
|
cmSourceFile* src = *i;
|
||||||
|
if(src->GetPropertyAsBool("GENERATED"))
|
||||||
|
{
|
||||||
|
// Note: This path conversion must match that used for
|
||||||
|
// CMAKE_C_INCLUDE_PATH so that the file names match.
|
||||||
|
infoFileStream
|
||||||
|
<< " \""
|
||||||
|
<< this->Convert(src->GetFullPath().c_str(), HOME_OUTPUT)
|
||||||
|
<< "\"\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
infoFileStream
|
||||||
|
<< ")\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -546,6 +572,7 @@ cmLocalUnixMakefileGenerator3
|
|||||||
std::string objectFile = this->Convert(obj.c_str(),START_OUTPUT,SHELL);
|
std::string objectFile = this->Convert(obj.c_str(),START_OUTPUT,SHELL);
|
||||||
|
|
||||||
// Construct the build message.
|
// Construct the build message.
|
||||||
|
std::vector<std::string> no_commands;
|
||||||
std::vector<std::string> commands;
|
std::vector<std::string> commands;
|
||||||
std::string buildEcho = "Building ";
|
std::string buildEcho = "Building ";
|
||||||
buildEcho += lang;
|
buildEcho += lang;
|
||||||
@ -575,6 +602,22 @@ cmLocalUnixMakefileGenerator3
|
|||||||
flags.c_str());
|
flags.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add dependencies known at CMake time.
|
||||||
|
std::string relativeObjDeps = relativeObj;
|
||||||
|
relativeObjDeps += "/depend";
|
||||||
|
this->WriteMakeRule(ruleFileStream, 0,
|
||||||
|
relativeObjDeps.c_str(), depends, no_commands);
|
||||||
|
depends.clear();
|
||||||
|
depends.push_back(relativeObjDeps);
|
||||||
|
|
||||||
|
// Make the target dependency scanning rule include cmake-time-known
|
||||||
|
// dependencies. The others are handled by the check-build-system
|
||||||
|
// path.
|
||||||
|
std::string depMark = this->GetRelativeTargetDirectory(target);
|
||||||
|
depMark += "/depend.make.mark";
|
||||||
|
this->WriteMakeRule(ruleFileStream, 0,
|
||||||
|
depMark.c_str(), depends, no_commands);
|
||||||
|
|
||||||
// Write the rule.
|
// Write the rule.
|
||||||
this->WriteMakeRule(ruleFileStream, 0,
|
this->WriteMakeRule(ruleFileStream, 0,
|
||||||
relativeObj.c_str(), depends, commands);
|
relativeObj.c_str(), depends, commands);
|
||||||
@ -583,7 +626,6 @@ cmLocalUnixMakefileGenerator3
|
|||||||
// corresponding targets.
|
// corresponding targets.
|
||||||
std::string objectRequires = relativeObj;
|
std::string objectRequires = relativeObj;
|
||||||
objectRequires += ".requires";
|
objectRequires += ".requires";
|
||||||
std::vector<std::string> no_commands;
|
|
||||||
std::vector<std::string> p_depends;
|
std::vector<std::string> p_depends;
|
||||||
// always provide an empty requires target
|
// always provide an empty requires target
|
||||||
this->WriteMakeRule(ruleFileStream, 0,
|
this->WriteMakeRule(ruleFileStream, 0,
|
||||||
@ -2682,7 +2724,21 @@ cmLocalUnixMakefileGenerator3
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this->WriteDisclaimer(ruleFileStream);
|
this->WriteDisclaimer(ruleFileStream);
|
||||||
|
|
||||||
|
// Get the set of generated files.
|
||||||
|
std::vector<std::string> generatedFilesVec;
|
||||||
|
if(haveDirectoryInfo)
|
||||||
|
{
|
||||||
|
if(const char* generated = mf->GetDefinition("CMAKE_GENERATED_FILES"))
|
||||||
|
{
|
||||||
|
cmSystemTools::ExpandListArgument(generated, generatedFilesVec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort for efficient lookup.
|
||||||
|
std::set<cmStdString> generatedFiles(generatedFilesVec.begin(),
|
||||||
|
generatedFilesVec.end());
|
||||||
|
|
||||||
// for each language we need to scan, scan it
|
// for each language we need to scan, scan it
|
||||||
const char *langStr = mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES");
|
const char *langStr = mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES");
|
||||||
std::vector<std::string> langs;
|
std::vector<std::string> langs;
|
||||||
@ -2726,15 +2782,16 @@ cmLocalUnixMakefileGenerator3
|
|||||||
includeRegexComplain = complainRegex;
|
includeRegexComplain = complainRegex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the scanner for this language
|
// Create the scanner for this language
|
||||||
cmDepends *scanner = 0;
|
cmDepends *scanner = 0;
|
||||||
if(lang == "C" || lang == "CXX" || lang == "RC")
|
if(lang == "C" || lang == "CXX" || lang == "RC")
|
||||||
{
|
{
|
||||||
// TODO: Handle RC (resource files) dependencies correctly.
|
// TODO: Handle RC (resource files) dependencies correctly.
|
||||||
scanner = new cmDependsC(includes,
|
scanner = new cmDependsC(includes,
|
||||||
includeRegexScan.c_str(),
|
includeRegexScan.c_str(),
|
||||||
includeRegexComplain.c_str());
|
includeRegexComplain.c_str(),
|
||||||
|
generatedFiles);
|
||||||
}
|
}
|
||||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||||
else if(lang == "Fortran")
|
else if(lang == "Fortran")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user