Explorar o código

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 %!s(int64=11) %!d(string=hai) anos
pai
achega
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.
 
 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
 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
   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
 ^^^^^^^^^^^^^^^^^^
 

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

+ 1 - 1
Source/cmInstallFilesCommand.cxx

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

+ 28 - 0
Source/cmInstallGenerator.cxx

@@ -11,6 +11,7 @@
 ============================================================================*/
 #include "cmInstallGenerator.h"
 
+#include "cmMakefile.h"
 #include "cmSystemTools.h"
 
 //----------------------------------------------------------------------------
@@ -98,6 +99,13 @@ void cmInstallGenerator
     {
     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)
     {
     os << " PERMISSIONS" << permissions_file;
@@ -182,3 +190,23 @@ std::string cmInstallGenerator::GetInstallDestination() const
   result += this->Destination;
   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"
 
 class cmLocalGenerator;
+class cmMakefile;
 
 /** \class cmInstallGenerator
  * \brief Support class for generating install scripts.
@@ -27,6 +28,9 @@ public:
   enum MessageLevel
   {
     MessageDefault,
+    MessageAlways,
+    MessageLazy,
+    MessageNever
   };
 
   cmInstallGenerator(const char* destination,
@@ -56,6 +60,9 @@ public:
   /** Test if this generator installs something for a given configuration.  */
   bool InstallsForConfig(const std::string& config);
 
+  /** Select message level from CMAKE_INSTALL_MESSAGE.  */
+  static MessageLevel SelectMessageLevel(cmMakefile* mf);
+
 protected:
   virtual void GenerateScript(std::ostream& os);
 

+ 1 - 1
Source/cmInstallProgramsCommand.cxx

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

+ 1 - 1
Source/cmLocalGenerator.cxx

@@ -3004,7 +3004,7 @@ public:
   cmInstallTargetGeneratorLocal(cmTarget& t, const char* dest, bool implib):
     cmInstallTargetGenerator(
       t, dest, implib, "", std::vector<std::string>(), "Unspecified",
-      MessageDefault,
+      cmInstallGenerator::SelectMessageLevel(t.GetMakefile()),
       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")
 install(DIRECTORY dir/ DESTINATION dir)

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

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