diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2018-10-02 20:38:26 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2018-10-10 14:26:39 (GMT) |
commit | fc8955e8891c645cd369a3cc8b607a14a8ed5bd7 (patch) | |
tree | 8a20a759ac2ea54aae9411bad8c54d109dd1ae02 /Source | |
parent | 514f0b572ea8ca2ba87810aa8f48185f266a8eaa (diff) | |
download | CMake-fc8955e8891c645cd369a3cc8b607a14a8ed5bd7.zip CMake-fc8955e8891c645cd369a3cc8b607a14a8ed5bd7.tar.gz CMake-fc8955e8891c645cd369a3cc8b607a14a8ed5bd7.tar.bz2 |
add_subdirectory: Run subdirectory install rules in correct order
Before this change, install rules created by add_subdirectory()
would be executed after all of the top-level install rules, even
if they were declared before the top-level rules. This change
adds a new policy, CMP0082, which interleaves the add_subdirectory()
install rules with the other install rules so they are run in the
correct order.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 2 | ||||
-rw-r--r-- | Source/cmInstallGenerator.cxx | 13 | ||||
-rw-r--r-- | Source/cmInstallGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmInstallScriptGenerator.cxx | 4 | ||||
-rw-r--r-- | Source/cmInstallSubdirectoryGenerator.cxx | 77 | ||||
-rw-r--r-- | Source/cmInstallSubdirectoryGenerator.h | 41 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 63 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 4 | ||||
-rw-r--r-- | Source/cmPolicies.h | 6 |
9 files changed, 195 insertions, 19 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 3cf6c8f..5e2758a 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -260,6 +260,8 @@ set(SRCS cmInstallFilesGenerator.cxx cmInstallScriptGenerator.h cmInstallScriptGenerator.cxx + cmInstallSubdirectoryGenerator.h + cmInstallSubdirectoryGenerator.cxx cmInstallTargetGenerator.h cmInstallTargetGenerator.cxx cmInstallDirectoryGenerator.h diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 53ac716..2b23658 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -22,6 +22,19 @@ cmInstallGenerator::~cmInstallGenerator() { } +bool cmInstallGenerator::HaveInstall() +{ + return true; +} + +void cmInstallGenerator::CheckCMP0082(bool& haveSubdirectoryInstall, + bool& haveInstallAfterSubdirectory) +{ + if (haveSubdirectoryInstall) { + haveInstallAfterSubdirectory = true; + } +} + void cmInstallGenerator::AddInstallRule( std::ostream& os, std::string const& dest, cmInstallType type, std::vector<std::string> const& files, bool optional /* = false */, diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h index fc1ce86..e5b88c3 100644 --- a/Source/cmInstallGenerator.h +++ b/Source/cmInstallGenerator.h @@ -38,6 +38,10 @@ public: bool exclude_from_all); ~cmInstallGenerator() override; + virtual bool HaveInstall(); + virtual void CheckCMP0082(bool& haveSubdirectoryInstall, + bool& haveInstallAfterSubdirectory); + void AddInstallRule( std::ostream& os, std::string const& dest, cmInstallType type, std::vector<std::string> const& files, bool optional = false, diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index 3a90f4c..1d7784e 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -37,9 +37,9 @@ void cmInstallScriptGenerator::AddScriptInstallRule(std::ostream& os, std::string const& script) { if (this->Code) { - os << indent.Next() << script << "\n"; + os << indent << script << "\n"; } else { - os << indent.Next() << "include(\"" << script << "\")\n"; + os << indent << "include(\"" << script << "\")\n"; } } diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx new file mode 100644 index 0000000..ca9f134 --- /dev/null +++ b/Source/cmInstallSubdirectoryGenerator.cxx @@ -0,0 +1,77 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmInstallSubdirectoryGenerator.h" + +#include "cmLocalGenerator.h" +#include "cmMakefile.h" +#include "cmPolicies.h" +#include "cmScriptGenerator.h" +#include "cmSystemTools.h" + +#include <sstream> +#include <vector> + +cmInstallSubdirectoryGenerator::cmInstallSubdirectoryGenerator( + cmMakefile* makefile, const char* binaryDirectory, bool excludeFromAll) + : cmInstallGenerator(nullptr, std::vector<std::string>(), nullptr, + MessageDefault, excludeFromAll) + , Makefile(makefile) + , BinaryDirectory(binaryDirectory) +{ +} + +cmInstallSubdirectoryGenerator::~cmInstallSubdirectoryGenerator() +{ +} + +bool cmInstallSubdirectoryGenerator::HaveInstall() +{ + for (auto generator : this->Makefile->GetInstallGenerators()) { + if (generator->HaveInstall()) { + return true; + } + } + + return false; +} + +void cmInstallSubdirectoryGenerator::CheckCMP0082( + bool& haveSubdirectoryInstall, bool& /*unused*/) +{ + if (this->HaveInstall()) { + haveSubdirectoryInstall = true; + } +} + +void cmInstallSubdirectoryGenerator::Compute(cmLocalGenerator* lg) +{ + this->LocalGenerator = lg; +} + +void cmInstallSubdirectoryGenerator::GenerateScript(std::ostream& os) +{ + if (!this->ExcludeFromAll) { + cmPolicies::PolicyStatus status = + this->LocalGenerator->GetPolicyStatus(cmPolicies::CMP0082); + switch (status) { + case cmPolicies::WARN: + case cmPolicies::OLD: + // OLD behavior is handled in cmLocalGenerator::GenerateInstallRules() + break; + + case cmPolicies::NEW: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: { + Indent indent; + std::string odir = this->BinaryDirectory; + cmSystemTools::ConvertToUnixSlashes(odir); + os << indent << "if(NOT CMAKE_INSTALL_LOCAL_ONLY)\n" + << indent.Next() + << "# Include the install script for the subdirectory.\n" + << indent.Next() << "include(\"" << odir + << "/cmake_install.cmake\")\n" + << indent << "endif()\n\n"; + } break; + } + } +} diff --git a/Source/cmInstallSubdirectoryGenerator.h b/Source/cmInstallSubdirectoryGenerator.h new file mode 100644 index 0000000..35471dd --- /dev/null +++ b/Source/cmInstallSubdirectoryGenerator.h @@ -0,0 +1,41 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmInstallSubdirectoryGenerator_h +#define cmInstallSubdirectoryGenerator_h + +#include "cmConfigure.h" // IWYU pragma: keep + +#include "cmInstallGenerator.h" + +#include <iosfwd> +#include <string> + +class cmLocalGenerator; +class cmMakefile; + +/** \class cmInstallSubdirectoryGenerator + * \brief Generate target installation rules. + */ +class cmInstallSubdirectoryGenerator : public cmInstallGenerator +{ +public: + cmInstallSubdirectoryGenerator(cmMakefile* makefile, + const char* binaryDirectory, + bool excludeFromAll); + ~cmInstallSubdirectoryGenerator() override; + + bool HaveInstall() override; + void CheckCMP0082(bool& haveSubdirectoryInstall, + bool& haveInstallAfterSubdirectory) override; + + void Compute(cmLocalGenerator* lg) override; + +protected: + void GenerateScript(std::ostream& os) override; + + cmMakefile* Makefile; + std::string BinaryDirectory; + cmLocalGenerator* LocalGenerator; +}; + +#endif diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 7030725..21b029e 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -517,31 +517,62 @@ void cmLocalGenerator::GenerateInstallRules() } // Ask each install generator to write its code. + cmPolicies::PolicyStatus status = this->GetPolicyStatus(cmPolicies::CMP0082); std::vector<cmInstallGenerator*> const& installers = this->Makefile->GetInstallGenerators(); - for (cmInstallGenerator* installer : installers) { - installer->Generate(fout, config, configurationTypes); + bool haveSubdirectoryInstall = false; + bool haveInstallAfterSubdirectory = false; + if (status == cmPolicies::WARN) { + for (cmInstallGenerator* installer : installers) { + installer->CheckCMP0082(haveSubdirectoryInstall, + haveInstallAfterSubdirectory); + installer->Generate(fout, config, configurationTypes); + } + } else { + for (cmInstallGenerator* installer : installers) { + installer->Generate(fout, config, configurationTypes); + } } // Write rules from old-style specification stored in targets. this->GenerateTargetInstallRules(fout, config, configurationTypes); // Include install scripts from subdirectories. - std::vector<cmStateSnapshot> children = - this->Makefile->GetStateSnapshot().GetChildren(); - if (!children.empty()) { - fout << "if(NOT CMAKE_INSTALL_LOCAL_ONLY)\n"; - fout << " # Include the install script for each subdirectory.\n"; - for (cmStateSnapshot const& c : children) { - if (!c.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) { - std::string odir = c.GetDirectory().GetCurrentBinary(); - cmSystemTools::ConvertToUnixSlashes(odir); - fout << " include(\"" << odir << "/cmake_install.cmake\")" - << std::endl; + switch (status) { + case cmPolicies::WARN: + if (haveInstallAfterSubdirectory && + this->Makefile->PolicyOptionalWarningEnabled( + "CMAKE_POLICY_WARNING_CMP0082")) { + std::ostringstream e; + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0082) << "\n"; + this->IssueMessage(cmake::AUTHOR_WARNING, e.str()); } - } - fout << "\n"; - fout << "endif()\n\n"; + CM_FALLTHROUGH; + case cmPolicies::OLD: { + std::vector<cmStateSnapshot> children = + this->Makefile->GetStateSnapshot().GetChildren(); + if (!children.empty()) { + fout << "if(NOT CMAKE_INSTALL_LOCAL_ONLY)\n"; + fout << " # Include the install script for each subdirectory.\n"; + for (cmStateSnapshot const& c : children) { + if (!c.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) { + std::string odir = c.GetDirectory().GetCurrentBinary(); + cmSystemTools::ConvertToUnixSlashes(odir); + fout << " include(\"" << odir << "/cmake_install.cmake\")" + << std::endl; + } + } + fout << "\n"; + fout << "endif()\n\n"; + } + } break; + + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + // NEW behavior is handled in + // cmInstallSubdirectoryGenerator::GenerateScript() + break; } // Record the install manifest. diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 8d163b7..0a69d09 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -28,6 +28,7 @@ #include "cmGeneratorExpressionEvaluationFile.h" #include "cmGlobalGenerator.h" #include "cmInstallGenerator.h" // IWYU pragma: keep +#include "cmInstallSubdirectoryGenerator.h" #include "cmListFileCache.h" #include "cmSourceFile.h" #include "cmSourceFileLocation.h" @@ -1669,6 +1670,9 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath, } else { this->UnConfiguredDirectories.push_back(subMf); } + + this->AddInstallGenerator(new cmInstallSubdirectoryGenerator( + subMf, binPath.c_str(), excludeFromAll)); } const std::string& cmMakefile::GetCurrentSourceDirectory() const diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index a367e47..a469f1e 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -240,7 +240,11 @@ class cmMakefile; cmPolicies::WARN) \ SELECT(POLICY, CMP0081, \ "Relative paths not allowed in LINK_DIRECTORIES target property.", \ - 3, 13, 0, cmPolicies::WARN) + 3, 13, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0082, \ + "Install rules from add_subdirectory() are interleaved with those " \ + "in caller.", \ + 3, 14, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ |