diff options
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 349 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 17 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 1 |
3 files changed, 241 insertions, 126 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index e2810ac..4cb1904 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -25,6 +25,194 @@ #include "assert.h" //---------------------------------------------------------------------------- +void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib, + cmTarget *target, cmake *cm) +{ + if(!badObjLib.empty()) + { + cmOStringStream e; + e << "OBJECT library \"" << target->GetName() << "\" contains:\n"; + for(std::vector<cmSourceFile*>::const_iterator i = badObjLib.begin(); + i != badObjLib.end(); ++i) + { + e << " " << (*i)->GetLocation().GetName() << "\n"; + } + e << "but may contain only headers and sources that compile."; + cm->IssueMessage(cmake::FATAL_ERROR, e.str(), + target->GetBacktrace()); + } +} + +struct ObjectSourcesTag {}; +struct CustomCommandsTag {}; +struct ExtraSourcesTag {}; +struct HeaderSourcesTag {}; +struct ExternalObjectsTag {}; +struct IDLSourcesTag {}; +struct ResxTag {}; +struct ModuleDefinitionFileTag {}; + +#if !defined(_MSC_VER) || _MSC_VER >= 1310 +template<typename Tag, typename OtherTag> +struct IsSameTag +{ + enum { + Result = false + }; +}; + +template<typename Tag> +struct IsSameTag<Tag, Tag> +{ + enum { + Result = true + }; +}; +#else +struct IsSameTagBase +{ + typedef char (&no_type)[1]; + typedef char (&yes_type)[2]; + template<typename T> struct Check; + template<typename T> static yes_type check(Check<T>*, Check<T>*); + static no_type check(...); +}; +template<typename Tag1, typename Tag2> +struct IsSameTag: public IsSameTagBase +{ + enum { + Result = (sizeof(check(static_cast< Check<Tag1>* >(0), + static_cast< Check<Tag2>* >(0))) == + sizeof(yes_type)) + }; +}; +#endif + +template<bool> +struct DoAccept +{ + template <typename T> static void Do(T&, cmSourceFile*) {} +}; + +template<> +struct DoAccept<true> +{ + static void Do(std::vector<cmSourceFile*>& files, cmSourceFile* f) + { + files.push_back(f); + } + static void Do(cmGeneratorTarget::ResxData& data, cmSourceFile* f) + { + // Build and save the name of the corresponding .h file + // This relationship will be used later when building the project files. + // Both names would have been auto generated from Visual Studio + // where the user supplied the file name and Visual Studio + // appended the suffix. + std::string resx = f->GetFullPath(); + std::string hFileName = resx.substr(0, resx.find_last_of(".")) + ".h"; + data.ExpectedResxHeaders.insert(hFileName); + data.ResxSources.push_back(f); + } + static void Do(std::string& data, cmSourceFile* f) + { + data = f->GetFullPath(); + } +}; + +//---------------------------------------------------------------------------- +template<typename Tag, typename DataType = std::vector<cmSourceFile*> > +struct TagVisitor +{ + DataType& Data; + std::vector<cmSourceFile*> BadObjLibFiles; + cmTarget *Target; + cmGlobalGenerator *GlobalGenerator; + cmsys::RegularExpression Header; + bool IsObjLib; + + TagVisitor(cmTarget *target, DataType& data) + : Data(data), Target(target), + GlobalGenerator(target->GetMakefile() + ->GetLocalGenerator()->GetGlobalGenerator()), + Header(CM_HEADER_REGEX), + IsObjLib(target->GetType() == cmTarget::OBJECT_LIBRARY) + { + } + + ~TagVisitor() + { + reportBadObjLib(this->BadObjLibFiles, this->Target, + this->GlobalGenerator->GetCMakeInstance()); + } + + void Accept(cmSourceFile *sf) + { + std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); + if(sf->GetCustomCommand()) + { + DoAccept<IsSameTag<Tag, CustomCommandsTag>::Result>::Do(this->Data, sf); + } + else if(this->Target->GetType() == cmTarget::UTILITY) + { + DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf); + } + else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY")) + { + DoAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>::Do(this->Data, sf); + } + else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT")) + { + DoAccept<IsSameTag<Tag, ExternalObjectsTag>::Result>::Do(this->Data, sf); + if(this->IsObjLib) + { + this->BadObjLibFiles.push_back(sf); + } + } + else if(sf->GetLanguage()) + { + DoAccept<IsSameTag<Tag, ObjectSourcesTag>::Result>::Do(this->Data, sf); + } + else if(ext == "def") + { + DoAccept<IsSameTag<Tag, ModuleDefinitionFileTag>::Result>::Do(this->Data, + sf); + if(this->IsObjLib) + { + this->BadObjLibFiles.push_back(sf); + } + } + else if(ext == "idl") + { + DoAccept<IsSameTag<Tag, IDLSourcesTag>::Result>::Do(this->Data, sf); + if(this->IsObjLib) + { + this->BadObjLibFiles.push_back(sf); + } + } + else if(ext == "resx") + { + DoAccept<IsSameTag<Tag, ResxTag>::Result>::Do(this->Data, sf); + } + else if(this->Header.find(sf->GetFullPath().c_str())) + { + DoAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>::Do(this->Data, sf); + } + else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str())) + { + DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf); + } + else + { + DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf); + if(this->IsObjLib && ext != "txt") + { + this->BadObjLibFiles.push_back(sf); + } + } + } +}; + +//---------------------------------------------------------------------------- cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t), SourceFileFlagsConstructed(false) { @@ -96,11 +284,34 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt, } } +#define IMPLEMENT_VISIT_IMPL(DATA, DATATYPE) \ + { \ + std::vector<cmSourceFile*> sourceFiles; \ + this->Target->GetSourceFiles(sourceFiles); \ + TagVisitor<DATA ## Tag DATATYPE> visitor(this->Target, data); \ + for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \ + si != sourceFiles.end(); ++si) \ + { \ + visitor.Accept(*si); \ + } \ + } \ + + +#define IMPLEMENT_VISIT(DATA) \ + IMPLEMENT_VISIT_IMPL(DATA, EMPTY) \ + +#define EMPTY +#define COMMA , + //---------------------------------------------------------------------------- void -cmGeneratorTarget::GetObjectSources(std::vector<cmSourceFile*> &objs) const +cmGeneratorTarget::GetObjectSources(std::vector<cmSourceFile*> &data) const { - objs = this->ObjectSources; + IMPLEMENT_VISIT(ObjectSources); + if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY) + { + this->ObjectSources = data; + } } //---------------------------------------------------------------------------- @@ -129,49 +340,53 @@ bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const } //---------------------------------------------------------------------------- -void cmGeneratorTarget::GetResxSources(std::vector<cmSourceFile*>& srcs) const +void cmGeneratorTarget::GetIDLSources(std::vector<cmSourceFile*>& data) const { - srcs = this->ResxSources; + IMPLEMENT_VISIT(IDLSources); } //---------------------------------------------------------------------------- -void cmGeneratorTarget::GetIDLSources(std::vector<cmSourceFile*>& srcs) const +void +cmGeneratorTarget::GetHeaderSources(std::vector<cmSourceFile*>& data) const { - srcs = this->IDLSources; + IMPLEMENT_VISIT(HeaderSources); } //---------------------------------------------------------------------------- -void -cmGeneratorTarget::GetHeaderSources(std::vector<cmSourceFile*>& srcs) const +void cmGeneratorTarget::GetExtraSources(std::vector<cmSourceFile*>& data) const { - srcs = this->HeaderSources; + IMPLEMENT_VISIT(ExtraSources); } //---------------------------------------------------------------------------- -void cmGeneratorTarget::GetExtraSources(std::vector<cmSourceFile*>& srcs) const +void +cmGeneratorTarget::GetCustomCommands(std::vector<cmSourceFile*>& data) const { - srcs = this->ExtraSources; + IMPLEMENT_VISIT(CustomCommands); } //---------------------------------------------------------------------------- void -cmGeneratorTarget::GetCustomCommands(std::vector<cmSourceFile*>& srcs) const +cmGeneratorTarget::GetExternalObjects(std::vector<cmSourceFile*>& data) const { - srcs = this->CustomCommands; + IMPLEMENT_VISIT(ExternalObjects); } //---------------------------------------------------------------------------- void cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs) const { - srcs = this->ExpectedResxHeaders; + ResxData data; + IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData) + srcs = data.ExpectedResxHeaders; } //---------------------------------------------------------------------------- -void -cmGeneratorTarget::GetExternalObjects(std::vector<cmSourceFile*>& srcs) const +void cmGeneratorTarget::GetResxSources(std::vector<cmSourceFile*>& srcs) const { - srcs = this->ExternalObjects; + ResxData data; + IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData) + srcs = data.ResxSources; } //---------------------------------------------------------------------------- @@ -283,102 +498,6 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const } //---------------------------------------------------------------------------- -void cmGeneratorTarget::ClassifySources() -{ - cmsys::RegularExpression header(CM_HEADER_REGEX); - - cmTarget::TargetType targetType = this->Target->GetType(); - bool isObjLib = targetType == cmTarget::OBJECT_LIBRARY; - - std::vector<cmSourceFile*> badObjLib; - std::vector<cmSourceFile*> sources; - this->Target->GetSourceFiles(sources); - for(std::vector<cmSourceFile*>::const_iterator si = sources.begin(); - si != sources.end(); ++si) - { - cmSourceFile* sf = *si; - std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); - if(sf->GetCustomCommand()) - { - this->CustomCommands.push_back(sf); - } - else if(targetType == cmTarget::UTILITY) - { - this->ExtraSources.push_back(sf); - } - else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY")) - { - this->HeaderSources.push_back(sf); - } - else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT")) - { - this->ExternalObjects.push_back(sf); - if(isObjLib) { badObjLib.push_back(sf); } - } - else if(sf->GetLanguage()) - { - this->ObjectSources.push_back(sf); - } - else if(ext == "def") - { - this->ModuleDefinitionFile = sf->GetFullPath(); - if(isObjLib) { badObjLib.push_back(sf); } - } - else if(ext == "idl") - { - this->IDLSources.push_back(sf); - if(isObjLib) { badObjLib.push_back(sf); } - } - else if(ext == "resx") - { - // Build and save the name of the corresponding .h file - // This relationship will be used later when building the project files. - // Both names would have been auto generated from Visual Studio - // where the user supplied the file name and Visual Studio - // appended the suffix. - std::string resx = sf->GetFullPath(); - std::string hFileName = resx.substr(0, resx.find_last_of(".")) + ".h"; - this->ExpectedResxHeaders.insert(hFileName); - this->ResxSources.push_back(sf); - } - else if(header.find(sf->GetFullPath().c_str())) - { - this->HeaderSources.push_back(sf); - } - else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str())) - { - // We only get here if a source file is not an external object - // and has an extension that is listed as an ignored file type. - // No message or diagnosis should be given. - this->ExtraSources.push_back(sf); - } - else - { - this->ExtraSources.push_back(sf); - if(isObjLib && ext != "txt") - { - badObjLib.push_back(sf); - } - } - } - - if(!badObjLib.empty()) - { - cmOStringStream e; - e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n"; - for(std::vector<cmSourceFile*>::iterator i = badObjLib.begin(); - i != badObjLib.end(); ++i) - { - e << " " << (*i)->GetLocation().GetName() << "\n"; - } - e << "but may contain only headers and sources that compile."; - this->GlobalGenerator->GetCMakeInstance() - ->IssueMessage(cmake::FATAL_ERROR, e.str(), - this->Target->GetBacktrace()); - } -} - -//---------------------------------------------------------------------------- void cmGeneratorTarget::LookupObjectLibraries() { std::vector<std::string> const& objLibs = @@ -433,7 +552,9 @@ void cmGeneratorTarget::LookupObjectLibraries() //---------------------------------------------------------------------------- std::string cmGeneratorTarget::GetModuleDefinitionFile() const { - return this->ModuleDefinitionFile; + std::string data; + IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile, COMMA std::string) + return data; } //---------------------------------------------------------------------------- diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 51d51f3..1e6ce64 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -82,7 +82,6 @@ public: */ void TraceDependencies(); - void ClassifySources(); void LookupObjectLibraries(); /** Get sources that must be built before the given source. */ @@ -113,23 +112,19 @@ public: struct SourceFileFlags GetTargetSourceFileFlags(const cmSourceFile* sf) const; + struct ResxData { + mutable std::set<std::string> ExpectedResxHeaders; + mutable std::vector<cmSourceFile*> ResxSources; + }; private: friend class cmTargetTraceDependencies; struct SourceEntry { std::vector<cmSourceFile*> Depends; }; typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType; SourceEntriesType SourceEntries; - std::string ModuleDefinitionFile; - - std::vector<cmSourceFile*> CustomCommands; - std::vector<cmSourceFile*> ExtraSources; - std::vector<cmSourceFile*> HeaderSources; - std::vector<cmSourceFile*> ExternalObjects; - std::vector<cmSourceFile*> IDLSources; - std::vector<cmSourceFile*> ResxSources; + std::map<cmSourceFile const*, std::string> Objects; std::set<cmSourceFile const*> ExplicitObjectName; - std::set<std::string> ExpectedResxHeaders; - std::vector<cmSourceFile*> ObjectSources; + mutable std::vector<cmSourceFile*> ObjectSources; std::vector<cmTarget*> ObjectLibraries; mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index e143eba..f76c6d1 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1439,7 +1439,6 @@ void cmGlobalGenerator::ComputeGeneratorTargetObjects() continue; } cmGeneratorTarget* gt = ti->second; - gt->ClassifySources(); gt->LookupObjectLibraries(); this->ComputeTargetObjects(gt); } |