diff options
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r-- | Source/cmTarget.cxx | 313 |
1 files changed, 251 insertions, 62 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 32aaccc..573b816 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -150,6 +150,7 @@ public: std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries; std::vector<TargetPropertyEntry*> CompileOptionsEntries; std::vector<TargetPropertyEntry*> CompileDefinitionsEntries; + std::vector<TargetPropertyEntry*> SourceEntries; std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries; mutable std::map<std::string, std::vector<TargetPropertyEntry*> > @@ -542,35 +543,58 @@ bool cmTarget::IsBundleOnApple() const } //---------------------------------------------------------------------------- -void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const +void cmTarget::GetSourceFiles(std::vector<std::string> &files) const { assert(this->GetType() != INTERFACE_LIBRARY); - for(std::vector<cmSourceFile*>::const_iterator - si = this->SourceFiles.begin(); - si != this->SourceFiles.end(); ++si) + for(std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator + si = this->Internal->SourceEntries.begin(); + si != this->Internal->SourceEntries.end(); ++si) { - std::string e; - if((*si)->GetFullPath(&e).empty()) + std::vector<std::string> srcs; + cmSystemTools::ExpandListArgument((*si)->ge->Evaluate(this->Makefile, + "", + false, + this), + srcs); + + for(std::vector<std::string>::const_iterator i = srcs.begin(); + i != srcs.end(); ++i) { - if(!e.empty()) + std::string src = *i; + cmSourceFile* sf = this->Makefile->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 = this->Makefile->GetCMakeInstance(); + cm->IssueMessage(cmake::FATAL_ERROR, e, + this->GetBacktrace()); + } + return; } - return; + files.push_back(src); } } - files = this->SourceFiles; } //---------------------------------------------------------------------------- -void cmTarget::AddSourceFile(cmSourceFile* sf) +void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const { - if (std::find(this->SourceFiles.begin(), this->SourceFiles.end(), sf) - == this->SourceFiles.end()) + std::vector<std::string> srcs; + this->GetSourceFiles(srcs); + + std::set<cmSourceFile*> emitted; + + for(std::vector<std::string>::const_iterator i = srcs.begin(); + i != srcs.end(); ++i) { - this->SourceFiles.push_back(sf); + cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i); + if (emitted.insert(sf).second) + { + files.push_back(sf); + } } } @@ -583,17 +607,17 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs) const char* src = i->c_str(); if(src[0] == '$' && src[1] == '<') { - this->ProcessSourceExpression(*i); + this->AddSource(src); } else { - this->AddSource(src); + this->AddSourceCMP0049(src); } } } //---------------------------------------------------------------------------- -cmSourceFile* cmTarget::AddSource(const std::string& s) +cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s) { std::string src = s; @@ -632,28 +656,91 @@ cmSourceFile* cmTarget::AddSource(const std::string& s) } } } - - cmSourceFile* sf = this->Makefile->GetOrCreateSource(src); - this->AddSourceFile(sf); - return sf; + return this->AddSource(src); } //---------------------------------------------------------------------------- -void cmTarget::ProcessSourceExpression(std::string const& expr) +struct CreateLocation +{ + cmMakefile const* Makefile; + + CreateLocation(cmMakefile const* mf) + : Makefile(mf) + { + + } + + cmSourceFileLocation operator()(const std::string& filename) + { + return cmSourceFileLocation(this->Makefile, filename); + } +}; + +//---------------------------------------------------------------------------- +struct LocationMatcher { - if(cmHasLiteralPrefix(expr.c_str(), "$<TARGET_OBJECTS:") && - expr[expr.size()-1] == '>') + const cmSourceFileLocation& Needle; + + LocationMatcher(const cmSourceFileLocation& needle) + : Needle(needle) + { + + } + + bool operator()(cmSourceFileLocation &loc) + { + return loc.Matches(this->Needle); + } +}; + + +//---------------------------------------------------------------------------- +struct TargetPropertyEntryFinder +{ +private: + const cmSourceFileLocation& Needle; +public: + TargetPropertyEntryFinder(const cmSourceFileLocation& needle) + : Needle(needle) + { + + } + + bool operator()(cmTargetInternals::TargetPropertyEntry* entry) + { + std::vector<std::string> files; + cmSystemTools::ExpandListArgument(entry->ge->GetInput(), files); + std::vector<cmSourceFileLocation> locations(files.size()); + std::transform(files.begin(), files.end(), locations.begin(), + CreateLocation(this->Needle.GetMakefile())); + + return std::find_if(locations.begin(), locations.end(), + LocationMatcher(this->Needle)) != locations.end(); + } +}; + +//---------------------------------------------------------------------------- +cmSourceFile* cmTarget::AddSource(const std::string& src) +{ + cmSourceFileLocation sfl(this->Makefile, src); + if (std::find_if(this->Internal->SourceEntries.begin(), + this->Internal->SourceEntries.end(), + TargetPropertyEntryFinder(sfl)) + == this->Internal->SourceEntries.end()) { - std::string objLibName = expr.substr(17, expr.size()-18); - this->ObjectLibraries.push_back(objLibName); + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmGeneratorExpression ge(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(src); + cge->SetEvaluateForBuildsystem(true); + this->Internal->SourceEntries.push_back( + new cmTargetInternals::TargetPropertyEntry(cge)); } - else + if (cmGeneratorExpression::Find(src) != std::string::npos) { - cmOStringStream e; - e << "Unrecognized generator expression:\n" - << " " << expr; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + return 0; } + return this->Makefile->GetOrCreateSource(src); } //---------------------------------------------------------------------------- @@ -2766,25 +2853,90 @@ const char *cmTarget::GetProperty(const std::string& prop, { cmOStringStream ss; const char* sep = ""; - for(std::vector<cmSourceFile*>::const_iterator - i = this->SourceFiles.begin(); - i != this->SourceFiles.end(); ++i) + typedef cmTargetInternals::TargetPropertyEntry + TargetPropertyEntry; + for(std::vector<TargetPropertyEntry*>::const_iterator + i = this->Internal->SourceEntries.begin(); + i != this->Internal->SourceEntries.end(); ++i) { - // Separate from the previous list entries. - ss << sep; - sep = ";"; + std::string entry = (*i)->ge->GetInput(); - // Construct what is known about this source file location. - cmSourceFileLocation const& location = (*i)->GetLocation(); - std::string sname = location.GetDirectory(); - if(!sname.empty()) + std::vector<std::string> files; + cmSystemTools::ExpandListArgument(entry, files); + for (std::vector<std::string>::const_iterator + li = files.begin(); li != files.end(); ++li) { - sname += "/"; - } - sname += location.GetName(); + if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") && + (*li)[li->size() - 1] == '>') + { + std::string objLibName = li->substr(17, li->size()-18); + + if (cmGeneratorExpression::Find(objLibName) != std::string::npos) + { + ss << sep; + sep = ";"; + ss << *li; + continue; + } + + bool addContent = false; + bool noMessage = true; + cmOStringStream e; + cmake::MessageType messageType = cmake::AUTHOR_WARNING; + switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0051)) + { + case cmPolicies::WARN: + e << (this->Makefile->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0051)) << "\n"; + noMessage = false; + case cmPolicies::OLD: + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + addContent = true; + } + if (!noMessage) + { + e << "Target \"" << this->Name << "\" contains $<TARGET_OBJECTS> " + "generator expression in its sources list. This content was not " + "previously part of the SOURCES property when that property was " + "read at configure time. Code reading that property needs to be " + "adapted to ignore the generator expression using the " + "string(GENEX_STRIP) command."; + this->Makefile->IssueMessage(messageType, e.str()); + } + if (addContent) + { + ss << sep; + sep = ";"; + ss << *li; + } + } + else if (cmGeneratorExpression::Find(*li) == std::string::npos) + { + ss << sep; + sep = ";"; + ss << *li; + } + else + { + cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li); + // Construct what is known about this source file location. + cmSourceFileLocation const& location = sf->GetLocation(); + std::string sname = location.GetDirectory(); + if(!sname.empty()) + { + sname += "/"; + } + sname += location.GetName(); - // Append this list entry. - ss << sname; + ss << sep; + sep = ";"; + // Append this list entry. + ss << sname; + } + } } this->Properties.SetProperty("SOURCES", ss.str().c_str(), cmProperty::TARGET); @@ -4844,8 +4996,10 @@ bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p, //---------------------------------------------------------------------------- void cmTarget::GetLanguages(std::set<std::string>& languages) const { + std::vector<cmSourceFile*> sourceFiles; + this->GetSourceFiles(sourceFiles); for(std::vector<cmSourceFile*>::const_iterator - i = this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i) + i = sourceFiles.begin(); i != sourceFiles.end(); ++i) { const std::string& lang = (*i)->GetLanguage(); if(!lang.empty()) @@ -4853,6 +5007,53 @@ void cmTarget::GetLanguages(std::set<std::string>& languages) const languages.insert(lang); } } + + std::vector<cmTarget*> objectLibraries; + std::vector<cmSourceFile const*> externalObjects; + if (this->Makefile->GetGeneratorTargets().empty()) + { + // At configure-time, this method can be called as part of getting the + // LOCATION property or to export() a file to be include()d. However + // there is no cmGeneratorTarget at configure-time, so search the SOURCES + // for TARGET_OBJECTS instead for backwards compatibility with OLD + // behavior of CMP0024 and CMP0026 only. + std::vector<std::string> srcs; + cmSystemTools::ExpandListArgument(this->GetProperty("SOURCES"), srcs); + for(std::vector<std::string>::const_iterator it = srcs.begin(); + it != srcs.end(); ++it) + { + if (cmHasLiteralPrefix(*it, "$<TARGET_OBJECTS:") + && cmHasLiteralSuffix(*it, ">")) + { + std::string objLibName = it->substr(17, it->size()-18); + if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLibName)) + { + objectLibraries.push_back(tgt); + } + } + } + } + else + { + cmGeneratorTarget* gt = this->Makefile->GetLocalGenerator() + ->GetGlobalGenerator() + ->GetGeneratorTarget(this); + gt->GetExternalObjects(externalObjects); + for(std::vector<cmSourceFile const*>::const_iterator + i = externalObjects.begin(); i != externalObjects.end(); ++i) + { + std::string objLib = (*i)->GetObjectLibrary(); + if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib)) + { + objectLibraries.push_back(tgt); + } + } + } + for(std::vector<cmTarget*>::const_iterator + i = objectLibraries.begin(); i != objectLibraries.end(); ++i) + { + (*i)->GetLanguages(languages); + } } //---------------------------------------------------------------------------- @@ -5917,19 +6118,6 @@ cmTarget::ComputeLinkImplementationLanguages(LinkImplementation& impl) const std::set<std::string> languages; // Get languages used in our source files. this->GetLanguages(languages); - // Get languages used in object library sources. - for(std::vector<std::string>::const_iterator - i = this->ObjectLibraries.begin(); - i != this->ObjectLibraries.end(); ++i) - { - if(cmTarget* objLib = this->Makefile->FindTargetToUse(*i)) - { - if(objLib->GetType() == cmTarget::OBJECT_LIBRARY) - { - objLib->GetLanguages(languages); - } - } - } // Copy the set of langauges to the link implementation. for(std::set<std::string>::iterator li = languages.begin(); li != languages.end(); ++li) @@ -6395,6 +6583,7 @@ cmTargetInternalPointer::~cmTargetInternalPointer() deleteAndClear(this->Pointer->IncludeDirectoriesEntries); deleteAndClear(this->Pointer->CompileOptionsEntries); deleteAndClear(this->Pointer->CompileDefinitionsEntries); + deleteAndClear(this->Pointer->SourceEntries); delete this->Pointer; } |