ENH: reduce the number of files produced still needs a bit more cleanup
This commit is contained in:
parent
90cefde755
commit
f85f919dbc
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 == '"')
|
||||
{
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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";
|
||||
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++)
|
||||
{
|
||||
std::string tname = lg->GetRelativeTargetDirectory(l->second);
|
||||
tname += "/DependInfo.cmake";
|
||||
cmSystemTools::ConvertToUnixSlashes(tname);
|
||||
cmakefileStream << " \"" << tname.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 *>(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";
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,30 +304,6 @@ cmLocalUnixMakefileGenerator3
|
|||
std::string dir = this->GetTargetDirectory(target);
|
||||
cmSystemTools::MakeDirectory(this->ConvertToFullPath(dir).c_str());
|
||||
|
||||
// First generate the object rule files. Save a list of all object
|
||||
// files for this target.
|
||||
std::vector<std::string> objects;
|
||||
std::vector<std::string> external_objects;
|
||||
const std::vector<cmSourceFile*>& sources = target.GetSourceFiles();
|
||||
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
|
||||
source != sources.end(); ++source)
|
||||
{
|
||||
if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
|
||||
!(*source)->GetCustomCommand())
|
||||
{
|
||||
if(!m_GlobalGenerator->IgnoreFile((*source)->GetSourceExtension().c_str()))
|
||||
{
|
||||
// Generate this object file's rule file.
|
||||
this->WriteObjectRuleFiles(target, *(*source), objects);
|
||||
}
|
||||
else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT"))
|
||||
{
|
||||
// This is an external object file. Just add it.
|
||||
external_objects.push_back((*source)->GetFullPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the build-time dependencies file for this target.
|
||||
std::string depBase = dir;
|
||||
depBase += "/";
|
||||
|
@ -352,9 +323,55 @@ cmLocalUnixMakefileGenerator3
|
|||
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;
|
||||
std::vector<std::string> external_objects;
|
||||
const std::vector<cmSourceFile*>& sources = target.GetSourceFiles();
|
||||
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
|
||||
source != sources.end(); ++source)
|
||||
{
|
||||
if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
|
||||
!(*source)->GetCustomCommand())
|
||||
{
|
||||
if(!m_GlobalGenerator->IgnoreFile((*source)->GetSourceExtension().c_str()))
|
||||
{
|
||||
// Generate this object file's rule file.
|
||||
this->WriteObjectRuleFiles(target, *(*source), objects,
|
||||
ruleFileStream);
|
||||
}
|
||||
else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT"))
|
||||
{
|
||||
// This is an external object file. Just add it.
|
||||
external_objects.push_back((*source)->GetFullPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write the custom commands for this target
|
||||
std::vector<std::string> cleanFiles;
|
||||
// Look for files registered for cleaning in this directory.
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
// create the file stream for the depends file
|
||||
std::string dir = cmSystemTools::GetFilenamePath(infoFile);
|
||||
dir += "/depend.make";
|
||||
|
||||
|
||||
// Get the set of include directories.
|
||||
std::vector<std::string> includes;
|
||||
if(haveDirectoryInfo)
|
||||
// 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()))
|
||||
{
|
||||
cmSystemTools::ExpandListArgument(includePath, includes);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the include file regular expression.
|
||||
std::string includeRegexScan = "^.*$";
|
||||
std::string includeRegexComplain = "^$";
|
||||
if(haveDirectoryInfo)
|
||||
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)
|
||||
{
|
||||
std::string scanRegexVar = "CMAKE_";
|
||||
scanRegexVar += lang;
|
||||
scanRegexVar += "_INCLUDE_REGEX_SCAN";
|
||||
if(const char* scanRegex = mf->GetDefinition(scanRegexVar.c_str()))
|
||||
// construct the checker
|
||||
std::string lang = li->c_str();
|
||||
|
||||
// Get the set of include directories.
|
||||
std::vector<std::string> includes;
|
||||
if(haveDirectoryInfo)
|
||||
{
|
||||
includeRegexScan = scanRegex;
|
||||
std::string includePathVar = "CMAKE_";
|
||||
includePathVar += lang;
|
||||
includePathVar += "_INCLUDE_PATH";
|
||||
if(const char* includePath = mf->GetDefinition(includePathVar.c_str()))
|
||||
{
|
||||
cmSystemTools::ExpandListArgument(includePath, includes);
|
||||
}
|
||||
}
|
||||
std::string complainRegexVar = "CMAKE_";
|
||||
complainRegexVar += lang;
|
||||
complainRegexVar += "_INCLUDE_REGEX_COMPLAIN";
|
||||
if(const char* complainRegex = mf->GetDefinition(complainRegexVar.c_str()))
|
||||
|
||||
// Get the include file regular expression.
|
||||
std::string includeRegexScan = "^.*$";
|
||||
std::string includeRegexComplain = "^$";
|
||||
if(haveDirectoryInfo)
|
||||
{
|
||||
includeRegexComplain = complainRegex;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
// 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";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue