summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/cmDepends.cxx78
-rw-r--r--Source/cmDepends.h32
-rw-r--r--Source/cmDependsC.cxx28
-rw-r--r--Source/cmDependsC.h19
-rw-r--r--Source/cmDependsFortran.cxx55
-rw-r--r--Source/cmDependsFortran.h5
-rw-r--r--Source/cmDependsJava.cxx14
-rw-r--r--Source/cmDependsJava.h11
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx71
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h7
-rw-r--r--Source/cmLocalGenerator.cxx20
-rw-r--r--Source/cmLocalGenerator.h3
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx572
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h29
-rw-r--r--Source/cmake.cxx2
15 files changed, 432 insertions, 514 deletions
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index 165eee0b21..01c6e11fb4 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -32,55 +32,14 @@ cmDepends::~cmDepends()
{
}
-void cmDepends::SetTargetFile(const char* dir, const char* targetFile,
- const char *markExt, const char *makeExt)
-{
- m_Directory = dir;
- m_TargetFile = targetFile;
-
- // Construct the path to the make and mark files. Append
- // appropriate extensions to their names.
- m_DependsMarkFile = dir;
- m_DependsMakeFile = dir;
- m_DependsMakeFile += "/";
- m_DependsMarkFile += "/";
- m_DependsMakeFile += m_TargetFile;
- m_DependsMarkFile += m_TargetFile;
- m_DependsMakeFile += makeExt;
- m_DependsMarkFile += markExt;
-
- if (!m_CompileDirectory.size())
- {
- m_CompileDirectory = dir;
- }
-}
-
-
//----------------------------------------------------------------------------
-bool cmDepends::Write()
+bool cmDepends::Write(const char *src, const char *obj, std::ostream &fout)
{
- // Dependency generation must always be done in the current working
- // directory.
- assert(m_Directory == ".");
-
- // Try to generate dependencies for the target file.
- cmGeneratedFileStream fout(m_DependsMakeFile.c_str());
- fout << "# Dependencies for " << m_TargetFile.c_str() << std::endl;
- if(this->WriteDependencies(fout) && fout)
- {
- // 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;
- }
+ return this->WriteDependencies(src, obj, fout);
}
//----------------------------------------------------------------------------
-void cmDepends::Check()
+void cmDepends::Check(const char *file)
{
// Dependency checks must be done in proper working directory.
std::string oldcwd = ".";
@@ -93,11 +52,11 @@ void cmDepends::Check()
}
// Check whether dependencies must be regenerated.
- std::ifstream fin(m_DependsMakeFile.c_str());
+ std::ifstream fin(file);
if(!(fin && this->CheckDependencies(fin)))
{
// Clear all dependencies so they will be regenerated.
- this->Clear();
+ this->Clear(file);
}
// Restore working directory.
@@ -108,37 +67,26 @@ void cmDepends::Check()
}
//----------------------------------------------------------------------------
-void cmDepends::Clear()
+void cmDepends::Clear(const char *file)
{
// Print verbose output.
if(m_Verbose)
{
cmOStringStream msg;
- msg << "Clearing dependencies for \"" << m_TargetFile << "\"." << std::endl;
+ msg << "Clearing dependencies in \"" << file << "\"." << std::endl;
cmSystemTools::Stdout(msg.str().c_str());
}
// Remove the dependency mark file to be sure dependencies will be
// regenerated.
- cmSystemTools::RemoveFile(m_DependsMarkFile.c_str());
-
+ std::string markFile = file;
+ markFile += ".mark";
+ cmSystemTools::RemoveFile(markFile.c_str());
+
// Write an empty dependency file.
- cmGeneratedFileStream depFileStream(m_DependsMakeFile.c_str());
+ cmGeneratedFileStream depFileStream(file);
depFileStream
- << "# Empty dependencies file for " << m_TargetFile.c_str() << ".\n"
+ << "# Empty dependencies file\n"
<< "# This may be replaced when dependencies are built." << std::endl;
}
-//----------------------------------------------------------------------------
-const char* cmDepends::GetMakeFileName()
-{
- // Skip over the directory part of the name.
- return m_DependsMakeFile.c_str() + m_Directory.length() + 1;
-}
-
-//----------------------------------------------------------------------------
-const char* cmDepends::GetMarkFileName()
-{
- // Skip over the directory part of the name.
- return m_DependsMarkFile.c_str() + m_Directory.length() + 1;
-}
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
index d659af6452..0ccd812bc1 100644
--- a/Source/cmDepends.h
+++ b/Source/cmDepends.h
@@ -33,10 +33,6 @@ public:
path from the build directory to the target file. */
cmDepends();
- /** set the name directory and extensions of the target file to scan */
- void SetTargetFile(const char* dir, const char* targetFile,
- const char *markExt, const char *makeExt);
-
/** at what level will the compile be done from */
void SetCompileDirectory(const char *dir) {m_CompileDirectory = dir;};
@@ -47,44 +43,30 @@ public:
virtual ~cmDepends();
/** Write dependencies for the target file. */
- bool Write();
-
+ bool Write(const char *src, const char *obj, std::ostream &os);
+
/** Check dependencies for the target file. */
- void Check();
+ void Check(const char *file);
/** Clear dependencies for the target file so they will be regenerated. */
- void Clear();
-
- /** Get the name of the dependency make file. */
- const char* GetMakeFileName();
-
- /** Get the name of the dependency mark file. */
- const char* GetMarkFileName();
+ void Clear(const char *file);
protected:
// Write dependencies for the target file to the given stream.
// Return true for success and false for failure.
- virtual bool WriteDependencies(std::ostream& os)=0;
+ virtual bool WriteDependencies(const char *src,
+ const char* obj, std::ostream& os)=0;
// Check dependencies for the target file in the given stream.
// Return false if dependencies must be regenerated and true
// otherwise.
- virtual bool CheckDependencies(std::istream& is)=0;
+ virtual bool CheckDependencies(std::istream& is) = 0;
// The directory in which the build rule for the target file is executed.
std::string m_Directory;
std::string m_CompileDirectory;
- // The name of the target file for which dependencies are maintained.
- std::string m_TargetFile;
-
- // The name of the .depends.make file corresponding to the target.
- std::string m_DependsMakeFile;
-
- // The name of the .depends file marking when dependencies were generated.
- std::string m_DependsMarkFile;
-
// Flag for verbose output.
bool m_Verbose;
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index 056c13c993..6d317a92cf 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -27,10 +27,8 @@ cmDependsC::cmDependsC()
//----------------------------------------------------------------------------
// yummy look at all those constructor arguments
-cmDependsC::cmDependsC(const char* sourceFile,
- std::vector<std::string> const& includes,
+cmDependsC::cmDependsC(std::vector<std::string> const& includes,
const char* scanRegex, const char* complainRegex):
- m_SourceFile(sourceFile),
m_IncludePath(&includes),
m_IncludeRegexLine("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)([\">])"),
m_IncludeRegexScan(scanRegex),
@@ -44,12 +42,18 @@ cmDependsC::~cmDependsC()
}
//----------------------------------------------------------------------------
-bool cmDependsC::WriteDependencies(std::ostream& os)
+bool cmDependsC::WriteDependencies(const char *src,
+ const char *obj, std::ostream& os)
{
// Make sure this is a scanning instance.
- if(m_SourceFile == "")
+ if(!src || src[0] == '\0')
{
- cmSystemTools::Error("Cannot scan dependencies without an source file.");
+ cmSystemTools::Error("Cannot scan dependencies without a source file.");
+ return false;
+ }
+ if(!obj || obj[0] == '\0')
+ {
+ cmSystemTools::Error("Cannot scan dependencies without an object file.");
return false;
}
if(!m_IncludePath)
@@ -61,10 +65,10 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
// Walk the dependency graph starting with the source file.
bool first = true;
UnscannedEntry root;
- root.FileName = m_SourceFile;
+ root.FileName = src;
m_Unscanned.push(root);
m_Encountered.clear();
- m_Encountered.insert(m_SourceFile);
+ m_Encountered.insert(src);
std::set<cmStdString> dependencies;
std::set<cmStdString> scanned;
while(!m_Unscanned.empty())
@@ -155,7 +159,7 @@ bool cmDependsC::WriteDependencies(std::ostream& os)
for(std::set<cmStdString>::iterator i=dependencies.begin();
i != dependencies.end(); ++i)
{
- os << m_TargetFile.c_str() << ": "
+ os << obj << ": "
<< cmSystemTools::ConvertToOutputPath(i->c_str()).c_str()
<< std::endl;
}
@@ -313,8 +317,12 @@ const char* cmDependsC::ParseFileName(const char* in, std::string& name)
bool quoted = false;
char* buf = new char[strlen(in)+1];
char* pos = buf;
+
+ // for every character while we haven't hit the end of the string AND we
+ // are in a quoted string OR the current character isn't a : or the second
+ // character AND it isn't a space
for(;*c && (quoted ||
- ((*c != ':' || pos > buf+1) && !isspace(*c))); ++c)
+ ((*c != ':' || pos > buf) && !isspace(*c))); ++c)
{
if(*c == '"')
{
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index 2f16d7719c..fb2b29d81b 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -30,22 +30,16 @@ public:
/** Checking instances need to know the build directory name and the
relative path from the build directory to the target file. */
cmDependsC();
-
- /** 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. It also uses the include file regular expressions.
- This is a good example of why constructors should not take arguments.
- */
- cmDependsC(const char* sourceFile, std::vector<std::string> const& includes,
+ cmDependsC(std::vector<std::string> const& includes,
const char* scanRegex, const char* complainRegex);
/** Virtual destructor to cleanup subclasses properly. */
virtual ~cmDependsC();
-
+
protected:
// Implement writing/checking methods required by superclass.
- virtual bool WriteDependencies(std::ostream& os);
+ virtual bool WriteDependencies(const char *src,
+ const char *file, std::ostream& os);
virtual bool CheckDependencies(std::istream& is);
// Method to scan a single file.
@@ -56,9 +50,6 @@ protected:
std::string& dependee);
const char* ParseFileName(const char* in, std::string& name);
- // The source file from which to start scanning.
- std::string m_SourceFile;
-
// The include file search path.
std::vector<std::string> const* m_IncludePath;
@@ -69,7 +60,7 @@ protected:
// recursively and which to complain about not finding.
cmsys::RegularExpression m_IncludeRegexScan;
cmsys::RegularExpression m_IncludeRegexComplain;
-
+
// Data structures for dependency graph walk.
struct UnscannedEntry
{
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 4a9ac100c6..ec60a8f0b9 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -77,15 +77,12 @@ struct cmDependsFortranParser_s
//----------------------------------------------------------------------------
cmDependsFortran::cmDependsFortran():
- m_SourceFile(),
m_IncludePath(0)
{
}
//----------------------------------------------------------------------------
-cmDependsFortran::cmDependsFortran(const char* sourceFile,
- std::vector<std::string> const& includes):
- m_SourceFile(sourceFile),
+cmDependsFortran::cmDependsFortran(std::vector<std::string> const& includes):
m_IncludePath(&includes)
{
}
@@ -96,14 +93,20 @@ cmDependsFortran::~cmDependsFortran()
}
//----------------------------------------------------------------------------
-bool cmDependsFortran::WriteDependencies(std::ostream& os)
+bool cmDependsFortran::WriteDependencies(const char *src,
+ const char *obj, std::ostream& os)
{
// Make sure this is a scanning instance.
- if(m_SourceFile == "")
+ if(!src || src[0] == '\0')
{
cmSystemTools::Error("Cannot scan dependencies without an source file.");
return false;
}
+ if(!obj || obj[0] == '\0')
+ {
+ cmSystemTools::Error("Cannot scan dependencies without an object file.");
+ return false;
+ }
if(!m_IncludePath)
{
cmSystemTools::Error("Cannot scan dependencies without an include path.");
@@ -114,7 +117,7 @@ bool cmDependsFortran::WriteDependencies(std::ostream& os)
cmDependsFortranParser parser(this);
// Push on the starting file.
- cmDependsFortranParser_FilePush(&parser, m_SourceFile.c_str());
+ cmDependsFortranParser_FilePush(&parser, src);
// Parse the translation unit.
if(cmDependsFortran_yyparse(parser.Scanner) != 0)
@@ -127,7 +130,7 @@ bool cmDependsFortran::WriteDependencies(std::ostream& os)
for(std::set<cmStdString>::const_iterator i = parser.Includes.begin();
i != parser.Includes.end(); ++i)
{
- os << m_TargetFile.c_str() << ": "
+ os << obj << ": "
<< cmSystemTools::ConvertToOutputPath(i->c_str()).c_str()
<< std::endl;
}
@@ -141,25 +144,8 @@ bool cmDependsFortran::WriteDependencies(std::ostream& os)
if(parser.Provides.find(*i) == parser.Provides.end())
{
// since we require some things add them to our list of requirements
- os << m_TargetFile.c_str() << ".requires: " << i->c_str() << ".mod.proxy"
+ os << obj << ".requires: " << i->c_str() << ".mod.proxy"
<< std::endl;
-#if 0
- // Always use lower case for the mod stamp file name.
- std::string m = cmSystemTools::LowerCase(*i);
- os << m_TargetFile.c_str() << ": " << m.c_str() << ".mod.stamp"
- << std::endl;
- os << i->c_str() << ".mod.proxy:" << std::endl;
- std::string stampName = m_Directory;
- stampName += "/";
- stampName += m;
- stampName += ".mod.stamp";
- if(!cmSystemTools::FileExists(stampName.c_str()))
- {
- std::ofstream stamp(stampName.c_str());
- stamp << "# Dummy stamp file in case nothing provides it."
- << std::endl;
- }
-#endif
}
}
@@ -167,14 +153,14 @@ bool cmDependsFortran::WriteDependencies(std::ostream& os)
for(std::set<cmStdString>::const_iterator i = parser.Provides.begin();
i != parser.Provides.end(); ++i)
{
- os << i->c_str() << ".mod.proxy: " << m_TargetFile.c_str()
+ os << i->c_str() << ".mod.proxy: " << obj
<< ".provides" << std::endl;
}
// If any modules are provided then they must be converted to stamp files.
if(!parser.Provides.empty())
{
- os << m_TargetFile.c_str() << ".provides.build:\n";
+ os << obj << ".provides.build:\n";
for(std::set<cmStdString>::const_iterator i = parser.Provides.begin();
i != parser.Provides.end(); ++i)
{
@@ -185,20 +171,9 @@ bool cmDependsFortran::WriteDependencies(std::ostream& os)
os << "\t$(CMAKE_COMMAND) -E cmake_copy_f90_mod "
<< i->c_str() << " " << m.c_str() << ".mod.stamp\n";
}
- os << "\t@touch " << m_TargetFile.c_str() << ".provides.build\n";
+ os << "\t@touch " << obj << ".provides.build\n";
}
-#if 0
- // if it provides something then connect the requires rule to the build rule
- if(!parser.Provides.empty())
- {
- os << m_TargetFile.c_str() << ".requires: " << m_TargetFile.c_str()
- << ".requires.build" << std::endl;
- // provide empty build rule for old gen for now, TODO remove later
- os << m_TargetFile.c_str() << ".requires.build:" << std::endl;
- }
-#endif
-
/*
// TODO:
What about .mod files provided in another directory and found with a
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index 98db772e42..bc22eeab42 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -33,7 +33,7 @@ public:
path from the build directory to the target file, the source
file from which to start scanning, and the include file search
path. */
- cmDependsFortran(const char* sourceFile, std::vector<std::string> const& includes);
+ cmDependsFortran(std::vector<std::string> const& includes);
/** Virtual destructor to cleanup subclasses properly. */
virtual ~cmDependsFortran();
@@ -51,7 +51,8 @@ public:
protected:
// Implement writing/checking methods required by superclass.
- virtual bool WriteDependencies(std::ostream& os);
+ virtual bool WriteDependencies(const char *src,
+ const char *file, std::ostream& os);
virtual bool CheckDependencies(std::istream& is);
// The source file from which to start scanning.
diff --git a/Source/cmDependsJava.cxx b/Source/cmDependsJava.cxx
index ae4e5251da..7e80e31057 100644
--- a/Source/cmDependsJava.cxx
+++ b/Source/cmDependsJava.cxx
@@ -20,14 +20,7 @@
#include "cmSystemTools.h"
//----------------------------------------------------------------------------
-cmDependsJava::cmDependsJava():
- m_SourceFile()
-{
-}
-
-//----------------------------------------------------------------------------
-cmDependsJava::cmDependsJava(const char* sourceFile):
- m_SourceFile(sourceFile)
+cmDependsJava::cmDependsJava()
{
}
@@ -37,10 +30,11 @@ cmDependsJava::~cmDependsJava()
}
//----------------------------------------------------------------------------
-bool cmDependsJava::WriteDependencies(std::ostream&)
+bool cmDependsJava::WriteDependencies(const char *src,
+ const char *file, std::ostream&)
{
// Make sure this is a scanning instance.
- if(m_SourceFile == "")
+ if(!src || src[0] == '\0')
{
cmSystemTools::Error("Cannot scan dependencies without an source file.");
return false;
diff --git a/Source/cmDependsJava.h b/Source/cmDependsJava.h
index 69466fc043..473567dedb 100644
--- a/Source/cmDependsJava.h
+++ b/Source/cmDependsJava.h
@@ -29,22 +29,15 @@ public:
relative path from the build directory to the target file. */
cmDependsJava();
- /** Scanning need to know the build directory name, the relative
- path from the build directory to the target file and the source
- file to scan. */
- cmDependsJava(const char* sourceFile);
-
/** Virtual destructor to cleanup subclasses properly. */
virtual ~cmDependsJava();
protected:
// Implement writing/checking methods required by superclass.
- virtual bool WriteDependencies(std::ostream& os);
+ virtual bool WriteDependencies(const char *src,
+ const char *file, std::ostream& os);
virtual bool CheckDependencies(std::istream& is);
- // The source file from which to start scanning.
- std::string m_SourceFile;
-
private:
cmDependsJava(cmDependsJava const&); // Purposely not implemented.
void operator=(cmDependsJava const&); // Purposely not implemented.
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 2627afde5f..e550c2c7e7 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -328,67 +328,34 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
}
cmakefileStream << " )\n\n";
- this->WriteMainCMakefileLanguageRules(cmakefileStream);
+ this->WriteMainCMakefileLanguageRules(cmakefileStream, m_LocalGenerators);
}
void cmGlobalUnixMakefileGenerator3
-::WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream)
+::WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream,
+ std::vector<cmLocalGenerator *> &lGenerators)
{
cmLocalUnixMakefileGenerator3 *lg;
- // now write all the language stuff
- // Set the set of files to check for dependency integrity.
- // loop over all of the local generators to collect this
- std::set<cmStdString> checkSetLangs;
- for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i)
- {
- lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
- std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>& checkSet =
- lg->GetIntegrityCheckSet();
- for(std::map<cmStdString,
- cmLocalUnixMakefileGenerator3::IntegrityCheckSet>::const_iterator
- l = checkSet.begin(); l != checkSet.end(); ++l)
- {
- checkSetLangs.insert(l->first);
- }
- }
-
- // list the languages
+ // now list all the target info files
cmakefileStream
<< "# The set of files whose dependency integrity should be checked:\n";
cmakefileStream
- << "SET(CMAKE_DEPENDS_LANGUAGES\n";
- for(std::set<cmStdString>::iterator
- l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
+ << "SET(CMAKE_DEPEND_INFO_FILES\n";
+ for (unsigned int i = 0; i < lGenerators.size(); ++i)
{
- cmakefileStream << " \"" << l->c_str() << "\"\n";
- }
- cmakefileStream << " )\n";
-
- // now list the files for each language
- for(std::set<cmStdString>::iterator
- l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
- {
- cmakefileStream
- << "SET(CMAKE_DEPENDS_CHECK_" << l->c_str() << "\n";
- // now for each local gen get the checkset
- for (unsigned int i = 0; i < m_LocalGenerators.size(); ++i)
+ lg = static_cast<cmLocalUnixMakefileGenerator3 *>(lGenerators[i]);
+ // for all of out targets
+ for (cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
+ l != lg->GetMakefile()->GetTargets().end(); l++)
{
- lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
- // get the check set for this local gen and language
- cmLocalUnixMakefileGenerator3::IntegrityCheckSet iCheckSet =
- lg->GetIntegrityCheckSet()[*l];
- // for each file
- for(cmLocalUnixMakefileGenerator3::IntegrityCheckSet::const_iterator csIter =
- iCheckSet.begin();
- csIter != iCheckSet.end(); ++csIter)
- {
- cmakefileStream << " \"" <<
- lg->Convert(csIter->c_str(),cmLocalGenerator::HOME_OUTPUT).c_str() << "\"\n";
- }
+ std::string tname = lg->GetRelativeTargetDirectory(l->second);
+ tname += "/DependInfo.cmake";
+ cmSystemTools::ConvertToUnixSlashes(tname);
+ cmakefileStream << " \"" << tname.c_str() << "\"\n";
}
- cmakefileStream << " )\n";
}
+ cmakefileStream << " )\n";
}
//----------------------------------------------------------------------------
@@ -768,7 +735,6 @@ cmGlobalUnixMakefileGenerator3
// for each target Generate the rule files for each target.
cmTargets& targets = lg->GetMakefile()->GetTargets();
- bool needRequiresStep = this->NeedRequiresStep(lg);
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
{
if (((t->second.GetType() == cmTarget::EXECUTABLE) ||
@@ -779,6 +745,8 @@ cmGlobalUnixMakefileGenerator3
t->second.GetName() &&
strlen(t->second.GetName()))
{
+ bool needRequiresStep =
+ this->NeedRequiresStep(lg,t->second.GetName());
// Add a rule to build the target by name.
localName = lg->GetRelativeTargetDirectory(t->second);
std::string makefileName = localName;
@@ -1006,10 +974,10 @@ cmGlobalUnixMakefileGenerator3::WriteHelpRule(std::ostream& ruleFileStream)
bool cmGlobalUnixMakefileGenerator3
-::NeedRequiresStep(cmLocalUnixMakefileGenerator3 *lg)
+::NeedRequiresStep(cmLocalUnixMakefileGenerator3 *lg,const char *name)
{
std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>&
- checkSet = lg->GetIntegrityCheckSet();
+ checkSet = lg->GetIntegrityCheckSet()[name];
for(std::map<cmStdString,
cmLocalUnixMakefileGenerator3::IntegrityCheckSet>::const_iterator
l = checkSet.begin(); l != checkSet.end(); ++l)
@@ -1022,6 +990,5 @@ bool cmGlobalUnixMakefileGenerator3
return true;
}
}
-
return false;
}
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index a17c389fbf..aebc086c48 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -83,12 +83,15 @@ public:
* requests that they Generate.
*/
virtual void Generate();
+
+
+ void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream,
+ std::vector<cmLocalGenerator *> &);
protected:
void WriteMainMakefile();
void WriteMainMakefile2();
void WriteMainCMakefile();
- void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream);
void WriteAllRules(cmLocalUnixMakefileGenerator3 *lg,
std::ostream& makefileStream);
void WriteHelpRule(std::ostream& ruleFileStream);
@@ -111,7 +114,7 @@ protected:
const char* name, std::set<cmStdString>& emitted);
// does this generator need a requires step for any of its targets
- bool NeedRequiresStep(cmLocalUnixMakefileGenerator3 *lg);
+ bool NeedRequiresStep(cmLocalUnixMakefileGenerator3 *lg, const char *);
};
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index eb36a4f32c..4f620a92b1 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -62,6 +62,17 @@ void cmLocalGenerator::Configure()
}
}
+ this->SetupPathConversions();
+
+ // Check whether relative paths should be used for optionally
+ // relative paths.
+ m_UseRelativePaths = m_Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS");
+
+ this->Configured = true;
+}
+
+void cmLocalGenerator::SetupPathConversions()
+{
// Setup the current output directory components for use by
// Convert
std::string outdir;
@@ -76,15 +87,10 @@ void cmLocalGenerator::Configure()
cmSystemTools::SplitPath(outdir.c_str(), m_HomeOutputDirectoryComponents);
outdir =
cmSystemTools::CollapseFullPath(m_Makefile->GetStartOutputDirectory());
- cmSystemTools::SplitPath(outdir.c_str(), m_StartOutputDirectoryComponents);
-
- // Check whether relative paths should be used for optionally
- // relative paths.
- m_UseRelativePaths = m_Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS");
-
- this->Configured = true;
+cmSystemTools::SplitPath(outdir.c_str(), m_StartOutputDirectoryComponents);
}
+
void cmLocalGenerator::SetGlobalGenerator(cmGlobalGenerator *gg)
{
m_GlobalGenerator = gg;
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index b5809fd656..3c88e62cc4 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -97,6 +97,9 @@ public:
OutputFormat output = UNCHANGED,
bool optional = false);
+ ///! Call this prior to using Convert
+ void SetupPathConversions();
+
/**
* Convert the given path to an output path that is optionally
* relative based on the cache option CMAKE_USE_RELATIVE_PATHS. The
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 736ca83ae4..d5d939ca8b 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -18,7 +18,7 @@
#include "cmDepends.h"
#include "cmGeneratedFileStream.h"
-#include "cmGlobalGenerator.h"
+#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmake.h"
@@ -174,23 +174,18 @@ void cmLocalUnixMakefileGenerator3
// Generate the rule files for each custom command.
// get the classes from the source lists then add them to the groups
const std::vector<cmSourceFile*> &classes = target.GetSourceFiles();
- std::string objTarget;
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); i++)
{
if(cmCustomCommand* cc = (*i)->GetCustomCommand())
{
cc->Used();
- objTarget = this->GenerateCustomRuleFile(*cc,tgtDir.c_str());
+ this->GenerateCustomRuleFile(*cc,tgtDir.c_str(),ruleFileStream);
if (clean)
{
cleanFiles.push_back
(this->Convert(cc->GetOutput(),HOME_OUTPUT,SHELL));
}
- ruleFileStream
- << m_IncludeDirective << " "
- << this->ConvertToOutputForExisting(objTarget.c_str()).c_str()
- << "\n";
}
}
}
@@ -309,6 +304,49 @@ cmLocalUnixMakefileGenerator3
std::string dir = this->GetTargetDirectory(target);
cmSystemTools::MakeDirectory(this->ConvertToFullPath(dir).c_str());
+ // Generate the build-time dependencies file for this target.
+ std::string depBase = dir;
+ depBase += "/";
+ depBase += target.GetName();
+
+ // Construct the rule file name.
+ std::string ruleFileName = dir;
+ ruleFileName += "/build.make";
+
+ // Open the rule file. This should be copy-if-different because the
+ // rules may depend on this file itself.
+ std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
+ cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
+ ruleFileStream.SetCopyIfDifferent(true);
+ if(!ruleFileStream)
+ {
+ return;
+ }
+ this->WriteDisclaimer(ruleFileStream);
+
+ this->WriteMakeVariables(ruleFileStream, HOME_OUTPUT);
+
+ // Include the dependencies for the target.
+ std::string depPath = dir;
+ depPath += "/depend.make";
+ depPath = this->ConvertToFullPath(depPath.c_str());
+ depPath = this->Convert(depPath.c_str(),HOME_OUTPUT,MAKEFILE);
+ ruleFileStream
+ << "# Include any dependencies generated for this target.\n"
+ << m_IncludeDirective << " "
+ << depPath
+ << "\n\n";
+
+ // make sure the depend file exists
+ if (!cmSystemTools::FileExists(depPath.c_str()))
+ {
+ // Write an empty dependency file.
+ cmGeneratedFileStream depFileStream(depPath.c_str());
+ depFileStream
+ << "# Empty dependencies file for " << target.GetName() << ".\n"
+ << "# This may be replaced when dependencies are built." << std::endl;
+ }
+
// First generate the object rule files. Save a list of all object
// files for this target.
std::vector<std::string> objects;
@@ -323,7 +361,8 @@ cmLocalUnixMakefileGenerator3
if(!m_GlobalGenerator->IgnoreFile((*source)->GetSourceExtension().c_str()))
{
// Generate this object file's rule file.
- this->WriteObjectRuleFiles(target, *(*source), objects);
+ this->WriteObjectRuleFiles(target, *(*source), objects,
+ ruleFileStream);
}
else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT"))
{
@@ -332,28 +371,6 @@ cmLocalUnixMakefileGenerator3
}
}
}
-
- // Generate the build-time dependencies file for this target.
- std::string depBase = dir;
- depBase += "/";
- depBase += target.GetName();
-
- // Construct the rule file name.
- std::string ruleFileName = dir;
- ruleFileName += "/build.make";
-
- // Open the rule file. This should be copy-if-different because the
- // rules may depend on this file itself.
- std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
- cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
- ruleFileStream.SetCopyIfDifferent(true);
- if(!ruleFileStream)
- {
- return;
- }
- this->WriteDisclaimer(ruleFileStream);
-
- this->WriteMakeVariables(ruleFileStream, HOME_OUTPUT);
// write the custom commands for this target
std::vector<std::string> cleanFiles;
@@ -368,24 +385,6 @@ cmLocalUnixMakefileGenerator3
// Include the rule file for each object.
std::string relPath = this->GetHomeRelativeOutputPath();
std::string objTarget;
- if(!objects.empty())
- {
- ruleFileStream
- << "# Include make rules for object files.\n";
- for(std::vector<std::string>::const_iterator obj = objects.begin();
- obj != objects.end(); ++obj)
- {
- objTarget = relPath;
- objTarget += *obj;
- objTarget += ".build.make";
- ruleFileStream
- << m_IncludeDirective << " "
- << this->ConvertToOutputForExisting(objTarget.c_str()).c_str()
- << "\n";
- }
- ruleFileStream
- << "\n";
- }
// Write the rule for this target type.
switch(target.GetType())
@@ -427,20 +426,10 @@ cmLocalUnixMakefileGenerator3
::WriteObjectDependRules(std::ostream& ruleFileStream,
std::string &obj,
const char * lang,
- const cmSourceFile& source,
+ cmSourceFile& source,
std::vector<std::string>& depends,
std::string& depMakeFile)
{
- // Generate the build-time dependencies file for this object file.
- std::string depMarkFile;
- if(!this->GenerateDependsMakeFile(lang, obj.c_str(),
- depMakeFile, depMarkFile))
- {
- cmSystemTools::Error("No dependency checker available for language \"",
- lang, "\".");
- return;
- }
-
// Create the list of dependencies known at cmake time. These are
// shared between the object file and dependency scanning rule.
depends.push_back(source.GetFullPath());
@@ -454,40 +443,6 @@ cmLocalUnixMakefileGenerator3
depends.push_back(i->c_str());
}
}
-
- // Write the dependency generation rule.
- std::string relativeObj = this->GetHomeRelativeOutputPath();
- relativeObj += obj;
- std::vector<std::string> commands;
- std::string depEcho = "Scanning ";
- depEcho += lang;
- depEcho += " dependencies of ";
- depEcho += this->Convert(relativeObj.c_str(),NONE,SHELL);
- this->AppendEcho(commands, depEcho.c_str());
-
- // Add a command to call CMake to scan dependencies. CMake will
- // touch the corresponding depends file after scanning dependencies.
- cmOStringStream depCmd;
- // TODO: Account for source file properties and directory-level
- // definitions when scanning for dependencies.
- depCmd << "$(CMAKE_COMMAND) -E cmake_depends "
- << " \""
- << m_GlobalGenerator->GetName() << "\" "
- << this->Convert(m_Makefile->GetHomeOutputDirectory(),FULL,SHELL)
- << " "
- << this->Convert(m_Makefile->GetStartOutputDirectory(),FULL,SHELL)
- << " "
- << lang << " "
- << relativeObj.c_str() << " "
- << this->Convert(source.GetFullPath().c_str(),HOME_OUTPUT,SHELL);
- commands.push_back(depCmd.str());
-
- // compute the target
- std::string relPath = this->GetHomeRelativeOutputPath();
- relPath += depMarkFile;
- // Write the rule.
- this->WriteMakeRule(ruleFileStream, 0,
- relPath.c_str(), depends, commands);
}
@@ -497,24 +452,16 @@ cmLocalUnixMakefileGenerator3
::WriteObjectBuildFile(std::string &obj,
const char *lang,
cmTarget& target,
- const cmSourceFile& source,
+ cmSourceFile& source,
std::vector<std::string>& depends,
- std::string &depMakeFile)
+ std::string &depMakeFile,
+ std::ostream &ruleFileStream)
{
// Open the rule file for writing. This should be copy-if-different
// because the rules may depend on this file itself.
- std::string ruleFileName = obj;
- ruleFileName += ".build.make";
+ std::string ruleFileName = this->GetTargetDirectory(target);
+ ruleFileName += "/build.make";
std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
- cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
- ruleFileStream.SetCopyIfDifferent(true);
- if(!ruleFileStream)
- {
- return;
- }
- this->WriteDisclaimer(ruleFileStream);
- ruleFileStream
- << "# Rule file for object file " << obj.c_str() << ".\n\n";
// generate the depend scanning rule
this->WriteObjectDependRules(ruleFileStream, obj, lang, source,
@@ -522,16 +469,6 @@ cmLocalUnixMakefileGenerator3
this->AppendRuleDepend(depends, ruleFileNameFull.c_str());
- // Include the dependencies for the target.
- std::string depPath = this->GetHomeRelativeOutputPath();
- depPath += depMakeFile;
- depMakeFile = this->Convert(depPath.c_str(),HOME_OUTPUT,MAKEFILE);
- ruleFileStream
- << "# Include any dependencies generated for this rule.\n"
- << m_IncludeDirective << " "
- << depMakeFile
- << "\n\n";
-
// Write the build rule.
// Build the set of compiler flags.
std::string flags;
@@ -649,8 +586,9 @@ cmLocalUnixMakefileGenerator3
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator3
-::WriteObjectRuleFiles(cmTarget& target, const cmSourceFile& source,
- std::vector<std::string>& objects)
+::WriteObjectRuleFiles(cmTarget& target, cmSourceFile& source,
+ std::vector<std::string>& objects,
+ std::ostream &ruleFileStream)
{
// Identify the language of the source file.
const char* lang = this->GetSourceFileLanguage(source);
@@ -698,50 +636,25 @@ cmLocalUnixMakefileGenerator3
std::string depMakeFile;
// generate the build rule file
- this->WriteObjectBuildFile(obj, lang, target, source, depends, depMakeFile);
+ this->WriteObjectBuildFile(obj, lang, target, source, depends, depMakeFile,
+ ruleFileStream);
// The object file should be checked for dependency integrity.
- m_CheckDependFiles[lang].insert(relativeObj);
-
+ m_CheckDependFiles[target.GetName()][lang].insert(&source);
+
// add this to the list of objects for this local generator
m_LocalObjectFiles[cmSystemTools::GetFilenameName(obj)].push_back(&target);
}
//----------------------------------------------------------------------------
-std::string
+void
cmLocalUnixMakefileGenerator3
-::GenerateCustomRuleFile(const cmCustomCommand& cc, const char *dir)
+::GenerateCustomRuleFile(const cmCustomCommand& cc, const char *dir,
+ std::ostream &ruleFileStream)
{
// Convert the output name to a relative path if possible.
std::string output = this->Convert(cc.GetOutput(),START_OUTPUT);
- // Construct the name of the rule file by transforming the output
- // name to a valid file name. Since the output is already a file
- // everything but the path characters is valid.
- std::string customName = output;
- cmSystemTools::ReplaceString(customName, "../", "___");
- cmSystemTools::ReplaceString(customName, "/", "_");
- cmSystemTools::ReplaceString(customName, ":", "_");
- std::string ruleFileName = dir;
- ruleFileName += "/";
- ruleFileName += customName;
- ruleFileName += ".build.make";
-
- // what is the relative path to the rule file
- std::string relRuleFile = this->Convert(ruleFileName.c_str(),HOME_OUTPUT);
-
- // Open the rule file. This should be copy-if-different because the
- // rules may depend on this file itself.
- cmGeneratedFileStream ruleFileStream(ruleFileName.c_str());
- ruleFileStream.SetCopyIfDifferent(true);
- if(!ruleFileStream)
- {
- return relRuleFile;
- }
- this->WriteDisclaimer(ruleFileStream);
- ruleFileStream
- << "# Custom command rule file for " << output.c_str() << ".\n\n";
-
// Collect the commands.
std::vector<std::string> commands;
std::string preEcho = "Generating ";
@@ -753,9 +666,6 @@ cmLocalUnixMakefileGenerator3
std::vector<std::string> depends;
this->AppendCustomDepend(depends, cc);
- // Add a dependency on the rule file itself.
- this->AppendRuleDepend(depends, relRuleFile.c_str());
-
// Write the rule.
const char* comment = 0;
if(cc.GetComment() && *cc.GetComment())
@@ -764,8 +674,6 @@ cmLocalUnixMakefileGenerator3
}
this->WriteMakeRule(ruleFileStream, comment,
cc.GetOutput(), depends, commands);
-
- return relRuleFile;
}
//----------------------------------------------------------------------------
@@ -850,19 +758,17 @@ cmLocalUnixMakefileGenerator3
{
// Construct a checker for the given language.
std::auto_ptr<cmDepends>
- checker(this->GetDependsChecker(lang,
- m_Makefile->GetStartOutputDirectory(),
- objFile, false));
+ checker(this->GetDependsChecker(lang,false));
if(checker.get())
{
- // Save the make and mark file names.
- depMakeFile = checker->GetMakeFileName();
- depMarkFile = checker->GetMarkFileName();
-
// Check the dependencies. Ths is required because we need at least an
// empty foo.obj.depends.make for make to include, so at cmake time the
// ::Check() method will generate that if it does not exist
- checker->Check();
+
+
+ // Todo: could just make sure that file exists,
+ // use different method not check
+ checker->Check(objFile);
return true;
}
@@ -1885,13 +1791,62 @@ cmLocalUnixMakefileGenerator3
cmTarget& target,
const std::vector<std::string>& objects)
{
+ // must write the targets depend info file
+ std::string dir = this->GetTargetDirectory(target);
+ std::string infoFileName = dir;
+ infoFileName += "/DependInfo.cmake";
+ std::string ruleFileNameFull = this->ConvertToFullPath(infoFileName);
+ cmGeneratedFileStream infoFileStream(ruleFileNameFull.c_str());
+ infoFileStream.SetCopyIfDifferent(true);
+ if(!infoFileStream)
+ {
+ return;
+ }
+ cmGlobalUnixMakefileGenerator3 *gg =
+ static_cast<cmGlobalUnixMakefileGenerator3 *>(m_GlobalGenerator);
+ this->WriteDependLanguageInfo(infoFileStream,target);
+
+ // and now write the rule to use it
std::vector<std::string> depends;
- std::vector<std::string> no_commands;
+ std::vector<std::string> commands;
// Construct the name of the dependency generation target.
std::string depTarget = this->GetRelativeTargetDirectory(target);
depTarget += "/depend";
+
+ std::string depMark = depTarget;
+ depMark += ".make.mark";
+ depends.push_back(depMark);
+
+ this->WriteMakeRule(ruleFileStream, 0,
+ depTarget.c_str(), depends, commands);
+ depends.clear();
+
+ // Write the dependency generation rule.
+ std::string depEcho = "Scanning dependencies of target ";
+ depEcho += target.GetName();
+ this->AppendEcho(commands, depEcho.c_str());
+
+ // Add a command to call CMake to scan dependencies. CMake will
+ // touch the corresponding depends file after scanning dependencies.
+ cmOStringStream depCmd;
+ // TODO: Account for source file properties and directory-level
+ // definitions when scanning for dependencies.
+ depCmd << "$(CMAKE_COMMAND) -E cmake_depends "
+ << " \""
+ << m_GlobalGenerator->GetName() << "\" "
+ << this->Convert(m_Makefile->GetHomeOutputDirectory(),FULL,SHELL)
+ << " "
+ << this->Convert(m_Makefile->GetStartOutputDirectory(),FULL,SHELL)
+ << " "
+ << this->Convert(ruleFileNameFull.c_str(),FULL,SHELL);
+ commands.push_back(depCmd.str());
+
+ // Write the rule.
+ this->WriteMakeRule(ruleFileStream, 0,
+ depMark.c_str(), depends, commands);
+#if 0
// This target drives dependency generation for all object files.
std::string relPath = this->GetHomeRelativeOutputPath();
std::string objTarget;
@@ -1903,10 +1858,7 @@ cmLocalUnixMakefileGenerator3
objTarget += ".depend";
depends.push_back(objTarget);
}
-
- // Write the rule.
- this->WriteMakeRule(ruleFileStream, 0,
- depTarget.c_str(), depends, no_commands);
+#endif
}
//----------------------------------------------------------------------------
@@ -2632,8 +2584,6 @@ cmLocalUnixMakefileGenerator3
//----------------------------------------------------------------------------
cmDepends*
cmLocalUnixMakefileGenerator3::GetDependsChecker(const std::string& lang,
- const char* dir,
- const char* objFile,
bool verbose)
{
cmDepends *ret = 0;
@@ -2653,8 +2603,6 @@ cmLocalUnixMakefileGenerator3::GetDependsChecker(const std::string& lang,
#endif
if (ret)
{
- ret->SetTargetFile(dir, objFile, ".depend",".build.depend.make");
- ret->SetCompileDirectory(m_Makefile->GetHomeOutputDirectory());
ret->SetVerbose(verbose);
}
return ret;
@@ -2666,17 +2614,11 @@ cmLocalUnixMakefileGenerator3
::ScanDependencies(std::vector<std::string> const& args)
{
// Format of arguments is:
- // $(CMAKE_COMMAND), cmake_depends, home_output_dir, start_output_dir, GeneratorName, <lang>, <obj>, <src>
+ // $(CMAKE_COMMAND), cmake_depends, GeneratorName, home_output_dir, start_output_dir, info file
// The caller has ensured that all required arguments exist.
- // The language for which we are scanning dependencies.
- std::string const& lang = args[5];
-
- // The file to which to write dependencies.
- const char* objFile = args[6].c_str();
-
- // The source file at which to start the scan.
- const char* srcFile = args[7].c_str();
+ // The info file for this target
+ std::string const& infoFile = args[5];
// Read the directory information file.
cmake cm;
@@ -2686,7 +2628,9 @@ cmLocalUnixMakefileGenerator3
lg->SetGlobalGenerator(&gg);
cmMakefile* mf = lg->GetMakefile();
mf->SetHomeOutputDirectory(args[3].c_str());
- mf->SetStartOutputDirectory(args[4].c_str());
+ mf->SetStartOutputDirectory(args[4].c_str());
+ lg->SetupPathConversions();
+
bool haveDirectoryInfo = false;
std::string dirInfoFile = args[4];
dirInfoFile += "/CMakeDirectoryInformation.cmake";
@@ -2696,6 +2640,13 @@ cmLocalUnixMakefileGenerator3
haveDirectoryInfo = true;
}
+ // read in the target info file
+ if(!mf->ReadListFile(0, infoFile.c_str()) ||
+ cmSystemTools::GetErrorOccuredFlag())
+ {
+ cmSystemTools::Error("Target DependInfo.cmake file not found");
+ }
+
// Test whether we need to force Unix paths.
if(haveDirectoryInfo)
{
@@ -2711,66 +2662,116 @@ cmLocalUnixMakefileGenerator3
{
cmSystemTools::Error("Directory Information file not found");
}
-
- // Get the set of include directories.
- std::vector<std::string> includes;
- if(haveDirectoryInfo)
+ // create the file stream for the depends file
+ std::string dir = cmSystemTools::GetFilenamePath(infoFile);
+ dir += "/depend.make";
+
+ // Open the rule file. This should be copy-if-different because the
+ // rules may depend on this file itself.
+ std::string ruleFileNameFull = dir;
+ cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
+ ruleFileStream.SetCopyIfDifferent(true);
+ if(!ruleFileStream)
{
- std::string includePathVar = "CMAKE_";
- includePathVar += lang;
- includePathVar += "_INCLUDE_PATH";
- if(const char* includePath = mf->GetDefinition(includePathVar.c_str()))
+ return false;
+ }
+ this->WriteDisclaimer(ruleFileStream);
+
+ // for each language we need to scan, scan it
+ const char *langStr = mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES");
+ std::vector<std::string> langs;
+ cmSystemTools::ExpandListArgument(langStr, langs);
+ for (std::vector<std::string>::iterator li =
+ langs.begin(); li != langs.end(); ++li)
+ {
+ // construct the checker
+ std::string lang = li->c_str();
+
+ // Get the set of include directories.
+ std::vector<std::string> includes;
+ if(haveDirectoryInfo)
{
- cmSystemTools::ExpandListArgument(includePath, includes);
+ std::string includePathVar = "CMAKE_";
+ includePathVar += lang;
+ includePathVar += "_INCLUDE_PATH";
+ if(const char* includePath = mf->GetDefinition(includePathVar.c_str()))
+ {
+ cmSystemTools::ExpandListArgument(includePath, includes);
+ }
}
- }
-
- // 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()))
+
+ // Get the include file regular expression.
+ std::string includeRegexScan = "^.*$";
+ std::string includeRegexComplain = "^$";
+ if(haveDirectoryInfo)
{
- includeRegexScan = scanRegex;
+ 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;
+ }
}
- std::string complainRegexVar = "CMAKE_";
- complainRegexVar += lang;
- complainRegexVar += "_INCLUDE_REGEX_COMPLAIN";
- if(const char* complainRegex = mf->GetDefinition(complainRegexVar.c_str()))
+
+ // Create the scanner for this language
+ cmDepends *scanner = 0;
+ if(lang == "C" || lang == "CXX" || lang == "RC")
{
- includeRegexComplain = complainRegex;
+ // TODO: Handle RC (resource files) dependencies correctly.
+ scanner = new cmDependsC(includes,
+ includeRegexScan.c_str(),
+ includeRegexComplain.c_str());
}
- }
-
- // Dispatch the scan for each language.
- if(lang == "C" || lang == "CXX" || lang == "RC")
- {
- // TODO: Handle RC (resource files) dependencies correctly.
- cmDependsC scanner(srcFile, includes,
- includeRegexScan.c_str(), includeRegexComplain.c_str());
- scanner.SetTargetFile(".",objFile,".depend",".build.depend.make");
- return scanner.Write();
- }
#ifdef CMAKE_BUILD_WITH_CMAKE
- else if(lang == "Fortran")
- {
- cmDependsFortran scanner(srcFile, includes);
- scanner.SetTargetFile(".",objFile,".depend",".build.depend.make");
- return scanner.Write();
- }
- else if(lang == "Java")
- {
- cmDependsJava scanner(srcFile);
- scanner.SetTargetFile(".",objFile,".depend",".build.depend.make");
- return scanner.Write();
- }
+ else if(lang == "Fortran")
+ {
+ scanner = new cmDependsFortran(includes);
+ }
+ else if(lang == "Java")
+ {
+ scanner = new cmDependsJava();
+ }
#endif
- return false;
+
+ // for each file we need to scan
+ std::string srcLang = "CMAKE_DEPENDS_CHECK_";
+ srcLang += lang;
+ const char *srcStr = mf->GetSafeDefinition(srcLang.c_str());
+ std::vector<std::string> srcs;
+ cmSystemTools::ExpandListArgument(srcStr, srcs);
+ for (std::vector<std::string>::iterator si =
+ srcs.begin(); si != srcs.end(); ++si)
+ {
+ std::string &src = *si;
+ ++si;
+ // make sure the object file is relative to home output
+ std::string obj = *si;
+ obj = lg->Convert(obj.c_str(),HOME_OUTPUT,MAKEFILE);
+ scanner->Write(src.c_str(),obj.c_str(),ruleFileStream);
+ }
+
+ // free the scanner for this language
+ if (scanner)
+ {
+ delete scanner;
+ }
+ }
+
+ // dependencies were generated, so touch the mark file
+ dir += ".mark";
+ std::ofstream fmark(dir.c_str());
+ fmark << "Dependencies updated>" << std::endl;
+
+ return true;
}
//----------------------------------------------------------------------------
@@ -2942,45 +2943,31 @@ void cmLocalUnixMakefileGenerator3::CheckDependencies(cmMakefile* mf,
bool verbose,
bool clear)
{
- // Get the list of languages that may have sources to check.
- const char* langDef = mf->GetDefinition("CMAKE_DEPENDS_LANGUAGES");
- if(!langDef)
+ // Get the list of target files to check
+ const char* infoDef = mf->GetDefinition("CMAKE_DEPEND_INFO_FILES");
+ if(!infoDef)
{
return;
}
- std::vector<std::string> languages;
- cmSystemTools::ExpandListArgument(langDef, languages);
+ std::vector<std::string> files;
+ cmSystemTools::ExpandListArgument(infoDef, files);
- // For each language get the set of files to check.
- for(std::vector<std::string>::iterator l = languages.begin();
- l != languages.end(); ++l)
+ // For each info file run the check
+ cmDependsC checker;
+ checker.SetVerbose(verbose);
+ for(std::vector<std::string>::iterator l = files.begin();
+ l != files.end(); ++l)
{
- std::string depCheck = "CMAKE_DEPENDS_CHECK_";
- depCheck += *l;
- if(const char* fileDef = mf->GetDefinition(depCheck.c_str()))
+ // either clear or check the files
+ std::string dependFile = cmSystemTools::GetFilenamePath(l->c_str());
+ dependFile += "/depend.make";
+ if (clear)
{
- // Check each file. The current working directory is already
- // correct.
- std::vector<std::string> files;
- cmSystemTools::ExpandListArgument(fileDef, files);
- for(std::vector<std::string>::iterator f = files.begin();
- f != files.end(); ++f)
- {
- // Construct a checker for the given language.
- std::auto_ptr<cmDepends>
- checker(this->GetDependsChecker(*l, ".", f->c_str(), verbose));
- if(checker.get())
- {
- if (clear)
- {
- checker->Clear();
- }
- else
- {
- checker->Check();
- }
- }
- }
+ checker.Clear(dependFile.c_str());
+ }
+ else
+ {
+ checker.Check(dependFile.c_str());
}
}
}
@@ -3063,3 +3050,58 @@ cmLocalUnixMakefileGenerator3::WriteHelpRule(std::ostream& ruleFileStream)
no_depends, commands);
ruleFileStream << "\n\n";
}
+
+void cmLocalUnixMakefileGenerator3
+::WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &target)
+{
+ // now write all the language stuff
+ // Set the set of files to check for dependency integrity.
+ std::set<cmStdString> checkSetLangs;
+ std::map<cmStdString,cmLocalUnixMakefileGenerator3::IntegrityCheckSet>&
+ checkSet = this->GetIntegrityCheckSet()[target.GetName()];
+ for(std::map<cmStdString,
+ cmLocalUnixMakefileGenerator3::IntegrityCheckSet>::const_iterator
+ l = checkSet.begin(); l != checkSet.end(); ++l)
+ {
+ checkSetLangs.insert(l->first);
+ }
+
+ // list the languages
+ cmakefileStream
+ << "# The set of files whose dependency integrity should be checked:\n";
+ cmakefileStream
+ << "SET(CMAKE_DEPENDS_LANGUAGES\n";
+ for(std::set<cmStdString>::iterator
+ l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
+ {
+ cmakefileStream << " \"" << l->c_str() << "\"\n";
+ }
+ cmakefileStream << " )\n";
+
+ // now list the files for each language
+ for(std::set<cmStdString>::iterator
+ l = checkSetLangs.begin(); l != checkSetLangs.end(); ++l)
+ {
+ cmakefileStream
+ << "SET(CMAKE_DEPENDS_CHECK_" << l->c_str() << "\n";
+ // get the check set for this local gen and language
+ cmLocalUnixMakefileGenerator3::IntegrityCheckSet iCheckSet =
+ checkSet[*l];
+ // for each file
+ for(cmLocalUnixMakefileGenerator3::IntegrityCheckSet::const_iterator
+ csIter = iCheckSet.begin();
+ csIter != iCheckSet.end(); ++csIter)
+ {
+ cmakefileStream << " \"" << (*csIter)->GetFullPath() << "\"\n";
+ // Get the full path name of the object file.
+ std::string obj = this->GetObjectFileName(target, **csIter);
+ cmakefileStream << " \"" <<
+ this->Convert(obj.c_str(),
+ cmLocalGenerator::FULL).c_str() << "\"\n";
+ }
+ cmakefileStream << " )\n";
+ }
+
+
+
+}
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index df27dadb27..97f7f10f49 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -140,8 +140,9 @@ public:
// List the files for which to check dependency integrity. Each
// language has its own list because integrity may be checked
// differently.
- struct IntegrityCheckSet: public std::set<cmStdString> {};
- std::map<cmStdString, IntegrityCheckSet> &GetIntegrityCheckSet()
+ struct IntegrityCheckSet: public std::set<cmSourceFile *> {};
+ struct IntegrityCheckSetMap: public std::map<cmStdString, IntegrityCheckSet> {};
+ std::map<cmStdString, IntegrityCheckSetMap> &GetIntegrityCheckSet()
{ return m_CheckDependFiles;}
void AppendTargetDepends(std::vector<std::string>& depends,
@@ -155,6 +156,9 @@ public:
protected:
+ // write the depend info
+ void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);
+
// write the target rules for the local Makefile into the stream
void WriteLocalMakefileTargets(std::ostream& ruleFileStream);
@@ -195,22 +199,24 @@ protected:
// create the rule files for an object
void WriteObjectRuleFiles(cmTarget& target,
- const cmSourceFile& source,
- std::vector<std::string>& objects);
+ cmSourceFile& source,
+ std::vector<std::string>& objects,
+ std::ostream &filestr);
// write the build rule for an object
void WriteObjectBuildFile(std::string &obj,
const char *lang,
cmTarget& target,
- const cmSourceFile& source,
+ cmSourceFile& source,
std::vector<std::string>& depends,
- std::string &depMakeFile);
+ std::string &depMakeFile,
+ std::ostream &filestr);
// write the depend.make file for an object
void WriteObjectDependRules(std::ostream& ruleFileStream,
std::string& obj,
const char *lang,
- const cmSourceFile& source,
+ cmSourceFile& source,
std::vector<std::string>& depends,
std::string& depMarkFile);
@@ -222,13 +228,12 @@ protected:
// return the appropriate depends checker
cmDepends* GetDependsChecker(const std::string& lang,
- const char* dir,
- const char* objFile,
bool verbose);
- std::string GenerateCustomRuleFile(const cmCustomCommand& cc,
- const char *dir);
+ void GenerateCustomRuleFile(const cmCustomCommand& cc,
+ const char *dir,
+ std::ostream &ruleStream);
// these three make some simple changes and then call WriteLibraryRule
void WriteStaticLibraryRule(std::ostream& ruleFileStream,
@@ -327,7 +332,7 @@ protected:
void ComputeHomeRelativeOutputPath();
private:
- std::map<cmStdString, IntegrityCheckSet> m_CheckDependFiles;
+ std::map<cmStdString, IntegrityCheckSetMap> m_CheckDependFiles;
//==========================================================================
// Configuration settings.
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index c64e3b295d..bcb67a177f 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -887,7 +887,7 @@ int cmake::CMakeCommand(std::vector<std::string>& args)
}
// Internal CMake dependency scanning support.
- else if (args[1] == "cmake_depends" && args.size() >= 8)
+ else if (args[1] == "cmake_depends" && args.size() >= 6)
{
cmake cm;
cmGlobalGenerator *ggd = cm.CreateGlobalGenerator(args[2].c_str());