1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-05-10 07:10:32 +08:00
CMake/Source/cmLinkItemGraphVisitor.cxx
Kitware Robot 0b96ae1f6a Revise C++ coding style using clang-format with "east const"
Run the `clang-format.bash` script to update all our C and C++ code to a
new style defined by `.clang-format`, now with "east const" enforcement.
Use `clang-format` version 18.

* If you reached this commit for a line in `git blame`, re-run the blame
  operation starting at the parent of this commit to see older history
  for the content.

* See the parent commit for instructions to rebase a change across this
  style transition commit.

Issue: #26123
2025-01-23 13:09:50 -05:00

141 lines
4.1 KiB
C++

/* 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)
{
auto const* 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);
}
}
auto const* 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.GetObjectLibrariesInSources(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);
}
}
}