From 4a92df86670f6407531242cf81ebcec056cc3eb5 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 26 Sep 2019 11:56:56 -0400 Subject: cmGlobalNinjaGenerator: Remove unused AddDependencyToAll overload --- Source/cmGlobalNinjaGenerator.cxx | 5 ----- Source/cmGlobalNinjaGenerator.h | 1 - 2 files changed, 6 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 7bba874..3a3c5fb 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -893,11 +893,6 @@ void cmGlobalNinjaGenerator::AddDependencyToAll(cmGeneratorTarget* target) this->AppendTargetOutputs(target, this->AllDependencies); } -void cmGlobalNinjaGenerator::AddDependencyToAll(const std::string& input) -{ - this->AllDependencies.push_back(input); -} - void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() { for (auto const& asd : this->AssumedSourceDependencies) { diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index dca783f..3549946 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -295,7 +295,6 @@ public: void AppendTargetDependsClosure(cmGeneratorTarget const* target, cmNinjaOuts& outputs, bool omit_self); void AddDependencyToAll(cmGeneratorTarget* target); - void AddDependencyToAll(const std::string& input); const std::vector& GetLocalGenerators() const { -- cgit v0.12 From be7857f40d4cee1cd3de6900c9de6b45cb332fe7 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 27 Sep 2019 10:13:39 -0400 Subject: cmLocalCommonGenerator: Mark GetConfigName as const --- Source/cmLocalCommonGenerator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h index abebbc2..eaef6ab 100644 --- a/Source/cmLocalCommonGenerator.h +++ b/Source/cmLocalCommonGenerator.h @@ -25,7 +25,7 @@ public: std::string wd); ~cmLocalCommonGenerator() override; - std::string const& GetConfigName() { return this->ConfigName; } + std::string const& GetConfigName() const { return this->ConfigName; } std::string GetWorkingDirectory() const { return this->WorkingDirectory; } -- cgit v0.12 From 11fb377eb96e6a90ea96126a2d22739f6983182a Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 27 Sep 2019 11:15:00 -0400 Subject: cmLocalUnixMakefileGenerator3: Mark GetRelativeTargetDirectory const --- Source/cmLocalUnixMakefileGenerator3.cxx | 2 +- Source/cmLocalUnixMakefileGenerator3.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 1d87e93..c50989e 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -809,7 +809,7 @@ void cmLocalUnixMakefileGenerator3::WriteConvenienceRule( } std::string cmLocalUnixMakefileGenerator3::GetRelativeTargetDirectory( - cmGeneratorTarget* target) + cmGeneratorTarget const* target) const { std::string dir = cmStrCat(this->HomeRelativeOutputPath, this->GetTargetDirectory(target)); diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index c02c0dc..f2295ef 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -139,7 +139,8 @@ public: void WriteSpecialTargetsTop(std::ostream& makefileStream); void WriteSpecialTargetsBottom(std::ostream& makefileStream); - std::string GetRelativeTargetDirectory(cmGeneratorTarget* target); + std::string GetRelativeTargetDirectory( + cmGeneratorTarget const* target) const; // File pairs for implicit dependency scanning. The key of the map // is the depender and the value is the explicit dependee. -- cgit v0.12 From 0733a94f648d63e8492fbcff3413cef461cb18d8 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 25 Sep 2019 14:09:43 -0400 Subject: Ninja,Makefile: Fix subdir "all" with nested EXCLUDE_FROM_ALL subdir The "all" target defined for a subdirectory (e.g. `cd sub; make` or `ninja sub/all`) should not include the "all" targets from nested subdirectories (e.g. `sub/sub`) that are marked as `EXCLUDE_FROM_ALL`. Fix this and add a test case. Issue: #19753 Co-Author: Sebastian Holtermann --- Source/cmGlobalNinjaGenerator.cxx | 3 +++ Source/cmGlobalUnixMakefileGenerator3.cxx | 3 +++ Tests/RunCMake/add_subdirectory/ExcludeFromAll.cmake | 1 + Tests/RunCMake/add_subdirectory/ExcludeFromAll/CMakeLists.txt | 2 ++ Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/CMakeLists.txt | 1 + Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/subsub.cpp | 4 ++++ Tests/RunCMake/add_subdirectory/ExcludeFromAll/check-sub.cmake | 1 + Tests/RunCMake/add_subdirectory/ExcludeFromAll/check.cmake | 1 + 8 files changed, 16 insertions(+) create mode 100644 Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/CMakeLists.txt create mode 100644 Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/subsub.cpp diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 3a3c5fb..0339193 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1123,6 +1123,9 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) // The directory-level rule should depend on the directory-level // rules of the subdirectories. for (cmStateSnapshot const& state : lg->GetStateSnapshot().GetChildren()) { + if (state.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) { + continue; + } std::string const& currentBinaryDir = state.GetDirectory().GetCurrentBinary(); folderTargets.push_back( diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 4ce3d5e..df4673d 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -429,6 +429,9 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2( // The directory-level rule should depend on the directory-level // rules of the subdirectories. for (cmStateSnapshot const& c : lg->GetStateSnapshot().GetChildren()) { + if (check_all && c.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) { + continue; + } std::string subdir = cmStrCat(c.GetDirectory().GetCurrentBinary(), '/', pass); depends.push_back(std::move(subdir)); diff --git a/Tests/RunCMake/add_subdirectory/ExcludeFromAll.cmake b/Tests/RunCMake/add_subdirectory/ExcludeFromAll.cmake index ff676a6..fbcfe7b 100644 --- a/Tests/RunCMake/add_subdirectory/ExcludeFromAll.cmake +++ b/Tests/RunCMake/add_subdirectory/ExcludeFromAll.cmake @@ -11,4 +11,5 @@ set(foo_lib \"$\") set(bar_lib \"$\") set(zot_lib \"$\") set(subinc_lib \"$\") +set(subsub_lib \"$\") ") diff --git a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/CMakeLists.txt b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/CMakeLists.txt index 790da54..9ed9e55 100644 --- a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/CMakeLists.txt +++ b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/CMakeLists.txt @@ -1,5 +1,7 @@ project(ExcludeFromAllSub NONE) +add_subdirectory(SubSub EXCLUDE_FROM_ALL) + add_library(bar STATIC EXCLUDE_FROM_ALL bar.cpp) add_library(zot STATIC zot.cpp) diff --git a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/CMakeLists.txt b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/CMakeLists.txt new file mode 100644 index 0000000..14f7973 --- /dev/null +++ b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/CMakeLists.txt @@ -0,0 +1 @@ +add_library(subsub STATIC subsub.cpp) diff --git a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/subsub.cpp b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/subsub.cpp new file mode 100644 index 0000000..ca689ed --- /dev/null +++ b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/subsub.cpp @@ -0,0 +1,4 @@ +int subsub() +{ + return 0; +} diff --git a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check-sub.cmake b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check-sub.cmake index 297ad1e..afacf6e 100644 --- a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check-sub.cmake +++ b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check-sub.cmake @@ -18,6 +18,7 @@ if(EXISTS ${RunCMake_TEST_BINARY_DIR}/check-debug.cmake) foreach(file "${main_exe}" "${bar_lib}" + "${subsub_lib}" ) if(EXISTS "${file}") set(RunCMake_TEST_FAILED diff --git a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check.cmake b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check.cmake index 433c032..b229f4c 100644 --- a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check.cmake +++ b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check.cmake @@ -21,6 +21,7 @@ if(EXISTS ${RunCMake_TEST_BINARY_DIR}/check-debug.cmake) foreach(file "${zot_lib}" "${bar_lib}" + "${subsub_lib}" ) if(EXISTS "${file}") set(RunCMake_TEST_FAILED -- cgit v0.12 From a49cd4d1a75f20180a349cdfea3fd384eedf3e8b Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 26 Sep 2019 14:35:55 -0400 Subject: Ninja: Fix EXCLUDE_FROM_ALL OFF on sub/sub/tgt in sub/all Defer adding a test to a later commit after all generators have been fixed. Issue: #19753 --- Source/cmGlobalNinjaGenerator.cxx | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 0339193..62106ac 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1114,8 +1114,25 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) type == cmStateEnums::SHARED_LIBRARY || type == cmStateEnums::MODULE_LIBRARY || type == cmStateEnums::OBJECT_LIBRARY || - type == cmStateEnums::UTILITY) && - !gt->GetPropertyAsBool("EXCLUDE_FROM_ALL")) { + type == cmStateEnums::UTILITY)) { + if (const char* exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) { + if (cmIsOn(exclude)) { + // This target has been explicitly excluded. + continue; + } + // This target has been explicitly un-excluded. The directory-level + // rule for every directory between this and the root (exclusive) + // should depend on the target-level rule for this target. + cmStateSnapshot dir = + lg->GetStateSnapshot().GetBuildsystemDirectoryParent(); + cmStateSnapshot parent = dir.GetBuildsystemDirectoryParent(); + while (parent.IsValid()) { + std::string const& folder = dir.GetDirectory().GetCurrentBinary(); + targetsPerFolder[folder].push_back(gt->GetName()); + dir = parent; + parent = parent.GetBuildsystemDirectoryParent(); + } + } folderTargets.push_back(gt->GetName()); } } -- cgit v0.12 From a75586c775eb8f663ca1372ff20f9a51e1ad420d Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 27 Sep 2019 08:50:54 -0400 Subject: Ninja: Simplify top-level "all" target generation Remove its dedicated implementation and update the per-directory "all" target generation to work for the top-level directory too. --- Source/cmGlobalNinjaGenerator.cxx | 45 +++++++++++---------------------------- Source/cmGlobalNinjaGenerator.h | 12 +---------- Source/cmLocalNinjaGenerator.cxx | 6 ------ 3 files changed, 14 insertions(+), 49 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 62106ac..3497828 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -20,6 +20,7 @@ #include "cmGeneratedFileStream.h" #include "cmGeneratorExpressionEvaluationFile.h" #include "cmGeneratorTarget.h" +#include "cmGlobalGenerator.h" #include "cmListFileCache.h" #include "cmLocalGenerator.h" #include "cmLocalNinjaGenerator.h" @@ -888,11 +889,6 @@ void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os) << cmVersion::GetMinorVersion() << "\n\n"; } -void cmGlobalNinjaGenerator::AddDependencyToAll(cmGeneratorTarget* target) -{ - this->AppendTargetOutputs(target, this->AllDependencies); -} - void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() { for (auto const& asd : this->AssumedSourceDependencies) { @@ -1091,19 +1087,11 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) cmGlobalNinjaGenerator::WriteDivider(os); os << "# Folder targets.\n\n"; - std::string const& rootBinaryDir = - this->LocalGenerators[0]->GetBinaryDirectory(); - std::map targetsPerFolder; for (cmLocalGenerator const* lg : this->LocalGenerators) { std::string const& currentBinaryFolder( lg->GetStateSnapshot().GetDirectory().GetCurrentBinary()); - // Do not generate a rule for the root binary dir. - if (currentBinaryFolder == rootBinaryDir) { - continue; - } - // The directory-level rule should depend on the target-level rules // for all targets in the directory. cmNinjaDeps& folderTargets = targetsPerFolder[currentBinaryFolder]; @@ -1121,19 +1109,16 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) continue; } // This target has been explicitly un-excluded. The directory-level - // rule for every directory between this and the root (exclusive) - // should depend on the target-level rule for this target. - cmStateSnapshot dir = - lg->GetStateSnapshot().GetBuildsystemDirectoryParent(); - cmStateSnapshot parent = dir.GetBuildsystemDirectoryParent(); - while (parent.IsValid()) { + // 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& folder = dir.GetDirectory().GetCurrentBinary(); - targetsPerFolder[folder].push_back(gt->GetName()); - dir = parent; - parent = parent.GetBuildsystemDirectoryParent(); + this->AppendTargetOutputs(gt, targetsPerFolder[folder]); } } - folderTargets.push_back(gt->GetName()); + this->AppendTargetOutputs(gt, folderTargets); } } @@ -1296,22 +1281,18 @@ void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os) cmGlobalNinjaGenerator::WriteDivider(os); os << "# Built-in targets\n\n"; - this->WriteTargetAll(os); + this->WriteTargetDefault(os); this->WriteTargetRebuildManifest(os); this->WriteTargetClean(os); this->WriteTargetHelp(os); } -void cmGlobalNinjaGenerator::WriteTargetAll(std::ostream& os) +void cmGlobalNinjaGenerator::WriteTargetDefault(std::ostream& os) { - cmNinjaBuild build("phony"); - build.Comment = "The main all target."; - build.Outputs.push_back(this->TargetAll); - build.ExplicitDeps = this->AllDependencies; - this->WriteBuild(os, build); - if (!this->HasOutputPathPrefix()) { - cmGlobalNinjaGenerator::WriteDefault(os, build.Outputs, + cmNinjaDeps all; + all.push_back(this->TargetAll); + cmGlobalNinjaGenerator::WriteDefault(os, all, "Make the all target the default."); } } diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 3549946..1bfbffa 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -17,7 +17,6 @@ #include "cmGeneratedFileStream.h" #include "cmGlobalCommonGenerator.h" -#include "cmGlobalGenerator.h" #include "cmGlobalGeneratorFactory.h" #include "cmNinjaTypes.h" #include "cmPolicies.h" @@ -294,18 +293,12 @@ public: cmNinjaDeps& outputs); void AppendTargetDependsClosure(cmGeneratorTarget const* target, cmNinjaOuts& outputs, bool omit_self); - void AddDependencyToAll(cmGeneratorTarget* target); const std::vector& GetLocalGenerators() const { return LocalGenerators; } - bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) - { - return cmGlobalGenerator::IsExcluded(root, target); - } - int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; } void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target); @@ -372,7 +365,7 @@ private: void WriteUnknownExplicitDependencies(std::ostream& os); void WriteBuiltinTargets(std::ostream& os); - void WriteTargetAll(std::ostream& os); + void WriteTargetDefault(std::ostream& os); void WriteTargetRebuildManifest(std::ostream& os); bool WriteTargetCleanAdditional(std::ostream& os); void WriteTargetClean(std::ostream& os); @@ -399,9 +392,6 @@ private: /// Length of rule command, used by rsp file evaluation std::unordered_map RuleCmdLength; - /// The set of dependencies to add to the "all" target. - cmNinjaDeps AllDependencies; - bool UsingGCCOnWindows = false; /// The set of custom commands we have seen. diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index fed8be5..187a847 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -88,12 +88,6 @@ void cmLocalNinjaGenerator::Generate() auto tg = cmNinjaTargetGenerator::New(target); if (tg) { tg->Generate(); - // Add the target to "all" if required. - if (!this->GetGlobalNinjaGenerator()->IsExcluded( - this->GetGlobalNinjaGenerator()->GetLocalGenerators()[0], - target)) { - this->GetGlobalNinjaGenerator()->AddDependencyToAll(target); - } } } -- cgit v0.12 From d713bcb6427381ab8743084726196a4eed96c135 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 27 Sep 2019 09:23:35 -0400 Subject: Ninja: Factor out per-dir "all" target computation into common generator This will make it re-usable for the Makefile generator. --- Source/cmGlobalCommonGenerator.cxx | 66 +++++++++++++++++++++++++++++++ Source/cmGlobalCommonGenerator.h | 24 ++++++++++++ Source/cmGlobalNinjaGenerator.cxx | 80 +++++++++++--------------------------- 3 files changed, 112 insertions(+), 58 deletions(-) diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx index bf992b4..93ff00b 100644 --- a/Source/cmGlobalCommonGenerator.cxx +++ b/Source/cmGlobalCommonGenerator.cxx @@ -2,6 +2,15 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGlobalCommonGenerator.h" +#include "cmGeneratorTarget.h" +#include "cmLocalGenerator.h" +#include "cmStateDirectory.h" +#include "cmStateSnapshot.h" +#include "cmStateTypes.h" +#include "cmStringAlgorithms.h" + +#include + class cmake; cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm) @@ -10,3 +19,60 @@ cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm) } cmGlobalCommonGenerator::~cmGlobalCommonGenerator() = default; + +std::map +cmGlobalCommonGenerator::ComputeDirectoryTargets() const +{ + std::map dirTargets; + for (cmLocalGenerator* lg : this->LocalGenerators) { + std::string const& currentBinaryDir( + lg->GetStateSnapshot().GetDirectory().GetCurrentBinary()); + DirectoryTarget& dirTarget = dirTargets[currentBinaryDir]; + dirTarget.LG = lg; + + // The directory-level rule should depend on the target-level rules + // for all targets in the directory. + for (auto gt : lg->GetGeneratorTargets()) { + cmStateEnums::TargetType const type = gt->GetType(); + if (type != cmStateEnums::EXECUTABLE && + type != cmStateEnums::STATIC_LIBRARY && + type != cmStateEnums::SHARED_LIBRARY && + type != cmStateEnums::MODULE_LIBRARY && + type != cmStateEnums::OBJECT_LIBRARY && + type != cmStateEnums::UTILITY) { + continue; + } + DirectoryTarget::Target t; + t.GT = gt; + if (const char* exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) { + if (cmIsOn(exclude)) { + // This target has been explicitly excluded. + t.ExcludeFromAll = true; + } else { + // 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; +} diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h index e19118b..de81da7 100644 --- a/Source/cmGlobalCommonGenerator.h +++ b/Source/cmGlobalCommonGenerator.h @@ -7,7 +7,13 @@ #include "cmGlobalGenerator.h" +#include +#include +#include + class cmake; +class cmGeneratorTarget; +class cmLocalGenerator; /** \class cmGlobalCommonGenerator * \brief Common infrastructure for Makefile and Ninja global generators. @@ -17,6 +23,24 @@ class cmGlobalCommonGenerator : public cmGlobalGenerator public: cmGlobalCommonGenerator(cmake* cm); ~cmGlobalCommonGenerator() override; + + struct DirectoryTarget + { + cmLocalGenerator* LG = nullptr; + struct Target + { + cmGeneratorTarget const* GT = nullptr; + bool ExcludeFromAll = false; + }; + std::vector Targets; + struct Dir + { + std::string Path; + bool ExcludeFromAll = false; + }; + std::vector Children; + }; + std::map ComputeDirectoryTargets() const; }; #endif diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 3497828..d8fe258 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1087,68 +1087,32 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) cmGlobalNinjaGenerator::WriteDivider(os); os << "# Folder targets.\n\n"; - std::map targetsPerFolder; - for (cmLocalGenerator const* lg : this->LocalGenerators) { - std::string const& currentBinaryFolder( - lg->GetStateSnapshot().GetDirectory().GetCurrentBinary()); - - // The directory-level rule should depend on the target-level rules - // for all targets in the directory. - cmNinjaDeps& folderTargets = targetsPerFolder[currentBinaryFolder]; - for (auto gt : lg->GetGeneratorTargets()) { - cmStateEnums::TargetType const type = gt->GetType(); - if ((type == cmStateEnums::EXECUTABLE || - type == cmStateEnums::STATIC_LIBRARY || - type == cmStateEnums::SHARED_LIBRARY || - type == cmStateEnums::MODULE_LIBRARY || - type == cmStateEnums::OBJECT_LIBRARY || - type == cmStateEnums::UTILITY)) { - if (const char* exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) { - if (cmIsOn(exclude)) { - // This target has been explicitly excluded. - continue; - } - // 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& folder = dir.GetDirectory().GetCurrentBinary(); - this->AppendTargetOutputs(gt, targetsPerFolder[folder]); - } - } - this->AppendTargetOutputs(gt, folderTargets); - } - } + std::map dirTargets = + this->ComputeDirectoryTargets(); - // The directory-level rule should depend on the directory-level - // rules of the subdirectories. - for (cmStateSnapshot const& state : lg->GetStateSnapshot().GetChildren()) { - if (state.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) { - continue; + for (auto const& it : dirTargets) { + cmNinjaBuild build("phony"); + cmGlobalNinjaGenerator::WriteDivider(os); + std::string const& currentBinaryDir = it.first; + DirectoryTarget const& dt = it.second; + + // Setup target + build.Comment = "Folder: " + currentBinaryDir; + build.Outputs.emplace_back( + this->ConvertToNinjaPath(currentBinaryDir + "/all")); + for (DirectoryTarget::Target const& t : dt.Targets) { + if (!t.ExcludeFromAll) { + this->AppendTargetOutputs(t.GT, build.ExplicitDeps); } - std::string const& currentBinaryDir = - state.GetDirectory().GetCurrentBinary(); - folderTargets.push_back( - this->ConvertToNinjaPath(currentBinaryDir + "/all")); } - } - - if (!targetsPerFolder.empty()) { - cmNinjaBuild build("phony"); - build.Outputs.emplace_back(""); - for (auto& it : targetsPerFolder) { - cmGlobalNinjaGenerator::WriteDivider(os); - std::string const& currentBinaryDir = it.first; - - // Setup target - build.Comment = "Folder: " + currentBinaryDir; - build.Outputs[0] = this->ConvertToNinjaPath(currentBinaryDir + "/all"); - build.ExplicitDeps = std::move(it.second); - // Write target - this->WriteBuild(os, build); + for (DirectoryTarget::Dir const& d : dt.Children) { + if (!d.ExcludeFromAll) { + build.ExplicitDeps.emplace_back( + this->ConvertToNinjaPath(d.Path + "/all")); + } } + // Write target + this->WriteBuild(os, build); } } -- cgit v0.12 From 742084337010ed26c19132a8b9d96e9e4891f9f6 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 27 Sep 2019 11:48:58 -0400 Subject: Makefiles: Fix EXCLUDE_FROM_ALL OFF on sub/sub/tgt in sub/all Defer adding a test to a later commit after all generators have been fixed. Issue: #19753 Co-Author: Sebastian Holtermann --- Source/cmGlobalUnixMakefileGenerator3.cxx | 89 ++++++++++--------------------- Source/cmGlobalUnixMakefileGenerator3.h | 4 +- 2 files changed, 31 insertions(+), 62 deletions(-) diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index df4673d..4c2d69f 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -230,17 +230,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2() depends.push_back(this->EmptyRuleHackDepends); } - // Write and empty all: - lg->WriteMakeRule(makefileStream, "The main recursive all target", "all", - depends, no_commands, true); - - // Write an empty preinstall: - lg->WriteMakeRule(makefileStream, "The main recursive preinstall target", - "preinstall", depends, no_commands, true); - // Write out the "special" stuff lg->WriteSpecialTargetsTop(makefileStream); + // Write the directory level rules. + for (auto const& it : this->ComputeDirectoryTargets()) { + this->WriteDirectoryRules2(makefileStream, it.second); + } + // Write the target convenience rules for (cmLocalGenerator* localGen : this->LocalGenerators) { this->WriteConvenienceRules2( @@ -396,44 +393,37 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefileLanguageRules( } void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2( - std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg, - const char* pass, bool check_all, bool check_relink, - std::vector const& commands) + std::ostream& ruleFileStream, DirectoryTarget const& dt, const char* pass, + bool check_all, bool check_relink, std::vector const& commands) { - // Get the relative path to the subdirectory from the top. + auto* lg = static_cast(dt.LG); std::string makeTarget = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', pass); // The directory-level rule should depend on the target-level rules // for all targets in the directory. std::vector depends; - for (cmGeneratorTarget* gtarget : lg->GetGeneratorTargets()) { - int type = gtarget->GetType(); - if ((type == cmStateEnums::EXECUTABLE) || - (type == cmStateEnums::STATIC_LIBRARY) || - (type == cmStateEnums::SHARED_LIBRARY) || - (type == cmStateEnums::MODULE_LIBRARY) || - (type == cmStateEnums::OBJECT_LIBRARY) || - (type == cmStateEnums::UTILITY)) { - // Add this to the list of depends rules in this directory. - if ((!check_all || !gtarget->GetPropertyAsBool("EXCLUDE_FROM_ALL")) && - (!check_relink || - gtarget->NeedRelinkBeforeInstall(lg->GetConfigName()))) { - std::string tname = - cmStrCat(lg->GetRelativeTargetDirectory(gtarget), '/', pass); - depends.push_back(std::move(tname)); - } + for (DirectoryTarget::Target const& t : dt.Targets) { + // Add this to the list of depends rules in this directory. + if ((!check_all || !t.ExcludeFromAll) && + (!check_relink || + t.GT->NeedRelinkBeforeInstall(lg->GetConfigName()))) { + // The target may be from a different directory; use its local gen. + auto const* tlg = static_cast( + t.GT->GetLocalGenerator()); + std::string tname = + cmStrCat(tlg->GetRelativeTargetDirectory(t.GT), '/', pass); + depends.push_back(std::move(tname)); } } // The directory-level rule should depend on the directory-level // rules of the subdirectories. - for (cmStateSnapshot const& c : lg->GetStateSnapshot().GetChildren()) { - if (check_all && c.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) { + for (DirectoryTarget::Dir const& d : dt.Children) { + if (check_all && d.ExcludeFromAll) { continue; } - std::string subdir = - cmStrCat(c.GetDirectory().GetCurrentBinary(), '/', pass); + std::string subdir = cmStrCat(d.Path, '/', pass); depends.push_back(std::move(subdir)); } @@ -455,8 +445,9 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2( } void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2( - std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg) + std::ostream& ruleFileStream, DirectoryTarget const& dt) { + auto* lg = static_cast(dt.LG); // Begin the directory-level rules section. { std::string dir = @@ -471,19 +462,17 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2( ruleFileStream << "\n\n"; } - if (!lg->IsRootMakefile()) { - // Write directory-level rules for "all". - this->WriteDirectoryRule2(ruleFileStream, lg, "all", true, false); + // Write directory-level rules for "all". + this->WriteDirectoryRule2(ruleFileStream, dt, "all", true, false); - // Write directory-level rules for "preinstall". - this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true); - } + // Write directory-level rules for "preinstall". + this->WriteDirectoryRule2(ruleFileStream, dt, "preinstall", true, true); // Write directory-level rules for "clean". { std::vector cmds; lg->AppendDirectoryCleanCommand(cmds); - this->WriteDirectoryRule2(ruleFileStream, lg, "clean", false, false, cmds); + this->WriteDirectoryRule2(ruleFileStream, dt, "clean", false, false, cmds); } } @@ -630,9 +619,6 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( std::string localName; std::string makeTargetName; - // write the directory level rules for this local gen - this->WriteDirectoryRules2(ruleFileStream, lg); - bool regenerate = !this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION"); if (regenerate) { depends.emplace_back("cmake_check_build_system"); @@ -698,15 +684,6 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( lg->WriteMakeRule(ruleFileStream, "All Build rule for target.", localName, depends, commands, true); - // add the all/all dependency - if (!this->IsExcluded(this->LocalGenerators[0], gtarget)) { - depends.clear(); - depends.push_back(localName); - commands.clear(); - lg->WriteMakeRule(ruleFileStream, "Include target in all.", "all", - depends, commands, true); - } - // Write the rule. commands.clear(); @@ -760,14 +737,6 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2( lg->WriteMakeRule(ruleFileStream, "Pre-install relink rule for target.", localName, depends, commands, true); - - if (!this->IsExcluded(this->LocalGenerators[0], gtarget)) { - depends.clear(); - depends.push_back(localName); - commands.clear(); - lg->WriteMakeRule(ruleFileStream, "Prepare target for install.", - "preinstall", depends, commands, true); - } } // add the clean rule diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 6a39509..79db30e 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -164,11 +164,11 @@ protected: cmLocalUnixMakefileGenerator3*); void WriteDirectoryRule2(std::ostream& ruleFileStream, - cmLocalUnixMakefileGenerator3* lg, const char* pass, + DirectoryTarget const& dt, const char* pass, bool check_all, bool check_relink, std::vector const& commands = {}); void WriteDirectoryRules2(std::ostream& ruleFileStream, - cmLocalUnixMakefileGenerator3* lg); + DirectoryTarget const& dt); void AppendGlobalTargetDepends(std::vector& depends, cmGeneratorTarget* target); -- cgit v0.12 From 8a15e75fe351579314f92dd9d9e2c6faeac5ad71 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 26 Sep 2019 11:47:14 -0400 Subject: Tests: Cover EXCLUDE_FROM_ALL OFF on sub/sub/tgt in sub/all Issue: #19753 --- Tests/RunCMake/add_subdirectory/ExcludeFromAll.cmake | 1 + Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/CMakeLists.txt | 2 ++ Tests/RunCMake/add_subdirectory/ExcludeFromAll/check-sub.cmake | 1 + Tests/RunCMake/add_subdirectory/ExcludeFromAll/check.cmake | 1 + 4 files changed, 5 insertions(+) diff --git a/Tests/RunCMake/add_subdirectory/ExcludeFromAll.cmake b/Tests/RunCMake/add_subdirectory/ExcludeFromAll.cmake index fbcfe7b..57ab938 100644 --- a/Tests/RunCMake/add_subdirectory/ExcludeFromAll.cmake +++ b/Tests/RunCMake/add_subdirectory/ExcludeFromAll.cmake @@ -12,4 +12,5 @@ set(bar_lib \"$\") set(zot_lib \"$\") set(subinc_lib \"$\") set(subsub_lib \"$\") +set(subsubinc_lib \"$\") ") diff --git a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/CMakeLists.txt b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/CMakeLists.txt index 14f7973..ec28275 100644 --- a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/CMakeLists.txt +++ b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/SubSub/CMakeLists.txt @@ -1 +1,3 @@ add_library(subsub STATIC subsub.cpp) +add_library(subsubinc STATIC subsub.cpp) +set_property(TARGET subsubinc PROPERTY EXCLUDE_FROM_ALL OFF) diff --git a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check-sub.cmake b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check-sub.cmake index afacf6e..d318c10 100644 --- a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check-sub.cmake +++ b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check-sub.cmake @@ -8,6 +8,7 @@ if(EXISTS ${RunCMake_TEST_BINARY_DIR}/check-debug.cmake) "${foo_lib}" "${subinc_lib}" "${zot_lib}" + "${subsubinc_lib}" ) if(NOT EXISTS "${file}") set(RunCMake_TEST_FAILED diff --git a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check.cmake b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check.cmake index b229f4c..d4bdef2 100644 --- a/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check.cmake +++ b/Tests/RunCMake/add_subdirectory/ExcludeFromAll/check.cmake @@ -8,6 +8,7 @@ if(EXISTS ${RunCMake_TEST_BINARY_DIR}/check-debug.cmake) "${foo_lib}" "${subinc_lib}" "${main_exe}" + "${subsubinc_lib}" ) if(EXISTS "${file}") # Remove for next step of test. -- cgit v0.12