1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-05-10 07:10:32 +08:00
CMake/Source/cmGlobalCommonGenerator.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

151 lines
5.4 KiB
C++

/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalCommonGenerator.h"
#include <algorithm>
#include <memory>
#include <utility>
#include <cmext/algorithm>
#include <cmsys/Glob.hxx>
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmake.h"
cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm)
: cmGlobalGenerator(cm)
{
}
cmGlobalCommonGenerator::~cmGlobalCommonGenerator() = default;
std::map<std::string, cmGlobalCommonGenerator::DirectoryTarget>
cmGlobalCommonGenerator::ComputeDirectoryTargets() const
{
std::map<std::string, DirectoryTarget> dirTargets;
for (auto const& lg : this->LocalGenerators) {
std::string currentBinaryDir =
lg->GetStateSnapshot().GetDirectory().GetCurrentBinary();
DirectoryTarget& dirTarget = dirTargets[currentBinaryDir];
dirTarget.LG = lg.get();
std::vector<std::string> const& configs =
static_cast<cmLocalCommonGenerator const*>(lg.get())->GetConfigNames();
// The directory-level rule should depend on the target-level rules
// for all targets in the directory.
for (auto const& gt : lg->GetGeneratorTargets()) {
cmStateEnums::TargetType const type = gt->GetType();
if (type == cmStateEnums::GLOBAL_TARGET || !gt->IsInBuildSystem()) {
continue;
}
DirectoryTarget::Target t;
t.GT = gt.get();
std::string const EXCLUDE_FROM_ALL("EXCLUDE_FROM_ALL");
if (cmValue exclude = gt->GetProperty(EXCLUDE_FROM_ALL)) {
for (std::string const& config : configs) {
cmGeneratorExpressionInterpreter genexInterpreter(lg.get(), config,
gt.get());
if (cmIsOn(genexInterpreter.Evaluate(*exclude, EXCLUDE_FROM_ALL))) {
// This target has been explicitly excluded.
t.ExcludedFromAllInConfigs.push_back(config);
}
}
if (t.ExcludedFromAllInConfigs.empty()) {
// This target has been explicitly un-excluded. The directory-level
// rule for every directory between this and the root should depend
// on the target-level rule for this target.
for (cmStateSnapshot dir =
lg->GetStateSnapshot().GetBuildsystemDirectoryParent();
dir.IsValid(); dir = dir.GetBuildsystemDirectoryParent()) {
std::string d = dir.GetDirectory().GetCurrentBinary();
dirTargets[d].Targets.emplace_back(t);
}
}
}
dirTarget.Targets.emplace_back(t);
}
// The directory-level rule should depend on the directory-level
// rules of the subdirectories.
for (cmStateSnapshot const& state : lg->GetStateSnapshot().GetChildren()) {
DirectoryTarget::Dir d;
d.Path = state.GetDirectory().GetCurrentBinary();
d.ExcludeFromAll =
state.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL");
dirTarget.Children.emplace_back(std::move(d));
}
}
return dirTargets;
}
bool cmGlobalCommonGenerator::IsExcludedFromAllInConfig(
DirectoryTarget::Target const& t, std::string const& config)
{
if (this->IsMultiConfig()) {
return cm::contains(t.ExcludedFromAllInConfigs, config);
}
return !t.ExcludedFromAllInConfigs.empty();
}
std::string cmGlobalCommonGenerator::GetEditCacheCommand() const
{
// If generating for an extra IDE, the edit_cache target cannot
// launch a terminal-interactive tool, so always use cmake-gui.
if (!this->GetExtraGeneratorName().empty()) {
return cmSystemTools::GetCMakeGUICommand();
}
// Use an internal cache entry to track the latest dialog used
// to edit the cache, and use that for the edit_cache target.
cmake* cm = this->GetCMakeInstance();
std::string editCacheCommand = cm->GetCMakeEditCommand();
if (!cm->GetCacheDefinition("CMAKE_EDIT_COMMAND") ||
!editCacheCommand.empty()) {
if (this->SupportsDirectConsole() && editCacheCommand.empty()) {
editCacheCommand = cmSystemTools::GetCMakeCursesCommand();
}
if (editCacheCommand.empty()) {
editCacheCommand = cmSystemTools::GetCMakeGUICommand();
}
if (!editCacheCommand.empty()) {
cm->AddCacheEntry("CMAKE_EDIT_COMMAND", editCacheCommand,
"Path to cache edit program executable.",
cmStateEnums::INTERNAL);
}
}
cmValue edit_cmd = cm->GetCacheDefinition("CMAKE_EDIT_COMMAND");
return edit_cmd ? *edit_cmd : std::string();
}
void cmGlobalCommonGenerator::RemoveUnknownClangTidyExportFixesFiles() const
{
for (auto const& dir : this->ClangTidyExportFixesDirs) {
cmsys::Glob g;
g.SetRecurse(true);
g.SetListDirs(false);
g.FindFiles(cmStrCat(dir, "/*.yaml"));
for (auto const& file : g.GetFiles()) {
if (!this->ClangTidyExportFixesFiles.count(file) &&
!std::any_of(this->ClangTidyExportFixesFiles.begin(),
this->ClangTidyExportFixesFiles.end(),
[&file](std::string const& knownFile) -> bool {
return cmSystemTools::SameFile(file, knownFile);
})) {
cmSystemTools::RemoveFile(file);
}
}
}
}