Merge topic 'FixImplicitDepends2'
05f162c
AddCustomCommand: Handle multiple IMPLICIT_DEPENDS files (#10048)c66f03a
cmDepends: No dependency-vector erasure in CheckDependenciese74ff7c
cmDepends: allow multiple dependees per dependerecc77d0
cmDependsC: fix indentation3e7d97d
cmDependsC: remove code duplicationb4e8f49
cmDependsC: remove unused member variable
This commit is contained in:
commit
3be0a7b4bf
|
@ -68,7 +68,8 @@ public:
|
||||||
" [COMMAND command2 [ARGS] [args2...] ...]\n"
|
" [COMMAND command2 [ARGS] [args2...] ...]\n"
|
||||||
" [MAIN_DEPENDENCY depend]\n"
|
" [MAIN_DEPENDENCY depend]\n"
|
||||||
" [DEPENDS [depends...]]\n"
|
" [DEPENDS [depends...]]\n"
|
||||||
" [IMPLICIT_DEPENDS <lang1> depend1 ...]\n"
|
" [IMPLICIT_DEPENDS <lang1> depend1\n"
|
||||||
|
" [<lang2> depend2] ...]\n"
|
||||||
" [WORKING_DIRECTORY dir]\n"
|
" [WORKING_DIRECTORY dir]\n"
|
||||||
" [COMMENT comment] [VERBATIM] [APPEND])\n"
|
" [COMMENT comment] [VERBATIM] [APPEND])\n"
|
||||||
"This defines a command to generate specified OUTPUT file(s). "
|
"This defines a command to generate specified OUTPUT file(s). "
|
||||||
|
@ -142,6 +143,8 @@ public:
|
||||||
"dependencies of an input file. The language given specifies the "
|
"dependencies of an input file. The language given specifies the "
|
||||||
"programming language whose corresponding dependency scanner should "
|
"programming language whose corresponding dependency scanner should "
|
||||||
"be used. Currently only C and CXX language scanners are supported. "
|
"be used. Currently only C and CXX language scanners are supported. "
|
||||||
|
"The language has to be specified for every file in the "
|
||||||
|
"IMPLICIT_DEPENDS list. "
|
||||||
"Dependencies discovered from the scanning are added to those of "
|
"Dependencies discovered from the scanning are added to those of "
|
||||||
"the custom command at build time. Note that the IMPLICIT_DEPENDS "
|
"the custom command at build time. Note that the IMPLICIT_DEPENDS "
|
||||||
"option is currently supported only for Makefile generators and "
|
"option is currently supported only for Makefile generators and "
|
||||||
|
|
|
@ -50,6 +50,7 @@ bool cmDepends::Write(std::ostream &makeDepends,
|
||||||
std::vector<std::string> pairs;
|
std::vector<std::string> pairs;
|
||||||
cmSystemTools::ExpandListArgument(srcStr, pairs);
|
cmSystemTools::ExpandListArgument(srcStr, pairs);
|
||||||
|
|
||||||
|
std::map<std::string, std::set<std::string> > dependencies;
|
||||||
for(std::vector<std::string>::iterator si = pairs.begin();
|
for(std::vector<std::string>::iterator si = pairs.begin();
|
||||||
si != pairs.end();)
|
si != pairs.end();)
|
||||||
{
|
{
|
||||||
|
@ -62,9 +63,14 @@ bool cmDepends::Write(std::ostream &makeDepends,
|
||||||
obj = this->LocalGenerator->Convert(obj.c_str(),
|
obj = this->LocalGenerator->Convert(obj.c_str(),
|
||||||
cmLocalGenerator::HOME_OUTPUT,
|
cmLocalGenerator::HOME_OUTPUT,
|
||||||
cmLocalGenerator::MAKEFILE);
|
cmLocalGenerator::MAKEFILE);
|
||||||
|
dependencies[obj].insert(src);
|
||||||
|
}
|
||||||
|
for(std::map<std::string, std::set<std::string> >::const_iterator
|
||||||
|
it = dependencies.begin(); it != dependencies.end(); ++it)
|
||||||
|
{
|
||||||
|
|
||||||
// Write the dependencies for this pair.
|
// Write the dependencies for this pair.
|
||||||
if(!this->WriteDependencies(src.c_str(), obj.c_str(),
|
if(!this->WriteDependencies(it->second, it->first,
|
||||||
makeDepends, internalDepends))
|
makeDepends, internalDepends))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -134,8 +140,9 @@ void cmDepends::Clear(const char *file)
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmDepends::WriteDependencies(const char*, const char*,
|
bool cmDepends::WriteDependencies(
|
||||||
std::ostream&, std::ostream&)
|
const std::set<std::string>&, const std::string&,
|
||||||
|
std::ostream&, std::ostream&)
|
||||||
{
|
{
|
||||||
// This should be implemented by the subclass.
|
// This should be implemented by the subclass.
|
||||||
return false;
|
return false;
|
||||||
|
@ -174,8 +181,10 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
|
||||||
// kdelibs/khtml this reduces the number of calls from 184k down to 92k,
|
// kdelibs/khtml this reduces the number of calls from 184k down to 92k,
|
||||||
// or the time for cmake -E cmake_depends from 0.3 s down to 0.21 s.
|
// or the time for cmake -E cmake_depends from 0.3 s down to 0.21 s.
|
||||||
dependerExists = cmSystemTools::FileExists(this->Depender);
|
dependerExists = cmSystemTools::FileExists(this->Depender);
|
||||||
DependencyVector tmp;
|
// If we erase validDeps[this->Depender] by overwriting it with an empty
|
||||||
validDeps[this->Depender] = tmp;
|
// vector, we lose dependencies for dependers that have multiple
|
||||||
|
// entries. No need to initialize the entry, std::map will do so on first
|
||||||
|
// access.
|
||||||
currentDependencies = &validDeps[this->Depender];
|
currentDependencies = &validDeps[this->Depender];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,8 +76,10 @@ protected:
|
||||||
|
|
||||||
// Write dependencies for the target file to the given stream.
|
// Write dependencies for the target file to the given stream.
|
||||||
// Return true for success and false for failure.
|
// Return true for success and false for failure.
|
||||||
virtual bool WriteDependencies(const char *src, const char* obj,
|
virtual bool WriteDependencies(const std::set<std::string>& sources,
|
||||||
std::ostream& makeDepends, std::ostream& internalDepends);
|
const std::string& obj,
|
||||||
|
std::ostream& makeDepends,
|
||||||
|
std::ostream& internalDepends);
|
||||||
|
|
||||||
// Check dependencies for the target file in the given stream.
|
// Check dependencies for the target file in the given stream.
|
||||||
// Return false if dependencies must be regenerated and true
|
// Return false if dependencies must be regenerated and true
|
||||||
|
|
|
@ -98,176 +98,179 @@ cmDependsC::~cmDependsC()
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmDependsC::WriteDependencies(const char *src, const char *obj,
|
bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
|
||||||
std::ostream& makeDepends, std::ostream& internalDepends)
|
const std::string& obj,
|
||||||
|
std::ostream& makeDepends,
|
||||||
|
std::ostream& internalDepends)
|
||||||
{
|
{
|
||||||
// Make sure this is a scanning instance.
|
// Make sure this is a scanning instance.
|
||||||
if(!src || src[0] == '\0')
|
if(sources.empty() || sources.begin()->empty())
|
||||||
{
|
{
|
||||||
cmSystemTools::Error("Cannot scan dependencies without a source file.");
|
cmSystemTools::Error("Cannot scan dependencies without a source file.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!obj || obj[0] == '\0')
|
if(obj.empty())
|
||||||
{
|
{
|
||||||
cmSystemTools::Error("Cannot scan dependencies without an object file.");
|
cmSystemTools::Error("Cannot scan dependencies without an object file.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<cmStdString> dependencies;
|
||||||
|
bool haveDeps = false;
|
||||||
|
|
||||||
if (this->ValidDeps != 0)
|
if (this->ValidDeps != 0)
|
||||||
{
|
{
|
||||||
std::map<std::string, DependencyVector>::const_iterator tmpIt =
|
std::map<std::string, DependencyVector>::const_iterator tmpIt =
|
||||||
this->ValidDeps->find(obj);
|
this->ValidDeps->find(obj);
|
||||||
if (tmpIt!= this->ValidDeps->end())
|
if (tmpIt!= this->ValidDeps->end())
|
||||||
{
|
{
|
||||||
// Write the dependencies to the output stream. Makefile rules
|
|
||||||
// written by the original local generator for this directory
|
|
||||||
// convert the dependencies to paths relative to the home output
|
|
||||||
// directory. We must do the same here.
|
|
||||||
internalDepends << obj << std::endl;
|
|
||||||
for(DependencyVector::const_iterator i=tmpIt->second.begin();
|
for(DependencyVector::const_iterator i=tmpIt->second.begin();
|
||||||
i != tmpIt->second.end(); ++i)
|
i != tmpIt->second.end(); ++i)
|
||||||
{
|
{
|
||||||
makeDepends << obj << ": " <<
|
dependencies.insert(*i);
|
||||||
this->LocalGenerator->Convert(i->c_str(),
|
|
||||||
cmLocalGenerator::HOME_OUTPUT,
|
|
||||||
cmLocalGenerator::MAKEFILE)
|
|
||||||
<< std::endl;
|
|
||||||
internalDepends << " " << i->c_str() << std::endl;
|
|
||||||
}
|
}
|
||||||
makeDepends << std::endl;
|
haveDeps = true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk the dependency graph starting with the source file.
|
if (!haveDeps)
|
||||||
bool first = true;
|
|
||||||
UnscannedEntry root;
|
|
||||||
root.FileName = src;
|
|
||||||
this->Unscanned.push(root);
|
|
||||||
this->Encountered.clear();
|
|
||||||
this->Encountered.insert(src);
|
|
||||||
std::set<cmStdString> dependencies;
|
|
||||||
std::set<cmStdString> scanned;
|
|
||||||
|
|
||||||
// Use reserve to allocate enough memory for tempPathStr
|
|
||||||
// so that during the loops no memory is allocated or freed
|
|
||||||
std::string tempPathStr;
|
|
||||||
tempPathStr.reserve(4*1024);
|
|
||||||
|
|
||||||
while(!this->Unscanned.empty())
|
|
||||||
{
|
{
|
||||||
// Get the next file to scan.
|
// Walk the dependency graph starting with the source file.
|
||||||
UnscannedEntry current = this->Unscanned.front();
|
int srcFiles = (int)sources.size();
|
||||||
this->Unscanned.pop();
|
this->Encountered.clear();
|
||||||
|
|
||||||
// If not a full path, find the file in the include path.
|
for(std::set<std::string>::const_iterator srcIt = sources.begin();
|
||||||
std::string fullName;
|
srcIt != sources.end(); ++srcIt)
|
||||||
if(first || cmSystemTools::FileIsFullPath(current.FileName.c_str()))
|
|
||||||
{
|
{
|
||||||
if(cmSystemTools::FileExists(current.FileName.c_str(), true))
|
UnscannedEntry root;
|
||||||
{
|
root.FileName = *srcIt;
|
||||||
fullName = current.FileName;
|
this->Unscanned.push(root);
|
||||||
}
|
this->Encountered.insert(*srcIt);
|
||||||
}
|
}
|
||||||
else if(!current.QuotedLocation.empty() &&
|
|
||||||
cmSystemTools::FileExists(current.QuotedLocation.c_str(), true))
|
|
||||||
{
|
|
||||||
// The include statement producing this entry was a double-quote
|
|
||||||
// include and the included file is present in the directory of
|
|
||||||
// the source containing the include statement.
|
|
||||||
fullName = current.QuotedLocation;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::map<cmStdString, cmStdString>::iterator
|
|
||||||
headerLocationIt=this->HeaderLocationCache.find(current.FileName);
|
|
||||||
if (headerLocationIt!=this->HeaderLocationCache.end())
|
|
||||||
{
|
|
||||||
fullName=headerLocationIt->second;
|
|
||||||
}
|
|
||||||
else for(std::vector<std::string>::const_iterator i =
|
|
||||||
this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
|
|
||||||
{
|
|
||||||
// Construct the name of the file as if it were in the current
|
|
||||||
// include directory. Avoid using a leading "./".
|
|
||||||
|
|
||||||
tempPathStr = "";
|
std::set<cmStdString> scanned;
|
||||||
if((*i) == ".")
|
|
||||||
{
|
|
||||||
tempPathStr += current.FileName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tempPathStr += *i;
|
|
||||||
tempPathStr+="/";
|
|
||||||
tempPathStr+=current.FileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look for the file in this location.
|
// Use reserve to allocate enough memory for tempPathStr
|
||||||
if(cmSystemTools::FileExists(tempPathStr.c_str(), true))
|
// so that during the loops no memory is allocated or freed
|
||||||
|
std::string tempPathStr;
|
||||||
|
tempPathStr.reserve(4*1024);
|
||||||
|
|
||||||
|
while(!this->Unscanned.empty())
|
||||||
|
{
|
||||||
|
// Get the next file to scan.
|
||||||
|
UnscannedEntry current = this->Unscanned.front();
|
||||||
|
this->Unscanned.pop();
|
||||||
|
|
||||||
|
// If not a full path, find the file in the include path.
|
||||||
|
std::string fullName;
|
||||||
|
if((srcFiles>0)
|
||||||
|
|| cmSystemTools::FileIsFullPath(current.FileName.c_str()))
|
||||||
|
{
|
||||||
|
if(cmSystemTools::FileExists(current.FileName.c_str(), true))
|
||||||
{
|
{
|
||||||
fullName = tempPathStr;
|
fullName = current.FileName;
|
||||||
HeaderLocationCache[current.FileName]=fullName;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else if(!current.QuotedLocation.empty() &&
|
||||||
|
cmSystemTools::FileExists(current.QuotedLocation.c_str(), true))
|
||||||
// Complain if the file cannot be found and matches the complain
|
|
||||||
// regex.
|
|
||||||
if(fullName.empty() &&
|
|
||||||
this->IncludeRegexComplain.find(current.FileName.c_str()))
|
|
||||||
{
|
|
||||||
cmSystemTools::Error("Cannot find file \"",
|
|
||||||
current.FileName.c_str(), "\".");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan the file if it was found and has not been scanned already.
|
|
||||||
if(!fullName.empty() && (scanned.find(fullName) == scanned.end()))
|
|
||||||
{
|
|
||||||
// Record scanned files.
|
|
||||||
scanned.insert(fullName);
|
|
||||||
|
|
||||||
// Check whether this file is already in the cache
|
|
||||||
std::map<cmStdString, cmIncludeLines*>::iterator fileIt=
|
|
||||||
this->FileCache.find(fullName);
|
|
||||||
if (fileIt!=this->FileCache.end())
|
|
||||||
{
|
{
|
||||||
fileIt->second->Used=true;
|
// The include statement producing this entry was a double-quote
|
||||||
dependencies.insert(fullName);
|
// include and the included file is present in the directory of
|
||||||
for (std::vector<UnscannedEntry>::const_iterator incIt=
|
// the source containing the include statement.
|
||||||
fileIt->second->UnscannedEntries.begin();
|
fullName = current.QuotedLocation;
|
||||||
incIt!=fileIt->second->UnscannedEntries.end(); ++incIt)
|
|
||||||
{
|
|
||||||
if (this->Encountered.find(incIt->FileName) ==
|
|
||||||
this->Encountered.end())
|
|
||||||
{
|
|
||||||
this->Encountered.insert(incIt->FileName);
|
|
||||||
this->Unscanned.push(*incIt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
std::map<cmStdString, cmStdString>::iterator
|
||||||
// Try to scan the file. Just leave it out if we cannot find
|
headerLocationIt=this->HeaderLocationCache.find(current.FileName);
|
||||||
// it.
|
if (headerLocationIt!=this->HeaderLocationCache.end())
|
||||||
std::ifstream fin(fullName.c_str());
|
|
||||||
if(fin)
|
|
||||||
{
|
{
|
||||||
// Add this file as a dependency.
|
fullName=headerLocationIt->second;
|
||||||
dependencies.insert(fullName);
|
}
|
||||||
|
else for(std::vector<std::string>::const_iterator i =
|
||||||
|
this->IncludePath.begin(); i != this->IncludePath.end(); ++i)
|
||||||
|
{
|
||||||
|
// Construct the name of the file as if it were in the current
|
||||||
|
// include directory. Avoid using a leading "./".
|
||||||
|
|
||||||
// Scan this file for new dependencies. Pass the directory
|
tempPathStr = "";
|
||||||
// containing the file to handle double-quote includes.
|
if((*i) == ".")
|
||||||
std::string dir = cmSystemTools::GetFilenamePath(fullName);
|
{
|
||||||
this->Scan(fin, dir.c_str(), fullName);
|
tempPathStr += current.FileName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tempPathStr += *i;
|
||||||
|
tempPathStr+="/";
|
||||||
|
tempPathStr+=current.FileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for the file in this location.
|
||||||
|
if(cmSystemTools::FileExists(tempPathStr.c_str(), true))
|
||||||
|
{
|
||||||
|
fullName = tempPathStr;
|
||||||
|
HeaderLocationCache[current.FileName]=fullName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
first = false;
|
// Complain if the file cannot be found and matches the complain
|
||||||
|
// regex.
|
||||||
|
if(fullName.empty() &&
|
||||||
|
this->IncludeRegexComplain.find(current.FileName.c_str()))
|
||||||
|
{
|
||||||
|
cmSystemTools::Error("Cannot find file \"",
|
||||||
|
current.FileName.c_str(), "\".");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan the file if it was found and has not been scanned already.
|
||||||
|
if(!fullName.empty() && (scanned.find(fullName) == scanned.end()))
|
||||||
|
{
|
||||||
|
// Record scanned files.
|
||||||
|
scanned.insert(fullName);
|
||||||
|
|
||||||
|
// Check whether this file is already in the cache
|
||||||
|
std::map<cmStdString, cmIncludeLines*>::iterator fileIt=
|
||||||
|
this->FileCache.find(fullName);
|
||||||
|
if (fileIt!=this->FileCache.end())
|
||||||
|
{
|
||||||
|
fileIt->second->Used=true;
|
||||||
|
dependencies.insert(fullName);
|
||||||
|
for (std::vector<UnscannedEntry>::const_iterator incIt=
|
||||||
|
fileIt->second->UnscannedEntries.begin();
|
||||||
|
incIt!=fileIt->second->UnscannedEntries.end(); ++incIt)
|
||||||
|
{
|
||||||
|
if (this->Encountered.find(incIt->FileName) ==
|
||||||
|
this->Encountered.end())
|
||||||
|
{
|
||||||
|
this->Encountered.insert(incIt->FileName);
|
||||||
|
this->Unscanned.push(*incIt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
// Try to scan the file. Just leave it out if we cannot find
|
||||||
|
// it.
|
||||||
|
std::ifstream fin(fullName.c_str());
|
||||||
|
if(fin)
|
||||||
|
{
|
||||||
|
// Add this file as a dependency.
|
||||||
|
dependencies.insert(fullName);
|
||||||
|
|
||||||
|
// Scan this file for new dependencies. Pass the directory
|
||||||
|
// containing the file to handle double-quote includes.
|
||||||
|
std::string dir = cmSystemTools::GetFilenamePath(fullName);
|
||||||
|
this->Scan(fin, dir.c_str(), fullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
srcFiles--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the dependencies to the output stream. Makefile rules
|
// Write the dependencies to the output stream. Makefile rules
|
||||||
|
@ -275,7 +278,7 @@ bool cmDependsC::WriteDependencies(const char *src, const char *obj,
|
||||||
// convert the dependencies to paths relative to the home output
|
// convert the dependencies to paths relative to the home output
|
||||||
// directory. We must do the same here.
|
// directory. We must do the same here.
|
||||||
internalDepends << obj << std::endl;
|
internalDepends << obj << std::endl;
|
||||||
for(std::set<cmStdString>::iterator i=dependencies.begin();
|
for(std::set<cmStdString>::const_iterator i=dependencies.begin();
|
||||||
i != dependencies.end(); ++i)
|
i != dependencies.end(); ++i)
|
||||||
{
|
{
|
||||||
makeDepends << obj << ": " <<
|
makeDepends << obj << ": " <<
|
||||||
|
|
|
@ -32,11 +32,9 @@ public:
|
||||||
virtual ~cmDependsC();
|
virtual ~cmDependsC();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::vector<char> t_CharBuffer;
|
|
||||||
|
|
||||||
// Implement writing/checking methods required by superclass.
|
// Implement writing/checking methods required by superclass.
|
||||||
virtual bool WriteDependencies(const char *src,
|
virtual bool WriteDependencies(const std::set<std::string>& sources,
|
||||||
const char *file,
|
const std::string& obj,
|
||||||
std::ostream& makeDepends,
|
std::ostream& makeDepends,
|
||||||
std::ostream& internalDepends);
|
std::ostream& internalDepends);
|
||||||
|
|
||||||
|
@ -82,7 +80,6 @@ protected:
|
||||||
const std::map<std::string, DependencyVector>* ValidDeps;
|
const std::map<std::string, DependencyVector>* ValidDeps;
|
||||||
std::set<cmStdString> Encountered;
|
std::set<cmStdString> Encountered;
|
||||||
std::queue<UnscannedEntry> Unscanned;
|
std::queue<UnscannedEntry> Unscanned;
|
||||||
t_CharBuffer Buffer;
|
|
||||||
|
|
||||||
std::map<cmStdString, cmIncludeLines *> FileCache;
|
std::map<cmStdString, cmIncludeLines *> FileCache;
|
||||||
std::map<cmStdString, cmStdString> HeaderLocationCache;
|
std::map<cmStdString, cmStdString> HeaderLocationCache;
|
||||||
|
|
|
@ -170,44 +170,50 @@ cmDependsFortran::~cmDependsFortran()
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmDependsFortran::WriteDependencies(const char *src, const char *obj,
|
bool cmDependsFortran::WriteDependencies(
|
||||||
std::ostream&, std::ostream&)
|
const std::set<std::string>& sources, const std::string& obj,
|
||||||
|
std::ostream&, std::ostream&)
|
||||||
{
|
{
|
||||||
// Make sure this is a scanning instance.
|
// Make sure this is a scanning instance.
|
||||||
if(!src || src[0] == '\0')
|
if(sources.empty() || sources.begin()->empty())
|
||||||
{
|
{
|
||||||
cmSystemTools::Error("Cannot scan dependencies without an source file.");
|
cmSystemTools::Error("Cannot scan dependencies without a source file.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!obj || obj[0] == '\0')
|
if(obj.empty())
|
||||||
{
|
{
|
||||||
cmSystemTools::Error("Cannot scan dependencies without an object file.");
|
cmSystemTools::Error("Cannot scan dependencies without an object file.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the information object for this source.
|
bool okay = true;
|
||||||
cmDependsFortranSourceInfo& info =
|
for(std::set<std::string>::const_iterator it = sources.begin();
|
||||||
this->Internal->CreateObjectInfo(obj, src);
|
it != sources.end(); ++it)
|
||||||
|
|
||||||
// Make a copy of the macros defined via ADD_DEFINITIONS
|
|
||||||
std::set<std::string> ppDefines(this->PPDefinitions.begin(),
|
|
||||||
this->PPDefinitions.end());
|
|
||||||
|
|
||||||
// Create the parser object. The constructor takes ppMacro and info per
|
|
||||||
// reference, so we may look into the resulting objects later.
|
|
||||||
cmDependsFortranParser parser(this, ppDefines, info);
|
|
||||||
|
|
||||||
// Push on the starting file.
|
|
||||||
cmDependsFortranParser_FilePush(&parser, src);
|
|
||||||
|
|
||||||
// Parse the translation unit.
|
|
||||||
if(cmDependsFortran_yyparse(parser.Scanner) != 0)
|
|
||||||
{
|
{
|
||||||
// Failed to parse the file. Report failure to write dependencies.
|
const std::string& src = *it;
|
||||||
return false;
|
// Get the information object for this source.
|
||||||
}
|
cmDependsFortranSourceInfo& info =
|
||||||
|
this->Internal->CreateObjectInfo(obj.c_str(), src.c_str());
|
||||||
|
|
||||||
return true;
|
// Make a copy of the macros defined via ADD_DEFINITIONS
|
||||||
|
std::set<std::string> ppDefines(this->PPDefinitions.begin(),
|
||||||
|
this->PPDefinitions.end());
|
||||||
|
|
||||||
|
// Create the parser object. The constructor takes ppMacro and info per
|
||||||
|
// reference, so we may look into the resulting objects later.
|
||||||
|
cmDependsFortranParser parser(this, ppDefines, info);
|
||||||
|
|
||||||
|
// Push on the starting file.
|
||||||
|
cmDependsFortranParser_FilePush(&parser, src.c_str());
|
||||||
|
|
||||||
|
// Parse the translation unit.
|
||||||
|
if(cmDependsFortran_yyparse(parser.Scanner) != 0)
|
||||||
|
{
|
||||||
|
// Failed to parse the file. Report failure to write dependencies.
|
||||||
|
okay = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -66,7 +66,7 @@ protected:
|
||||||
|
|
||||||
// Implement writing/checking methods required by superclass.
|
// Implement writing/checking methods required by superclass.
|
||||||
virtual bool WriteDependencies(
|
virtual bool WriteDependencies(
|
||||||
const char *src, const char *file,
|
const std::set<std::string>& sources, const std::string& file,
|
||||||
std::ostream& makeDepends, std::ostream& internalDepends);
|
std::ostream& makeDepends, std::ostream& internalDepends);
|
||||||
|
|
||||||
// Actually write the depenencies to the streams.
|
// Actually write the depenencies to the streams.
|
||||||
|
|
|
@ -25,11 +25,11 @@ cmDependsJava::~cmDependsJava()
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmDependsJava::WriteDependencies(const char *src, const char *,
|
bool cmDependsJava::WriteDependencies(const std::set<std::string>& sources,
|
||||||
std::ostream&, std::ostream&)
|
const std::string&, std::ostream&, std::ostream&)
|
||||||
{
|
{
|
||||||
// Make sure this is a scanning instance.
|
// Make sure this is a scanning instance.
|
||||||
if(!src || src[0] == '\0')
|
if(sources.empty() || sources.begin()->empty())
|
||||||
{
|
{
|
||||||
cmSystemTools::Error("Cannot scan dependencies without an source file.");
|
cmSystemTools::Error("Cannot scan dependencies without an source file.");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -29,7 +29,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Implement writing/checking methods required by superclass.
|
// Implement writing/checking methods required by superclass.
|
||||||
virtual bool WriteDependencies(const char *src, const char *file,
|
virtual bool WriteDependencies(
|
||||||
|
const std::set<std::string>& sources, const std::string& file,
|
||||||
std::ostream& makeDepends, std::ostream& internalDepends);
|
std::ostream& makeDepends, std::ostream& internalDepends);
|
||||||
virtual bool CheckDependencies(std::istream& internalDepends,
|
virtual bool CheckDependencies(std::istream& internalDepends,
|
||||||
const char* internalDependsFileName,
|
const char* internalDependsFileName,
|
||||||
|
|
|
@ -1939,8 +1939,12 @@ void cmLocalUnixMakefileGenerator3
|
||||||
for(ImplicitDependFileMap::const_iterator pi = implicitPairs.begin();
|
for(ImplicitDependFileMap::const_iterator pi = implicitPairs.begin();
|
||||||
pi != implicitPairs.end(); ++pi)
|
pi != implicitPairs.end(); ++pi)
|
||||||
{
|
{
|
||||||
cmakefileStream << " \"" << pi->second << "\" ";
|
for(cmDepends::DependencyVector::const_iterator di = pi->second.begin();
|
||||||
cmakefileStream << "\"" << pi->first << "\"\n";
|
di != pi->second.end(); ++ di)
|
||||||
|
{
|
||||||
|
cmakefileStream << " \"" << *di << "\" ";
|
||||||
|
cmakefileStream << "\"" << pi->first << "\"\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cmakefileStream << " )\n";
|
cmakefileStream << " )\n";
|
||||||
|
|
||||||
|
@ -2204,7 +2208,7 @@ cmLocalUnixMakefileGenerator3::AddImplicitDepends(cmTarget const& tgt,
|
||||||
const char* obj,
|
const char* obj,
|
||||||
const char* src)
|
const char* src)
|
||||||
{
|
{
|
||||||
this->ImplicitDepends[tgt.GetName()][lang][obj] = src;
|
this->ImplicitDepends[tgt.GetName()][lang][obj].push_back(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -209,7 +209,8 @@ public:
|
||||||
|
|
||||||
// File pairs for implicit dependency scanning. The key of the map
|
// File pairs for implicit dependency scanning. The key of the map
|
||||||
// is the depender and the value is the explicit dependee.
|
// is the depender and the value is the explicit dependee.
|
||||||
struct ImplicitDependFileMap: public std::map<cmStdString, cmStdString> {};
|
struct ImplicitDependFileMap:
|
||||||
|
public std::map<cmStdString, cmDepends::DependencyVector> {};
|
||||||
struct ImplicitDependLanguageMap:
|
struct ImplicitDependLanguageMap:
|
||||||
public std::map<cmStdString, ImplicitDependFileMap> {};
|
public std::map<cmStdString, ImplicitDependFileMap> {};
|
||||||
struct ImplicitDependTargetMap:
|
struct ImplicitDependTargetMap:
|
||||||
|
|
|
@ -64,7 +64,8 @@ if("${CMAKE_GENERATOR}" MATCHES "Make")
|
||||||
# Test the IMPLICIT_DEPENDS feature.
|
# Test the IMPLICIT_DEPENDS feature.
|
||||||
set(ZOT_DEPENDS IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep.cxx)
|
set(ZOT_DEPENDS IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep.cxx)
|
||||||
set(ZOT_CUSTOM_DEP
|
set(ZOT_CUSTOM_DEP
|
||||||
IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep_custom.cxx)
|
IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep_custom.cxx
|
||||||
|
CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep_custom2.cxx )
|
||||||
else()
|
else()
|
||||||
# No IMPLICIT_DEPENDS...just depend directly.
|
# No IMPLICIT_DEPENDS...just depend directly.
|
||||||
set(ZOT_DEPENDS DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx.in)
|
set(ZOT_DEPENDS DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx.in)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
#include <zot_custom.hxx.in>
|
||||||
|
// some comment
|
Loading…
Reference in New Issue