/* 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 #include #include #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmProperty.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" class cmake; cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm) : cmGlobalGenerator(cm) { } cmGlobalCommonGenerator::~cmGlobalCommonGenerator() = default; std::map cmGlobalCommonGenerator::ComputeDirectoryTargets() const { std::map dirTargets; for (const auto& lg : this->LocalGenerators) { std::string const& currentBinaryDir( lg->GetStateSnapshot().GetDirectory().GetCurrentBinary()); DirectoryTarget& dirTarget = dirTargets[currentBinaryDir]; dirTarget.LG = lg.get(); const std::vector& configs = lg->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); // The directory-level rule should depend on the target-level rules // for all targets in the directory. for (const auto& gt : lg->GetGeneratorTargets()) { cmStateEnums::TargetType const type = gt->GetType(); if (type == cmStateEnums::GLOBAL_TARGET || !gt->IsInBuildSystem()) { continue; } DirectoryTarget::Target t; t.GT = gt.get(); const std::string EXCLUDE_FROM_ALL("EXCLUDE_FROM_ALL"); if (cmProp exclude = gt->GetProperty(EXCLUDE_FROM_ALL)) { for (const std::string& 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 const& 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( const DirectoryTarget::Target& t, const std::string& config) { if (this->IsMultiConfig()) { return cm::contains(t.ExcludedFromAllInConfigs, config); } return !t.ExcludedFromAllInConfigs.empty(); }