123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmLinkItemGraphVisitor.h"
- #include <map>
- #include <utility>
- #include <vector>
- #include "cmGeneratorTarget.h"
- #include "cmLinkItem.h"
- #include "cmMakefile.h"
- void cmLinkItemGraphVisitor::VisitItem(cmLinkItem const& item)
- {
- if (this->ItemVisited(item)) {
- return;
- }
- this->OnItem(item);
- this->VisitLinks(item, item);
- }
- void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
- cmLinkItem const& rootItem)
- {
- if (!item.Target) {
- return;
- }
- for (auto const& config : item.Target->Makefile->GetGeneratorConfigs(
- cmMakefile::IncludeEmptyConfig)) {
- this->VisitLinks(item, rootItem, config);
- }
- }
- void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
- cmLinkItem const& rootItem,
- std::string const& config)
- {
- auto const& target = *item.Target;
- DependencyMap dependencies;
- cmLinkItemGraphVisitor::GetDependencies(target, config, dependencies);
- for (auto const& d : dependencies) {
- auto const& dependency = d.second;
- auto const& dependencyType = dependency.first;
- auto const& dependee = dependency.second;
- this->VisitItem(dependee);
- if (this->LinkVisited(item, dependee)) {
- continue;
- }
- this->OnDirectLink(item, dependee, dependencyType);
- if (rootItem.AsStr() != item.AsStr()) {
- this->OnIndirectLink(rootItem, dependee);
- }
- // Visit all the direct and indirect links.
- this->VisitLinks(dependee, dependee);
- this->VisitLinks(dependee, item);
- this->VisitLinks(dependee, rootItem);
- }
- }
- bool cmLinkItemGraphVisitor::ItemVisited(cmLinkItem const& item)
- {
- auto& collection = this->VisitedItems;
- bool const visited = collection.find(item.AsStr()) != collection.cend();
- if (!visited) {
- collection.insert(item.AsStr());
- }
- return visited;
- }
- bool cmLinkItemGraphVisitor::LinkVisited(cmLinkItem const& depender,
- cmLinkItem const& dependee)
- {
- auto const link = std::make_pair(depender.AsStr(), dependee.AsStr());
- bool const linkVisited =
- this->VisitedLinks.find(link) != this->VisitedLinks.cend();
- if (!linkVisited) {
- this->VisitedLinks.insert(link);
- }
- return linkVisited;
- }
- void cmLinkItemGraphVisitor::GetDependencies(cmGeneratorTarget const& target,
- std::string const& config,
- DependencyMap& dependencies)
- {
- const auto* implementationLibraries = target.GetLinkImplementationLibraries(
- config, cmGeneratorTarget::UseTo::Link);
- if (implementationLibraries) {
- for (auto const& lib : implementationLibraries->Libraries) {
- auto const& name = lib.AsStr();
- dependencies[name] = Dependency(DependencyType::LinkPrivate, lib);
- }
- }
- const auto* interfaceLibraries = target.GetLinkInterfaceLibraries(
- config, &target, cmGeneratorTarget::UseTo::Compile);
- if (interfaceLibraries) {
- for (auto const& lib : interfaceLibraries->Libraries) {
- auto const& name = lib.AsStr();
- if (dependencies.find(name) != dependencies.cend()) {
- dependencies[name] = Dependency(DependencyType::LinkPublic, lib);
- } else {
- dependencies[name] = Dependency(DependencyType::LinkInterface, lib);
- }
- }
- }
- std::vector<cmGeneratorTarget*> objectLibraries;
- target.GetObjectLibrariesCMP0026(objectLibraries);
- for (auto const& lib : objectLibraries) {
- auto const& name = lib->GetName();
- if (dependencies.find(name) == dependencies.cend()) {
- auto objectItem = cmLinkItem(lib, false, lib->GetBacktrace());
- dependencies[name] = Dependency(DependencyType::Object, objectItem);
- }
- }
- auto const& utilityItems = target.GetUtilityItems();
- for (auto const& item : utilityItems) {
- auto const& name = item.AsStr();
- if (dependencies.find(name) == dependencies.cend()) {
- dependencies[name] = Dependency(DependencyType::Utility, item);
- }
- }
- }
|