summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmDependsC.cxx42
-rw-r--r--Source/cmDependsC.h13
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx67
3 files changed, 109 insertions, 13 deletions
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index 9653274..a17fb26 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -21,18 +21,21 @@
#include <ctype.h> // isspace
//----------------------------------------------------------------------------
-cmDependsC::cmDependsC()
+cmDependsC::cmDependsC():
+ m_IncludePath(0), m_GeneratedFiles(0)
{
}
//----------------------------------------------------------------------------
// yummy look at all those constructor arguments
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_IncludeRegexLine("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)([\">])"),
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;
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;
}
}
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
// include and the included file is present in the directory of
@@ -113,7 +118,7 @@ bool cmDependsC::WriteDependencies(const char *src,
temp += current.FileName;
// Look for the file in this location.
- if(cmSystemTools::FileExists(temp.c_str()))
+ if(this->FileExistsOrIsGenerated(temp, scanned, dependencies))
{
fullName = temp;
break;
@@ -346,3 +351,28 @@ const char* cmDependsC::ParseFileName(const char* in, std::string& name)
// Return the ending position.
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());
+ }
+}
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index fb2b29d..26cfc1b 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -31,7 +31,8 @@ public:
relative path from the build directory to the target file. */
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);
/** Virtual destructor to cleanup subclasses properly. */
virtual ~cmDependsC();
@@ -50,6 +51,11 @@ protected:
std::string& dependee);
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.
std::vector<std::string> const* m_IncludePath;
@@ -60,7 +66,10 @@ protected:
// recursively and which to complain about not finding.
cmsys::RegularExpression m_IncludeRegexScan;
cmsys::RegularExpression m_IncludeRegexComplain;
-
+
+ // Set of generated files available.
+ std::set<cmStdString> const* m_GeneratedFiles;
+
// Data structures for dependency graph walk.
struct UnscannedEntry
{
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 2fe763d..f688549 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -203,6 +203,8 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile()
for(std::vector<std::string>::iterator i = includeDirs.begin();
i != includeDirs.end(); ++i)
{
+ // Note: This path conversion must match that used for
+ // CMAKE_GENERATED_FILES so that the file names match.
infoFileStream
<< " \"" << 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";
infoFileStream
<< "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);
// Construct the build message.
+ std::vector<std::string> no_commands;
std::vector<std::string> commands;
std::string buildEcho = "Building ";
buildEcho += lang;
@@ -575,6 +602,22 @@ cmLocalUnixMakefileGenerator3
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.
this->WriteMakeRule(ruleFileStream, 0,
relativeObj.c_str(), depends, commands);
@@ -583,7 +626,6 @@ cmLocalUnixMakefileGenerator3
// corresponding targets.
std::string objectRequires = relativeObj;
objectRequires += ".requires";
- std::vector<std::string> no_commands;
std::vector<std::string> p_depends;
// always provide an empty requires target
this->WriteMakeRule(ruleFileStream, 0,
@@ -2682,7 +2724,21 @@ cmLocalUnixMakefileGenerator3
return false;
}
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
const char *langStr = mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES");
std::vector<std::string> langs;
@@ -2726,15 +2782,16 @@ cmLocalUnixMakefileGenerator3
includeRegexComplain = complainRegex;
}
}
-
+
// Create the scanner for this language
cmDepends *scanner = 0;
if(lang == "C" || lang == "CXX" || lang == "RC")
{
// TODO: Handle RC (resource files) dependencies correctly.
scanner = new cmDependsC(includes,
- includeRegexScan.c_str(),
- includeRegexComplain.c_str());
+ includeRegexScan.c_str(),
+ includeRegexComplain.c_str(),
+ generatedFiles);
}
#ifdef CMAKE_BUILD_WITH_CMAKE
else if(lang == "Fortran")