ENH: reduce the number of files produced still needs a bit more cleanup

This commit is contained in:
Ken Martin 2005-07-27 09:49:37 -04:00
parent 90cefde755
commit f85f919dbc
15 changed files with 435 additions and 517 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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 == '"')
{

View File

@ -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
{

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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.

View File

@ -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;
}

View File

@ -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 *);
};

View File

@ -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;

View File

@ -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

View File

@ -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";
}
}

View File

@ -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.

View File

@ -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());