|
@@ -159,10 +159,13 @@ public:
|
|
|
CachedLinkInterfaceCompileOptionsEntries;
|
|
|
mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
|
|
|
CachedLinkInterfaceCompileDefinitionsEntries;
|
|
|
+ mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
|
|
|
+ CachedLinkInterfaceSourcesEntries;
|
|
|
|
|
|
mutable std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
|
|
|
mutable std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
|
|
|
mutable std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone;
|
|
|
+ mutable std::map<std::string, bool> CacheLinkInterfaceSourcesDone;
|
|
|
};
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
@@ -198,6 +201,7 @@ cmTargetInternals::~cmTargetInternals()
|
|
|
deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries);
|
|
|
deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries);
|
|
|
deleteAndClear(this->CachedLinkInterfaceCompileDefinitionsEntries);
|
|
|
+ deleteAndClear(this->CachedLinkInterfaceSourcesEntries);
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
@@ -543,43 +547,157 @@ bool cmTarget::IsBundleOnApple() const
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
-void cmTarget::GetSourceFiles(std::vector<std::string> &files,
|
|
|
- const std::string& config) const
|
|
|
+static void processSources(cmTarget const* tgt,
|
|
|
+ const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
|
|
|
+ std::vector<std::string> &srcs,
|
|
|
+ std::set<std::string> &uniqueSrcs,
|
|
|
+ cmGeneratorExpressionDAGChecker *dagChecker,
|
|
|
+ cmTarget const* head,
|
|
|
+ std::string const& config)
|
|
|
{
|
|
|
- assert(this->GetType() != INTERFACE_LIBRARY);
|
|
|
- for(std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
|
|
|
- si = this->Internal->SourceEntries.begin();
|
|
|
- si != this->Internal->SourceEntries.end(); ++si)
|
|
|
- {
|
|
|
- std::vector<std::string> srcs;
|
|
|
- cmSystemTools::ExpandListArgument((*si)->ge->Evaluate(this->Makefile,
|
|
|
- config,
|
|
|
- false,
|
|
|
- this),
|
|
|
- srcs);
|
|
|
+ cmMakefile *mf = tgt->GetMakefile();
|
|
|
|
|
|
- for(std::vector<std::string>::const_iterator i = srcs.begin();
|
|
|
- i != srcs.end(); ++i)
|
|
|
+ for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
|
|
|
+ it = entries.begin(), end = entries.end(); it != end; ++it)
|
|
|
+ {
|
|
|
+ bool cacheSources = false;
|
|
|
+ std::vector<std::string> entrySources = (*it)->CachedEntries;
|
|
|
+ if(entrySources.empty())
|
|
|
{
|
|
|
- std::string src = *i;
|
|
|
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
|
|
|
- std::string e;
|
|
|
- src = sf->GetFullPath(&e);
|
|
|
- if(src.empty())
|
|
|
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
|
|
|
+ config,
|
|
|
+ false,
|
|
|
+ head ? head : tgt,
|
|
|
+ tgt,
|
|
|
+ dagChecker),
|
|
|
+ entrySources);
|
|
|
+ if (mf->IsGeneratingBuildSystem()
|
|
|
+ && !(*it)->ge->GetHadContextSensitiveCondition())
|
|
|
+ {
|
|
|
+ cacheSources = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ for(std::vector<std::string>::iterator i = entrySources.begin();
|
|
|
+ i != entrySources.end(); ++i)
|
|
|
{
|
|
|
- if(!e.empty())
|
|
|
+ std::string& src = *i;
|
|
|
+
|
|
|
+ cmSourceFile* sf = mf->GetOrCreateSource(src);
|
|
|
+ std::string e;
|
|
|
+ src = sf->GetFullPath(&e);
|
|
|
+ if(src.empty())
|
|
|
{
|
|
|
- cmake* cm = this->Makefile->GetCMakeInstance();
|
|
|
- cm->IssueMessage(cmake::FATAL_ERROR, e,
|
|
|
- this->GetBacktrace());
|
|
|
+ if(!e.empty())
|
|
|
+ {
|
|
|
+ cmake* cm = mf->GetCMakeInstance();
|
|
|
+ cm->IssueMessage(cmake::FATAL_ERROR, e,
|
|
|
+ tgt->GetBacktrace());
|
|
|
+ }
|
|
|
+ return;
|
|
|
}
|
|
|
- return;
|
|
|
}
|
|
|
- files.push_back(src);
|
|
|
+ if (cacheSources)
|
|
|
+ {
|
|
|
+ (*it)->CachedEntries = entrySources;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for(std::vector<std::string>::iterator
|
|
|
+ li = entrySources.begin(); li != entrySources.end(); ++li)
|
|
|
+ {
|
|
|
+ std::string src = *li;
|
|
|
+
|
|
|
+ if(uniqueSrcs.insert(src).second)
|
|
|
+ {
|
|
|
+ srcs.push_back(src);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+//----------------------------------------------------------------------------
|
|
|
+void cmTarget::GetSourceFiles(std::vector<std::string> &files,
|
|
|
+ const std::string& config,
|
|
|
+ cmTarget const* head) const
|
|
|
+{
|
|
|
+ assert(this->GetType() != INTERFACE_LIBRARY);
|
|
|
+
|
|
|
+
|
|
|
+ cmListFileBacktrace lfbt;
|
|
|
+
|
|
|
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
|
|
+ this->GetName(),
|
|
|
+ "SOURCES", 0, 0);
|
|
|
+
|
|
|
+ std::set<std::string> uniqueSrcs;
|
|
|
+ processSources(this,
|
|
|
+ this->Internal->SourceEntries,
|
|
|
+ files,
|
|
|
+ uniqueSrcs,
|
|
|
+ &dagChecker,
|
|
|
+ head,
|
|
|
+ config);
|
|
|
+
|
|
|
+ if (!this->Internal->CacheLinkInterfaceSourcesDone[config])
|
|
|
+ {
|
|
|
+ for (std::vector<cmValueWithOrigin>::const_iterator
|
|
|
+ it = this->Internal->LinkImplementationPropertyEntries.begin(),
|
|
|
+ end = this->Internal->LinkImplementationPropertyEntries.end();
|
|
|
+ it != end; ++it)
|
|
|
+ {
|
|
|
+ if (!cmGeneratorExpression::IsValidTargetName(it->Value)
|
|
|
+ && cmGeneratorExpression::Find(it->Value) == std::string::npos)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ {
|
|
|
+ cmGeneratorExpression ge(lfbt);
|
|
|
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
|
|
|
+ ge.Parse(it->Value);
|
|
|
+ std::string targetResult = cge->Evaluate(this->Makefile, config,
|
|
|
+ false, this, 0, &dagChecker);
|
|
|
+ if (!this->Makefile->FindTargetToUse(targetResult))
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ std::string sourceGenex = "$<TARGET_PROPERTY:" +
|
|
|
+ it->Value + ",INTERFACE_SOURCES>";
|
|
|
+ if (cmGeneratorExpression::Find(it->Value) != std::string::npos)
|
|
|
+ {
|
|
|
+ // Because it->Value is a generator expression, ensure that it
|
|
|
+ // evaluates to the non-empty string before being used in the
|
|
|
+ // TARGET_PROPERTY expression.
|
|
|
+ sourceGenex = "$<$<BOOL:" + it->Value + ">:" + sourceGenex + ">";
|
|
|
+ }
|
|
|
+ cmGeneratorExpression ge(it->Backtrace);
|
|
|
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(
|
|
|
+ sourceGenex);
|
|
|
+
|
|
|
+ this->Internal
|
|
|
+ ->CachedLinkInterfaceSourcesEntries[config].push_back(
|
|
|
+ new cmTargetInternals::TargetPropertyEntry(cge,
|
|
|
+ it->Value));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ processSources(this,
|
|
|
+ this->Internal->CachedLinkInterfaceSourcesEntries[config],
|
|
|
+ files,
|
|
|
+ uniqueSrcs,
|
|
|
+ &dagChecker,
|
|
|
+ head,
|
|
|
+ config);
|
|
|
+
|
|
|
+ if (!this->Makefile->IsGeneratingBuildSystem())
|
|
|
+ {
|
|
|
+ deleteAndClear(this->Internal->CachedLinkInterfaceSourcesEntries);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ this->Internal->CacheLinkInterfaceSourcesDone[config] = true;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
//----------------------------------------------------------------------------
|
|
|
bool
|
|
|
cmTarget::GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const
|
|
@@ -639,10 +757,11 @@ cmTarget::GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
|
|
|
- const std::string& config) const
|
|
|
+ const std::string& config,
|
|
|
+ cmTarget const* head) const
|
|
|
{
|
|
|
std::vector<std::string> srcs;
|
|
|
- this->GetSourceFiles(srcs, config);
|
|
|
+ this->GetSourceFiles(srcs, config, head);
|
|
|
|
|
|
std::set<cmSourceFile*> emitted;
|
|
|
|
|
@@ -5053,10 +5172,11 @@ bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
void cmTarget::GetLanguages(std::set<std::string>& languages,
|
|
|
- const std::string& config) const
|
|
|
+ const std::string& config,
|
|
|
+ cmTarget const* head) const
|
|
|
{
|
|
|
std::vector<cmSourceFile*> sourceFiles;
|
|
|
- this->GetSourceFiles(sourceFiles, config);
|
|
|
+ this->GetSourceFiles(sourceFiles, config, head);
|
|
|
for(std::vector<cmSourceFile*>::const_iterator
|
|
|
i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
|
|
|
{
|
|
@@ -5111,7 +5231,7 @@ void cmTarget::GetLanguages(std::set<std::string>& languages,
|
|
|
for(std::vector<cmTarget*>::const_iterator
|
|
|
i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
|
|
|
{
|
|
|
- (*i)->GetLanguages(languages, config);
|
|
|
+ (*i)->GetLanguages(languages, config, head);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -6050,7 +6170,7 @@ cmTarget::GetLinkImplementation(const std::string& config,
|
|
|
// Compute the link implementation for this configuration.
|
|
|
LinkImplementation impl;
|
|
|
this->ComputeLinkImplementation(config, impl, head);
|
|
|
- this->ComputeLinkImplementationLanguages(config, impl);
|
|
|
+ this->ComputeLinkImplementationLanguages(config, impl, head);
|
|
|
|
|
|
// Store the information for this configuration.
|
|
|
cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
|
|
@@ -6058,7 +6178,7 @@ cmTarget::GetLinkImplementation(const std::string& config,
|
|
|
}
|
|
|
else if (i->second.Languages.empty())
|
|
|
{
|
|
|
- this->ComputeLinkImplementationLanguages(config, i->second);
|
|
|
+ this->ComputeLinkImplementationLanguages(config, i->second, head);
|
|
|
}
|
|
|
|
|
|
return &i->second;
|
|
@@ -6172,12 +6292,13 @@ void cmTarget::ComputeLinkImplementation(const std::string& config,
|
|
|
//----------------------------------------------------------------------------
|
|
|
void
|
|
|
cmTarget::ComputeLinkImplementationLanguages(const std::string& config,
|
|
|
- LinkImplementation& impl) const
|
|
|
+ LinkImplementation& impl,
|
|
|
+ cmTarget const* head) const
|
|
|
{
|
|
|
// This target needs runtime libraries for its source languages.
|
|
|
std::set<std::string> languages;
|
|
|
// Get languages used in our source files.
|
|
|
- this->GetLanguages(languages, config);
|
|
|
+ this->GetLanguages(languages, config, head);
|
|
|
// Copy the set of langauges to the link implementation.
|
|
|
for(std::set<std::string>::iterator li = languages.begin();
|
|
|
li != languages.end(); ++li)
|