ENH: Implemented support for include/complain regular expressions for dependency scanning. This now includes the possibility that scanning will return failure and the build will stop.
This commit is contained in:
parent
c44e6d30e5
commit
337ad802c6
|
@ -42,7 +42,7 @@ cmDepends::~cmDepends()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmDepends::Write()
|
||||
bool cmDepends::Write()
|
||||
{
|
||||
// Try to generate dependencies for the target file.
|
||||
cmGeneratedFileStream fout(m_DependsMakeFile.c_str());
|
||||
|
@ -52,6 +52,11 @@ void cmDepends::Write()
|
|||
// Dependencies were generated. Touch the mark file.
|
||||
std::ofstream fmark(m_DependsMarkFile.c_str());
|
||||
fmark << "Dependencies updated for " << m_TargetFile.c_str() << std::endl;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
virtual ~cmDepends();
|
||||
|
||||
/** Write dependencies for the target file. */
|
||||
void Write();
|
||||
bool Write();
|
||||
|
||||
/** Check dependencies for the target file. */
|
||||
void Check();
|
||||
|
|
|
@ -23,18 +23,23 @@ cmDependsC::cmDependsC(const char* dir, const char* targetFile):
|
|||
cmDepends(dir, targetFile),
|
||||
m_SourceFile(),
|
||||
m_IncludePath(0),
|
||||
m_IncludeLineRegex()
|
||||
m_IncludeRegexLine(),
|
||||
m_IncludeRegexScan(),
|
||||
m_IncludeRegexComplain()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmDependsC::cmDependsC(const char* dir, const char* targetFile,
|
||||
const char* sourceFile,
|
||||
std::vector<std::string> const& includes):
|
||||
std::vector<std::string> const& includes,
|
||||
const char* scanRegex, const char* complainRegex):
|
||||
cmDepends(dir, targetFile),
|
||||
m_SourceFile(sourceFile),
|
||||
m_IncludePath(&includes),
|
||||
m_IncludeLineRegex("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)[\">]")
|
||||
m_IncludeRegexLine("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)[\">]"),
|
||||
m_IncludeRegexScan(scanRegex),
|
||||
m_IncludeRegexComplain(complainRegex)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -61,6 +66,7 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
|
|||
// Walk the dependency graph starting with the source file.
|
||||
bool first = true;
|
||||
m_Unscanned.push(m_SourceFile);
|
||||
m_Encountered.clear();
|
||||
m_Encountered.insert(m_SourceFile);
|
||||
std::set<cmStdString> dependencies;
|
||||
std::set<cmStdString> scanned;
|
||||
|
@ -74,7 +80,10 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
|
|||
std::string fullName;
|
||||
if(first || cmSystemTools::FileIsFullPath(fname.c_str()))
|
||||
{
|
||||
fullName = fname;
|
||||
if(cmSystemTools::FileExists(fname.c_str()))
|
||||
{
|
||||
fullName = fname;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -92,8 +101,16 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
|
|||
}
|
||||
}
|
||||
|
||||
// Complain if the file cannot be found and matches the complain
|
||||
// regex.
|
||||
if(fullName.empty() && m_IncludeRegexComplain.find(fname.c_str()))
|
||||
{
|
||||
cmSystemTools::Error("Cannot find file \"", fname.c_str(), "\".");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Scan the file if it was found and has not been scanned already.
|
||||
if(fullName.size() && (scanned.find(fullName) == scanned.end()))
|
||||
if(!fullName.empty() && (scanned.find(fullName) == scanned.end()))
|
||||
{
|
||||
// Record scanned files.
|
||||
scanned.insert(fullName);
|
||||
|
@ -113,7 +130,6 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
|
|||
|
||||
first = false;
|
||||
}
|
||||
m_Encountered.clear();
|
||||
|
||||
// Write the dependencies to the output stream.
|
||||
for(std::set<cmStdString>::iterator i=dependencies.begin();
|
||||
|
@ -228,16 +244,16 @@ void cmDependsC::Scan(std::istream& is)
|
|||
std::string line;
|
||||
while(cmSystemTools::GetLineFromStream(is, line))
|
||||
{
|
||||
// Match include directives. TODO: Support include regex and
|
||||
// ignore regex. Possibly also support directory-based inclusion
|
||||
// in dependencies.
|
||||
if(m_IncludeLineRegex.find(line.c_str()))
|
||||
// Match include directives.
|
||||
if(m_IncludeRegexLine.find(line.c_str()))
|
||||
{
|
||||
// Get the file being included.
|
||||
std::string includeFile = m_IncludeLineRegex.match(1);
|
||||
std::string includeFile = m_IncludeRegexLine.match(1);
|
||||
|
||||
// Queue the file if it has not yet been encountered.
|
||||
if(m_Encountered.find(includeFile) == m_Encountered.end())
|
||||
// Queue the file if it has not yet been encountered and it
|
||||
// matches the regular expression for recursive scanning.
|
||||
if(m_Encountered.find(includeFile) == m_Encountered.end() &&
|
||||
m_IncludeRegexScan.find(includeFile.c_str()))
|
||||
{
|
||||
m_Encountered.insert(includeFile);
|
||||
m_Unscanned.push(includeFile);
|
||||
|
|
|
@ -34,9 +34,10 @@ public:
|
|||
/** Scanning need to know the build directory name, the relative
|
||||
path from the build directory to the target file, the source
|
||||
file from which to start scanning, and the include file search
|
||||
path. */
|
||||
path. It also uses the include file regular expressions. */
|
||||
cmDependsC(const char* dir, const char* targetFile,
|
||||
const char* sourceFile, std::vector<std::string> const& includes);
|
||||
const char* sourceFile, std::vector<std::string> const& includes,
|
||||
const char* scanRegex, const char* complainRegex);
|
||||
|
||||
/** Virtual destructor to cleanup subclasses properly. */
|
||||
virtual ~cmDependsC();
|
||||
|
@ -56,7 +57,12 @@ protected:
|
|||
std::vector<std::string> const* m_IncludePath;
|
||||
|
||||
// Regular expression to identify C preprocessor include directives.
|
||||
cmsys::RegularExpression m_IncludeLineRegex;
|
||||
cmsys::RegularExpression m_IncludeRegexLine;
|
||||
|
||||
// Regular expressions to choose which include files to scan
|
||||
// recursively and which to complain about not finding.
|
||||
cmsys::RegularExpression m_IncludeRegexScan;
|
||||
cmsys::RegularExpression m_IncludeRegexComplain;
|
||||
|
||||
// Data structures for dependency graph walk.
|
||||
std::set<cmStdString> m_Encountered;
|
||||
|
|
|
@ -234,6 +234,7 @@ void cmLocalUnixMakefileGenerator2::GenerateCMakefile()
|
|||
<< "SET(CMAKE_MAKEFILE_OUTPUTS\n"
|
||||
<< " \"" << this->ConvertToRelativePath(makefileName.c_str()).c_str() << "\"\n"
|
||||
<< " \"" << this->ConvertToRelativePath(check.c_str()).c_str() << "\"\n"
|
||||
<< " \"CMakeDirectoryInformation.cmake\"\n"
|
||||
<< " )\n\n";
|
||||
|
||||
// Set the set of files to check for dependency integrity.
|
||||
|
@ -525,8 +526,7 @@ cmLocalUnixMakefileGenerator2
|
|||
// touch the corresponding depends file after scanning dependencies.
|
||||
cmOStringStream depCmd;
|
||||
// TODO: Account for source file properties and directory-level
|
||||
// definitions when scanning for dependencies. Also account for
|
||||
// include/ignore regular expressions.
|
||||
// definitions when scanning for dependencies.
|
||||
depCmd << "$(CMAKE_COMMAND) -E cmake_depends " << lang << " "
|
||||
<< this->ConvertToRelativeOutputPath(obj.c_str()) << " "
|
||||
<< this->ConvertToRelativeOutputPath(source.GetFullPath().c_str());
|
||||
|
@ -2854,20 +2854,41 @@ cmLocalUnixMakefileGenerator2
|
|||
}
|
||||
}
|
||||
|
||||
// Get the include file regular expression.
|
||||
std::string includeRegexScan = "^.*$";
|
||||
std::string includeRegexComplain = "^$";
|
||||
if(haveDirectoryInfo)
|
||||
{
|
||||
std::string scanRegexVar = "CMAKE_";
|
||||
scanRegexVar += lang;
|
||||
scanRegexVar += "_INCLUDE_REGEX_SCAN";
|
||||
if(const char* scanRegex = mf->GetDefinition(scanRegexVar.c_str()))
|
||||
{
|
||||
includeRegexScan = scanRegex;
|
||||
}
|
||||
std::string complainRegexVar = "CMAKE_";
|
||||
complainRegexVar += lang;
|
||||
complainRegexVar += "_INCLUDE_REGEX_COMPLAIN";
|
||||
if(const char* complainRegex = mf->GetDefinition(complainRegexVar.c_str()))
|
||||
{
|
||||
includeRegexComplain = complainRegex;
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch the scan for each language.
|
||||
if(lang == "C" || lang == "CXX" || lang == "RC")
|
||||
{
|
||||
// TODO: Handle RC (resource files) dependencies correctly.
|
||||
cmDependsC scanner(".", objFile, srcFile, includes);
|
||||
scanner.Write();
|
||||
return true;
|
||||
cmDependsC scanner(".", objFile, srcFile, includes,
|
||||
includeRegexScan.c_str(), includeRegexComplain.c_str());
|
||||
return scanner.Write();
|
||||
true;
|
||||
}
|
||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||
else if(lang == "Fortran")
|
||||
{
|
||||
cmDependsFortran scanner(".", objFile, srcFile, includes);
|
||||
scanner.Write();
|
||||
return true;
|
||||
return scanner.Write();
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue