Bläddra i källkod

install: Add CMAKE_INSTALL_MESSAGE variable (#13761)

Create a variable to allow users to control which installation
messages are printed.  In particular, provide a "LAZY" setting
that prints "Installing" messages but not "Up-to-date" messages.
This is desirable for incremental re-installations.

Suggested-by: J Decker <[email protected]>
Brad King 11 år sedan
förälder
incheckning
c9568de52c

+ 2 - 1
Help/command/file.rst

@@ -298,6 +298,7 @@ See the :command:`install(DIRECTORY)` command for documentation of
 permissions, ``PATTERN``, ``REGEX``, and ``EXCLUDE`` options.
 permissions, ``PATTERN``, ``REGEX``, and ``EXCLUDE`` options.
 
 
 The ``INSTALL`` signature differs slightly from ``COPY``: it prints
 The ``INSTALL`` signature differs slightly from ``COPY``: it prints
-status messages, and ``NO_SOURCE_PERMISSIONS`` is default.
+status messages (subject to the :variable:`CMAKE_INSTALL_MESSAGE` variable),
+and ``NO_SOURCE_PERMISSIONS`` is default.
 Installation scripts generated by the :command:`install` command
 Installation scripts generated by the :command:`install` command
 use this signature (with some undocumented options for internal use).
 use this signature (with some undocumented options for internal use).

+ 4 - 0
Help/command/install.rst

@@ -59,6 +59,10 @@ signatures that specify them.  The common options are:
   Specify that it is not an error if the file to be installed does
   Specify that it is not an error if the file to be installed does
   not exist.
   not exist.
 
 
+Command signatures that install files may print messages during
+installation.  Use the :variable:`CMAKE_INSTALL_MESSAGE` variable
+to control which messages are printed.
+
 Installing Targets
 Installing Targets
 ^^^^^^^^^^^^^^^^^^
 ^^^^^^^^^^^^^^^^^^
 
 

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -128,6 +128,7 @@ Variables that Change Behavior
    /variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE
    /variable/CMAKE_INCLUDE_DIRECTORIES_BEFORE
    /variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
    /variable/CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
    /variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
    /variable/CMAKE_INSTALL_DEFAULT_COMPONENT_NAME
+   /variable/CMAKE_INSTALL_MESSAGE
    /variable/CMAKE_INSTALL_PREFIX
    /variable/CMAKE_INSTALL_PREFIX
    /variable/CMAKE_LIBRARY_PATH
    /variable/CMAKE_LIBRARY_PATH
    /variable/CMAKE_MFC_FLAG
    /variable/CMAKE_MFC_FLAG

+ 5 - 0
Help/release/dev/install-messages.rst

@@ -0,0 +1,5 @@
+install-messages
+----------------
+
+* The :variable:`CMAKE_INSTALL_MESSAGE` variable was introduced to
+  optionally reduce output installation.

+ 30 - 0
Help/variable/CMAKE_INSTALL_MESSAGE.rst

@@ -0,0 +1,30 @@
+CMAKE_INSTALL_MESSAGE
+---------------------
+
+Specify verbosity of installation script code generated by the
+:command:`install` command (using the :command:`file(INSTALL)` command).
+For paths that are newly installed or updated, installation
+may print lines like::
+
+  -- Installing: /some/destination/path
+
+For paths that are already up to date, installation may print
+lines like::
+
+  -- Up-to-date: /some/destination/path
+
+The ``CMAKE_INSTALL_MESSAGE`` variable may be set to control
+which messages are printed:
+
+``ALWAYS``
+  Print both ``Installing`` and ``Up-to-date`` messages.
+
+``LAZY``
+  Print ``Installing`` but not ``Up-to-date`` messages.
+
+``NEVER``
+  Print neither ``Installing`` nor ``Up-to-date`` messages.
+
+Other values have undefined behavior and may not be diagnosed.
+
+If this variable is not set, the default behavior is ``ALWAYS``.

+ 4 - 4
Source/cmInstallCommand.cxx

@@ -26,7 +26,7 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator(cmTarget& target,
      const cmInstallCommandArguments& args, bool impLib, bool forceOpt = false)
      const cmInstallCommandArguments& args, bool impLib, bool forceOpt = false)
 {
 {
   cmInstallGenerator::MessageLevel message =
   cmInstallGenerator::MessageLevel message =
-    cmInstallGenerator::MessageDefault;
+    cmInstallGenerator::SelectMessageLevel(target.GetMakefile());
   return new cmInstallTargetGenerator(target, args.GetDestination().c_str(),
   return new cmInstallTargetGenerator(target, args.GetDestination().c_str(),
                         impLib, args.GetPermissions().c_str(),
                         impLib, args.GetPermissions().c_str(),
                         args.GetConfigurations(), args.GetComponent().c_str(),
                         args.GetConfigurations(), args.GetComponent().c_str(),
@@ -40,7 +40,7 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator(
     const cmInstallCommandArguments& args, bool programs)
     const cmInstallCommandArguments& args, bool programs)
 {
 {
   cmInstallGenerator::MessageLevel message =
   cmInstallGenerator::MessageLevel message =
-    cmInstallGenerator::MessageDefault;
+    cmInstallGenerator::SelectMessageLevel(mf);
   return new cmInstallFilesGenerator(mf,
   return new cmInstallFilesGenerator(mf,
                         absFiles, args.GetDestination().c_str(),
                         absFiles, args.GetDestination().c_str(),
                         programs, args.GetPermissions().c_str(),
                         programs, args.GetPermissions().c_str(),
@@ -1215,7 +1215,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
     }
     }
 
 
   cmInstallGenerator::MessageLevel message =
   cmInstallGenerator::MessageLevel message =
-    cmInstallGenerator::MessageDefault;
+    cmInstallGenerator::SelectMessageLevel(this->Makefile);
 
 
   // Create the directory install generator.
   // Create the directory install generator.
   this->Makefile->AddInstallGenerator(
   this->Makefile->AddInstallGenerator(
@@ -1344,7 +1344,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
     }
     }
 
 
   cmInstallGenerator::MessageLevel message =
   cmInstallGenerator::MessageLevel message =
-    cmInstallGenerator::MessageDefault;
+    cmInstallGenerator::SelectMessageLevel(this->Makefile);
 
 
   // Create the export install generator.
   // Create the export install generator.
   cmInstallExportGenerator* exportGenerator =
   cmInstallExportGenerator* exportGenerator =

+ 1 - 1
Source/cmInstallFilesCommand.cxx

@@ -133,7 +133,7 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
                                        "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
                                        "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
   std::vector<std::string> no_configurations;
   std::vector<std::string> no_configurations;
   cmInstallGenerator::MessageLevel message =
   cmInstallGenerator::MessageLevel message =
-    cmInstallGenerator::MessageDefault;
+    cmInstallGenerator::SelectMessageLevel(this->Makefile);
   this->Makefile->AddInstallGenerator(
   this->Makefile->AddInstallGenerator(
     new cmInstallFilesGenerator(this->Makefile, this->Files,
     new cmInstallFilesGenerator(this->Makefile, this->Files,
                                 destination.c_str(), false,
                                 destination.c_str(), false,

+ 28 - 0
Source/cmInstallGenerator.cxx

@@ -11,6 +11,7 @@
 ============================================================================*/
 ============================================================================*/
 #include "cmInstallGenerator.h"
 #include "cmInstallGenerator.h"
 
 
+#include "cmMakefile.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
 
 
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
@@ -98,6 +99,13 @@ void cmInstallGenerator
     {
     {
     os << " OPTIONAL";
     os << " OPTIONAL";
     }
     }
+  switch(this->Message)
+    {
+    case MessageDefault: break;
+    case MessageAlways: os << " MESSAGE_ALWAYS"; break;
+    case MessageLazy:   os << " MESSAGE_LAZY"; break;
+    case MessageNever:  os << " MESSAGE_NEVER"; break;
+    }
   if(permissions_file && *permissions_file)
   if(permissions_file && *permissions_file)
     {
     {
     os << " PERMISSIONS" << permissions_file;
     os << " PERMISSIONS" << permissions_file;
@@ -182,3 +190,23 @@ std::string cmInstallGenerator::GetInstallDestination() const
   result += this->Destination;
   result += this->Destination;
   return result;
   return result;
 }
 }
+
+//----------------------------------------------------------------------------
+cmInstallGenerator::MessageLevel
+cmInstallGenerator::SelectMessageLevel(cmMakefile* mf)
+{
+  std::string m = mf->GetSafeDefinition("CMAKE_INSTALL_MESSAGE");
+  if(m == "ALWAYS")
+    {
+    return MessageAlways;
+    }
+  if(m == "LAZY")
+    {
+    return MessageLazy;
+    }
+  if(m == "NEVER")
+    {
+    return MessageNever;
+    }
+  return MessageDefault;
+}

+ 7 - 0
Source/cmInstallGenerator.h

@@ -16,6 +16,7 @@
 #include "cmScriptGenerator.h"
 #include "cmScriptGenerator.h"
 
 
 class cmLocalGenerator;
 class cmLocalGenerator;
+class cmMakefile;
 
 
 /** \class cmInstallGenerator
 /** \class cmInstallGenerator
  * \brief Support class for generating install scripts.
  * \brief Support class for generating install scripts.
@@ -27,6 +28,9 @@ public:
   enum MessageLevel
   enum MessageLevel
   {
   {
     MessageDefault,
     MessageDefault,
+    MessageAlways,
+    MessageLazy,
+    MessageNever
   };
   };
 
 
   cmInstallGenerator(const char* destination,
   cmInstallGenerator(const char* destination,
@@ -56,6 +60,9 @@ public:
   /** Test if this generator installs something for a given configuration.  */
   /** Test if this generator installs something for a given configuration.  */
   bool InstallsForConfig(const std::string& config);
   bool InstallsForConfig(const std::string& config);
 
 
+  /** Select message level from CMAKE_INSTALL_MESSAGE.  */
+  static MessageLevel SelectMessageLevel(cmMakefile* mf);
+
 protected:
 protected:
   virtual void GenerateScript(std::ostream& os);
   virtual void GenerateScript(std::ostream& os);
 
 

+ 1 - 1
Source/cmInstallProgramsCommand.cxx

@@ -94,7 +94,7 @@ void cmInstallProgramsCommand::FinalPass()
                                        "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
                                        "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
   std::vector<std::string> no_configurations;
   std::vector<std::string> no_configurations;
   cmInstallGenerator::MessageLevel message =
   cmInstallGenerator::MessageLevel message =
-    cmInstallGenerator::MessageDefault;
+    cmInstallGenerator::SelectMessageLevel(this->Makefile);
   this->Makefile->AddInstallGenerator(
   this->Makefile->AddInstallGenerator(
     new cmInstallFilesGenerator(this->Makefile, this->Files,
     new cmInstallFilesGenerator(this->Makefile, this->Files,
                                 destination.c_str(), true,
                                 destination.c_str(), true,

+ 1 - 1
Source/cmLocalGenerator.cxx

@@ -3004,7 +3004,7 @@ public:
   cmInstallTargetGeneratorLocal(cmTarget& t, const char* dest, bool implib):
   cmInstallTargetGeneratorLocal(cmTarget& t, const char* dest, bool implib):
     cmInstallTargetGenerator(
     cmInstallTargetGenerator(
       t, dest, implib, "", std::vector<std::string>(), "Unspecified",
       t, dest, implib, "", std::vector<std::string>(), "Unspecified",
-      MessageDefault,
+      cmInstallGenerator::SelectMessageLevel(t.GetMakefile()),
       false) {}
       false) {}
 };
 };
 
 

+ 24 - 0
Tests/RunCMake/install/DIRECTORY-message-lazy-check.cmake

@@ -0,0 +1,24 @@
+file(REMOVE_RECURSE ${RunCMake_TEST_BINARY_DIR}/prefix)
+execute_process(COMMAND ${CMAKE_COMMAND} -P ${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake
+  OUTPUT_VARIABLE out ERROR_VARIABLE err)
+set(expect "
+-- Installing: [^\n]*/prefix/dir\r?
+-- Installing: [^\n]*/prefix/dir/empty.txt\r?
+")
+if(NOT out MATCHES "${expect}")
+  string(REGEX REPLACE "\n" "\n  " out "  ${out}")
+  set(RunCMake_TEST_FAILED
+    "${RunCMake_TEST_FAILED}First install did not say 'Installing' as expected:\n${out}")
+endif()
+set(f ${RunCMake_TEST_BINARY_DIR}/prefix/dir/empty.txt)
+if(NOT EXISTS "${f}")
+  set(RunCMake_TEST_FAILED
+    "${RunCMake_TEST_FAILED}File was not installed:\n  ${f}\n")
+endif()
+execute_process(COMMAND ${CMAKE_COMMAND} -P ${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake
+  OUTPUT_VARIABLE out ERROR_VARIABLE err)
+if(out MATCHES "(Installing|Up-to-date)")
+  string(REGEX REPLACE "\n" "\n  " out "  ${out}")
+  set(RunCMake_TEST_FAILED
+    "${RunCMake_TEST_FAILED}Second install was not silent as expected:\n${out}")
+endif()

+ 3 - 0
Tests/RunCMake/install/DIRECTORY-message-lazy.cmake

@@ -0,0 +1,3 @@
+set(CMAKE_INSTALL_MESSAGE "LAZY")
+set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/prefix")
+install(DIRECTORY dir/ DESTINATION dir)

+ 1 - 0
Tests/RunCMake/install/DIRECTORY-message.cmake

@@ -1,2 +1,3 @@
+set(CMAKE_INSTALL_MESSAGE "ALWAYS")
 set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/prefix")
 set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/prefix")
 install(DIRECTORY dir/ DESTINATION dir)
 install(DIRECTORY dir/ DESTINATION dir)

+ 1 - 0
Tests/RunCMake/install/RunCMakeTest.cmake

@@ -1,5 +1,6 @@
 include(RunCMake)
 include(RunCMake)
 run_cmake(DIRECTORY-message)
 run_cmake(DIRECTORY-message)
+run_cmake(DIRECTORY-message-lazy)
 run_cmake(SkipInstallRulesWarning)
 run_cmake(SkipInstallRulesWarning)
 run_cmake(SkipInstallRulesNoWarning1)
 run_cmake(SkipInstallRulesNoWarning1)
 run_cmake(SkipInstallRulesNoWarning2)
 run_cmake(SkipInstallRulesNoWarning2)