diff options
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 515 |
1 files changed, 0 insertions, 515 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 61b93be..fb921fd 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -23,8 +23,6 @@ #include <cmext/algorithm> #include <cmext/string_view> -#include "cmsys/RegularExpression.hxx" - #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmCryptoHash.h" @@ -49,7 +47,6 @@ #include "cmSourceFile.h" #include "cmSourceFileLocation.h" #include "cmSourceFileLocationKind.h" -#include "cmSourceGroup.h" #include "cmStandardLevel.h" #include "cmStandardLevelResolver.h" #include "cmState.h" @@ -1520,519 +1517,7 @@ void AddLangSpecificImplicitIncludeDirectories( } } -void AddObjectEntries(cmGeneratorTarget const* headTarget, - std::string const& config, - cmGeneratorExpressionDAGChecker* dagChecker, - EvaluatedTargetPropertyEntries& entries) -{ - if (cmLinkImplementationLibraries const* impl = - headTarget->GetLinkImplementationLibraries(config, UseTo::Compile)) { - entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition; - for (cmLinkImplItem const& lib : impl->Libraries) { - if (lib.Target && - lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) { - std::string uniqueName = - headTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely( - lib.Target); - std::string genex = "$<TARGET_OBJECTS:" + std::move(uniqueName) + ">"; - cmGeneratorExpression ge(*headTarget->Makefile->GetCMakeInstance(), - lib.Backtrace); - std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex); - cge->SetEvaluateForBuildsystem(true); - - EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace); - cmExpandList(cge->Evaluate(headTarget->GetLocalGenerator(), config, - headTarget, dagChecker), - ee.Values); - if (cge->GetHadContextSensitiveCondition()) { - ee.ContextDependent = true; - } - entries.Entries.emplace_back(std::move(ee)); - } - } - } -} - -void addFileSetEntry(cmGeneratorTarget const* headTarget, - std::string const& config, - cmGeneratorExpressionDAGChecker* dagChecker, - cmFileSet const* fileSet, - EvaluatedTargetPropertyEntries& entries) -{ - auto dirCges = fileSet->CompileDirectoryEntries(); - auto dirs = fileSet->EvaluateDirectoryEntries( - dirCges, headTarget->GetLocalGenerator(), config, headTarget, dagChecker); - bool contextSensitiveDirs = false; - for (auto const& dirCge : dirCges) { - if (dirCge->GetHadContextSensitiveCondition()) { - contextSensitiveDirs = true; - break; - } - } - cmake* cm = headTarget->GetLocalGenerator()->GetCMakeInstance(); - for (auto& entryCge : fileSet->CompileFileEntries()) { - auto tpe = cmGeneratorTarget::TargetPropertyEntry::CreateFileSet( - dirs, contextSensitiveDirs, std::move(entryCge), fileSet); - entries.Entries.emplace_back( - EvaluateTargetPropertyEntry(headTarget, config, "", dagChecker, *tpe)); - EvaluatedTargetPropertyEntry const& entry = entries.Entries.back(); - for (auto const& file : entry.Values) { - auto* sf = headTarget->Makefile->GetOrCreateSource(file); - if (fileSet->GetType() == "HEADERS"_s) { - sf->SetProperty("HEADER_FILE_ONLY", "TRUE"); - } - -#ifndef CMAKE_BOOTSTRAP - std::string e; - std::string w; - auto path = sf->ResolveFullPath(&e, &w); - if (!w.empty()) { - cm->IssueMessage(MessageType::AUTHOR_WARNING, w, entry.Backtrace); - } - if (path.empty()) { - if (!e.empty()) { - cm->IssueMessage(MessageType::FATAL_ERROR, e, entry.Backtrace); - } - return; - } - bool found = false; - for (auto const& sg : headTarget->Makefile->GetSourceGroups()) { - if (sg.MatchChildrenFiles(path)) { - found = true; - break; - } - } - if (!found) { - if (fileSet->GetType() == "HEADERS"_s) { - headTarget->Makefile->GetOrCreateSourceGroup("Header Files") - ->AddGroupFile(path); - } - } -#endif - } - } -} - -void AddFileSetEntries(cmGeneratorTarget const* headTarget, - std::string const& config, - cmGeneratorExpressionDAGChecker* dagChecker, - EvaluatedTargetPropertyEntries& entries) -{ - for (auto const& entry : headTarget->Target->GetHeaderSetsEntries()) { - for (auto const& name : cmList{ entry.Value }) { - auto const* headerSet = headTarget->Target->GetFileSet(name); - addFileSetEntry(headTarget, config, dagChecker, headerSet, entries); - } - } - for (auto const& entry : headTarget->Target->GetCxxModuleSetsEntries()) { - for (auto const& name : cmList{ entry.Value }) { - auto const* cxxModuleSet = headTarget->Target->GetFileSet(name); - addFileSetEntry(headTarget, config, dagChecker, cxxModuleSet, entries); - } - } -} - -bool processSources(cmGeneratorTarget const* tgt, - EvaluatedTargetPropertyEntries& entries, - std::vector<BT<std::string>>& srcs, - std::unordered_set<std::string>& uniqueSrcs, - bool debugSources) -{ - cmMakefile* mf = tgt->Target->GetMakefile(); - - bool contextDependent = entries.HadContextSensitiveCondition; - - for (EvaluatedTargetPropertyEntry& entry : entries.Entries) { - if (entry.ContextDependent) { - contextDependent = true; - } - - cmLinkImplItem const& item = entry.LinkImplItem; - std::string const& targetName = item.AsStr(); - - for (std::string& src : entry.Values) { - cmSourceFile* sf = mf->GetOrCreateSource(src); - std::string e; - std::string w; - std::string fullPath = sf->ResolveFullPath(&e, &w); - cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance(); - if (!w.empty()) { - cm->IssueMessage(MessageType::AUTHOR_WARNING, w, entry.Backtrace); - } - if (fullPath.empty()) { - if (!e.empty()) { - cm->IssueMessage(MessageType::FATAL_ERROR, e, entry.Backtrace); - } - return contextDependent; - } - - if (!targetName.empty() && !cmSystemTools::FileIsFullPath(src)) { - std::ostringstream err; - if (!targetName.empty()) { - err << "Target \"" << targetName - << "\" contains relative path in its INTERFACE_SOURCES:\n \"" - << src << "\""; - } else { - err << "Found relative path while evaluating sources of \"" - << tgt->GetName() << "\":\n \"" << src << "\"\n"; - } - tgt->GetLocalGenerator()->IssueMessage(MessageType::FATAL_ERROR, - err.str()); - return contextDependent; - } - src = fullPath; - } - std::string usedSources; - for (std::string const& src : entry.Values) { - if (uniqueSrcs.insert(src).second) { - srcs.emplace_back(src, entry.Backtrace); - if (debugSources) { - usedSources += " * " + src + "\n"; - } - } - } - if (!usedSources.empty()) { - tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage( - MessageType::LOG, - std::string("Used sources for target ") + tgt->GetName() + ":\n" + - usedSources, - entry.Backtrace); - } - } - return contextDependent; -} } - -std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( - std::string const& config) const -{ - std::vector<BT<std::string>> files; - - if (!this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) { - // 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. - - cmBTStringRange sourceEntries = this->Target->GetSourceEntries(); - for (auto const& entry : sourceEntries) { - cmList items{ entry.Value }; - for (auto const& item : items) { - if (cmHasLiteralPrefix(item, "$<TARGET_OBJECTS:") && - item.back() == '>') { - continue; - } - files.emplace_back(item); - } - } - return files; - } - - cmList debugProperties{ this->Makefile->GetDefinition( - "CMAKE_DEBUG_TARGET_PROPERTIES") }; - bool debugSources = - !this->DebugSourcesDone && cm::contains(debugProperties, "SOURCES"); - - if (this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) { - this->DebugSourcesDone = true; - } - - cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr, nullptr, - this->LocalGenerator); - - EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries( - this, config, std::string(), &dagChecker, this->SourceEntries); - - std::unordered_set<std::string> uniqueSrcs; - bool contextDependentDirectSources = - processSources(this, entries, files, uniqueSrcs, debugSources); - - // Collect INTERFACE_SOURCES of all direct link-dependencies. - EvaluatedTargetPropertyEntries linkInterfaceSourcesEntries; - AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(), - &dagChecker, linkInterfaceSourcesEntries, - IncludeRuntimeInterface::No, UseTo::Compile); - bool contextDependentInterfaceSources = processSources( - this, linkInterfaceSourcesEntries, files, uniqueSrcs, debugSources); - - // Collect TARGET_OBJECTS of direct object link-dependencies. - bool contextDependentObjects = false; - if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) { - EvaluatedTargetPropertyEntries linkObjectsEntries; - AddObjectEntries(this, config, &dagChecker, linkObjectsEntries); - contextDependentObjects = processSources(this, linkObjectsEntries, files, - uniqueSrcs, debugSources); - // Note that for imported targets or multi-config generators supporting - // cross-config builds the paths to the object files must be per-config, - // so contextDependentObjects will be true here even if object libraries - // are specified without per-config generator expressions. - } - - // Collect this target's file sets. - EvaluatedTargetPropertyEntries fileSetEntries; - AddFileSetEntries(this, config, &dagChecker, fileSetEntries); - bool contextDependentFileSets = - processSources(this, fileSetEntries, files, uniqueSrcs, debugSources); - - // Determine if sources are context-dependent or not. - if (!contextDependentDirectSources && !contextDependentInterfaceSources && - !contextDependentObjects && !contextDependentFileSets) { - this->SourcesAreContextDependent = Tribool::False; - } else { - this->SourcesAreContextDependent = Tribool::True; - } - - return files; -} - -void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*>& files, - const std::string& config) const -{ - std::vector<BT<cmSourceFile*>> tmp = this->GetSourceFiles(config); - files.reserve(tmp.size()); - for (BT<cmSourceFile*>& v : tmp) { - files.push_back(v.Value); - } -} - -std::vector<BT<cmSourceFile*>> cmGeneratorTarget::GetSourceFiles( - std::string const& config) const -{ - std::vector<BT<cmSourceFile*>> files; - if (!this->GlobalGenerator->GetConfigureDoneCMP0026()) { - // Since we are still configuring not all sources may exist yet, - // so we need to avoid full source classification because that - // requires the absolute paths to all sources to be determined. - // Since this is only for compatibility with old policies that - // projects should not depend on anymore, just compute the files - // without memoizing them. - std::vector<BT<std::string>> srcs = this->GetSourceFilePaths(config); - std::set<cmSourceFile*> emitted; - for (BT<std::string> const& s : srcs) { - cmSourceFile* sf = this->Makefile->GetOrCreateSource(s.Value); - if (emitted.insert(sf).second) { - files.emplace_back(sf, s.Backtrace); - } - } - return files; - } - - KindedSources const& kinded = this->GetKindedSources(config); - files.reserve(kinded.Sources.size()); - for (SourceAndKind const& si : kinded.Sources) { - files.push_back(si.Source); - } - return files; -} - -void cmGeneratorTarget::GetSourceFilesWithoutObjectLibraries( - std::vector<cmSourceFile*>& files, const std::string& config) const -{ - std::vector<BT<cmSourceFile*>> tmp = - this->GetSourceFilesWithoutObjectLibraries(config); - files.reserve(tmp.size()); - for (BT<cmSourceFile*>& v : tmp) { - files.push_back(v.Value); - } -} - -std::vector<BT<cmSourceFile*>> -cmGeneratorTarget::GetSourceFilesWithoutObjectLibraries( - std::string const& config) const -{ - std::vector<BT<cmSourceFile*>> files; - KindedSources const& kinded = this->GetKindedSources(config); - files.reserve(kinded.Sources.size()); - for (SourceAndKind const& si : kinded.Sources) { - if (si.Source.Value->GetObjectLibrary().empty()) { - files.push_back(si.Source); - } - } - return files; -} - -cmGeneratorTarget::KindedSources const& cmGeneratorTarget::GetKindedSources( - std::string const& config) const -{ - // If we already processed one configuration and found no dependency - // on configuration then always use the one result. - if (this->SourcesAreContextDependent == Tribool::False) { - return this->KindedSourcesMap.begin()->second; - } - - // Lookup any existing link implementation for this configuration. - std::string const key = cmSystemTools::UpperCase(config); - auto it = this->KindedSourcesMap.find(key); - if (it != this->KindedSourcesMap.end()) { - if (!it->second.Initialized) { - std::ostringstream e; - e << "The SOURCES of \"" << this->GetName() - << "\" use a generator expression that depends on the " - "SOURCES themselves."; - this->GlobalGenerator->GetCMakeInstance()->IssueMessage( - MessageType::FATAL_ERROR, e.str(), this->GetBacktrace()); - static KindedSources empty; - return empty; - } - return it->second; - } - - // Add an entry to the map for this configuration. - KindedSources& files = this->KindedSourcesMap[key]; - this->ComputeKindedSources(files, config); - files.Initialized = true; - return files; -} - -void cmGeneratorTarget::ComputeKindedSources(KindedSources& files, - std::string const& config) const -{ - // Get the source file paths by string. - std::vector<BT<std::string>> srcs = this->GetSourceFilePaths(config); - - cmsys::RegularExpression header_regex(CM_HEADER_REGEX); - std::vector<cmSourceFile*> badObjLib; - - std::set<cmSourceFile*> emitted; - for (BT<std::string> const& s : srcs) { - // Create each source at most once. - cmSourceFile* sf = this->Makefile->GetOrCreateSource(s.Value); - if (!emitted.insert(sf).second) { - continue; - } - - // Compute the kind (classification) of this source file. - SourceKind kind; - std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); - cmFileSet const* fs = this->GetFileSetForSource(config, sf); - if (sf->GetCustomCommand()) { - kind = SourceKindCustomCommand; - } else if (!this->Target->IsNormal() && !this->Target->IsImported() && - fs && (fs->GetType() == "CXX_MODULES"_s)) { - kind = SourceKindCxxModuleSource; - } else if (this->Target->GetType() == cmStateEnums::UTILITY || - this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY - // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 - // NOLINTNEXTLINE(bugprone-branch-clone) - ) { - kind = SourceKindExtra; - } else if (this->IsSourceFilePartOfUnityBatch(sf->ResolveFullPath())) { - kind = SourceKindUnityBatched; - // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165 - // NOLINTNEXTLINE(bugprone-branch-clone) - } else if (sf->GetPropertyAsBool("HEADER_FILE_ONLY")) { - kind = SourceKindHeader; - } else if (sf->GetPropertyAsBool("EXTERNAL_OBJECT")) { - kind = SourceKindExternalObject; - } else if (!sf->GetOrDetermineLanguage().empty()) { - kind = SourceKindObjectSource; - } else if (ext == "def") { - kind = SourceKindModuleDefinition; - if (this->GetType() == cmStateEnums::OBJECT_LIBRARY) { - badObjLib.push_back(sf); - } - } else if (ext == "idl") { - kind = SourceKindIDL; - if (this->GetType() == cmStateEnums::OBJECT_LIBRARY) { - badObjLib.push_back(sf); - } - } else if (ext == "resx") { - kind = SourceKindResx; - } else if (ext == "appxmanifest") { - kind = SourceKindAppManifest; - } else if (ext == "manifest") { - if (sf->GetPropertyAsBool("VS_DEPLOYMENT_CONTENT")) { - kind = SourceKindExtra; - } else { - kind = SourceKindManifest; - } - } else if (ext == "pfx") { - kind = SourceKindCertificate; - } else if (ext == "xaml") { - kind = SourceKindXaml; - } else if (header_regex.find(sf->ResolveFullPath())) { - kind = SourceKindHeader; - } else { - kind = SourceKindExtra; - } - - // Save this classified source file in the result vector. - files.Sources.push_back({ BT<cmSourceFile*>(sf, s.Backtrace), kind }); - } - - if (!badObjLib.empty()) { - std::ostringstream e; - e << "OBJECT library \"" << this->GetName() << "\" contains:\n"; - for (cmSourceFile* i : badObjLib) { - e << " " << i->GetLocation().GetName() << "\n"; - } - e << "but may contain only sources that compile, header files, and " - "other files that would not affect linking of a normal library."; - this->GlobalGenerator->GetCMakeInstance()->IssueMessage( - MessageType::FATAL_ERROR, e.str(), this->GetBacktrace()); - } -} - -std::vector<cmGeneratorTarget::AllConfigSource> const& -cmGeneratorTarget::GetAllConfigSources() const -{ - if (this->AllConfigSources.empty()) { - this->ComputeAllConfigSources(); - } - return this->AllConfigSources; -} - -void cmGeneratorTarget::ComputeAllConfigSources() const -{ - std::vector<std::string> configs = - this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); - - std::map<cmSourceFile const*, size_t> index; - - for (size_t ci = 0; ci < configs.size(); ++ci) { - KindedSources const& sources = this->GetKindedSources(configs[ci]); - for (SourceAndKind const& src : sources.Sources) { - auto mi = index.find(src.Source.Value); - if (mi == index.end()) { - AllConfigSource acs; - acs.Source = src.Source.Value; - acs.Kind = src.Kind; - this->AllConfigSources.push_back(std::move(acs)); - std::map<cmSourceFile const*, size_t>::value_type entry( - src.Source.Value, this->AllConfigSources.size() - 1); - mi = index.insert(entry).first; - } - this->AllConfigSources[mi->second].Configs.push_back(ci); - } - } -} - -std::vector<cmGeneratorTarget::AllConfigSource> -cmGeneratorTarget::GetAllConfigSources(SourceKind kind) const -{ - std::vector<AllConfigSource> result; - for (AllConfigSource const& source : this->GetAllConfigSources()) { - if (source.Kind == kind) { - result.push_back(source); - } - } - return result; -} - -std::set<std::string> cmGeneratorTarget::GetAllConfigCompileLanguages() const -{ - std::set<std::string> languages; - std::vector<AllConfigSource> const& sources = this->GetAllConfigSources(); - for (AllConfigSource const& si : sources) { - std::string const& lang = si.Source->GetOrDetermineLanguage(); - if (!lang.empty()) { - languages.emplace(lang); - } - } - return languages; -} - std::string cmGeneratorTarget::GetCompilePDBName( const std::string& config) const { |