diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 9d17320e7..8bfc42849 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -150,6 +150,7 @@ public: std::vector IncludeDirectoriesEntries; std::vector CompileOptionsEntries; std::vector CompileDefinitionsEntries; + std::vector SourceEntries; std::vector LinkImplementationPropertyEntries; mutable std::map > @@ -545,37 +546,51 @@ bool cmTarget::IsBundleOnApple() const void cmTarget::GetSourceFiles(std::vector &files) const { assert(this->GetType() != INTERFACE_LIBRARY); - std::vector sourceFiles; - this->GetSourceFiles(sourceFiles); - for(std::vector::const_iterator - si = sourceFiles.begin(); - si != sourceFiles.end(); ++si) + for(std::vector::const_iterator + si = this->Internal->SourceEntries.begin(); + si != this->Internal->SourceEntries.end(); ++si) { - files.push_back((*si)->GetFullPath()); + std::vector srcs; + cmSystemTools::ExpandListArgument((*si)->ge->GetInput(), srcs); + for(std::vector::const_iterator i = srcs.begin(); + i != srcs.end(); ++i) + { + std::string src = *i; + cmSourceFile* sf = this->Makefile->GetOrCreateSource(src); + std::string e; + src = sf->GetFullPath(&e); + if(src.empty()) + { + if(!e.empty()) + { + cmake* cm = this->Makefile->GetCMakeInstance(); + cm->IssueMessage(cmake::FATAL_ERROR, e, + this->GetBacktrace()); + } + return; + } + files.push_back(src); + } } } //---------------------------------------------------------------------------- void cmTarget::GetSourceFiles(std::vector &files) const { - assert(this->GetType() != INTERFACE_LIBRARY); - for(std::vector::const_iterator - si = this->SourceFiles.begin(); - si != this->SourceFiles.end(); ++si) + std::vector srcs; + this->GetSourceFiles(srcs); + + std::set emitted; + + for(std::vector::const_iterator i = srcs.begin(); + i != srcs.end(); ++i) { - std::string e; - if((*si)->GetFullPath(&e).empty()) + cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i); + if (emitted.insert(sf).second) { - if(!e.empty()) - { - cmake* cm = this->Makefile->GetCMakeInstance(); - cm->IssueMessage(cmake::FATAL_ERROR, e, - this->GetBacktrace()); - } - return; + files.push_back(sf); } } - files = this->SourceFiles; } //---------------------------------------------------------------------------- @@ -639,18 +654,87 @@ cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s) return this->AddSource(src); } +//---------------------------------------------------------------------------- +struct CreateLocation +{ + cmMakefile const* Makefile; + + CreateLocation(cmMakefile const* mf) + : Makefile(mf) + { + + } + + cmSourceFileLocation operator()(const std::string& filename) + { + return cmSourceFileLocation(this->Makefile, filename); + } +}; + +//---------------------------------------------------------------------------- +struct LocationMatcher +{ + 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 files; + cmSystemTools::ExpandListArgument(entry->ge->GetInput(), files); + std::vector 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) { - cmSourceFile* sf = this->Makefile->GetOrCreateSource(src); - if (std::find(this->SourceFiles.begin(), this->SourceFiles.end(), sf) - == this->SourceFiles.end()) + cmSourceFileLocation sfl(this->Makefile, src); + if (std::find_if(this->Internal->SourceEntries.begin(), + this->Internal->SourceEntries.end(), + TargetPropertyEntryFinder(sfl)) + == this->Internal->SourceEntries.end()) { - this->SourceFiles.push_back(sf); + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmGeneratorExpression ge(lfbt); + cmsys::auto_ptr cge = ge.Parse(src); + this->Internal->SourceEntries.push_back( + new cmTargetInternals::TargetPropertyEntry(cge)); } - return sf; + return this->Makefile->GetOrCreateSource(src); } + + //---------------------------------------------------------------------------- void cmTarget::ProcessSourceExpression(std::string const& expr) { @@ -2779,25 +2863,34 @@ const char *cmTarget::GetProperty(const std::string& prop, { cmOStringStream ss; const char* sep = ""; - for(std::vector::const_iterator - i = this->SourceFiles.begin(); - i != this->SourceFiles.end(); ++i) + typedef cmTargetInternals::TargetPropertyEntry + TargetPropertyEntry; + for(std::vector::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 files; + cmSystemTools::ExpandListArgument(entry, files); + for (std::vector::const_iterator + li = files.begin(); li != files.end(); ++li) { - sname += "/"; - } - sname += location.GetName(); + 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); @@ -6410,6 +6503,7 @@ cmTargetInternalPointer::~cmTargetInternalPointer() deleteAndClear(this->Pointer->IncludeDirectoriesEntries); deleteAndClear(this->Pointer->CompileOptionsEntries); deleteAndClear(this->Pointer->CompileDefinitionsEntries); + deleteAndClear(this->Pointer->SourceEntries); delete this->Pointer; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index e9e36227f..45fca53a2 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -686,7 +686,6 @@ private: std::vector PreLinkCommands; std::vector PostBuildCommands; TargetType TargetTypeValue; - std::vector SourceFiles; std::vector ObjectLibraries; LinkLibraryVectorType LinkLibraries; LinkLibraryVectorType PrevLinkedLibraries;