summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2018-10-02 20:38:26 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2018-10-10 14:26:39 (GMT)
commitfc8955e8891c645cd369a3cc8b607a14a8ed5bd7 (patch)
tree8a20a759ac2ea54aae9411bad8c54d109dd1ae02 /Source
parent514f0b572ea8ca2ba87810aa8f48185f266a8eaa (diff)
downloadCMake-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.txt2
-rw-r--r--Source/cmInstallGenerator.cxx13
-rw-r--r--Source/cmInstallGenerator.h4
-rw-r--r--Source/cmInstallScriptGenerator.cxx4
-rw-r--r--Source/cmInstallSubdirectoryGenerator.cxx77
-rw-r--r--Source/cmInstallSubdirectoryGenerator.h41
-rw-r--r--Source/cmLocalGenerator.cxx63
-rw-r--r--Source/cmMakefile.cxx4
-rw-r--r--Source/cmPolicies.h6
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) \