Merge topic 'install-messages'

d19b64d6 install(DIRECTORY): Add MESSAGE_NEVER option to avoid output (#13761)
c9568de5 install: Add CMAKE_INSTALL_MESSAGE variable (#13761)
ec7cf7ea install: Thread message level setting through internal API
abebcd23 file(INSTALL): Add undocumented options to control output verbosity
464567a5 file(INSTALL): Report existing DIRECTORY as Up-to-date
f701b0b7 file(INSTALL): Do not pre-create DESTINATION for DIRECTORY
f0a01962 cmInstallTargetGenerator: Drop default constructor arguments
67815894 Help: Add install() command document section headers
This commit is contained in:
Brad King 2014-06-27 09:42:42 -04:00 committed by CMake Topic Stage
commit 3138da6e67
39 changed files with 407 additions and 42 deletions

View File

@ -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).

View File

@ -1,8 +1,15 @@
install install
------- -------
.. only:: html
.. contents::
Specify rules to run at install time. Specify rules to run at install time.
Introduction
^^^^^^^^^^^^
This command generates installation rules for a project. Rules This command generates installation rules for a project. Rules
specified by calls to this command within a source directory are specified by calls to this command within a source directory are
executed in order during installation. The order across directories executed in order during installation. The order across directories
@ -52,7 +59,12 @@ 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
^^^^^^^^^^^^^^^^^^
:: ::
@ -147,7 +159,8 @@ file itself, call ``install(EXPORT)``, documented below.
Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property
set to ``TRUE`` has undefined behavior. set to ``TRUE`` has undefined behavior.
------------------------------------------------------------------------------ Installing Files
^^^^^^^^^^^^^^^^
:: ::
@ -175,14 +188,15 @@ The list of ``files...`` given to ``FILES`` or ``PROGRAMS`` may use
However, if any item begins in a generator expression it must evaluate However, if any item begins in a generator expression it must evaluate
to a full path. to a full path.
------------------------------------------------------------------------------ Installing Directories
^^^^^^^^^^^^^^^^^^^^^^
:: ::
install(DIRECTORY dirs... DESTINATION <dir> install(DIRECTORY dirs... DESTINATION <dir>
[FILE_PERMISSIONS permissions...] [FILE_PERMISSIONS permissions...]
[DIRECTORY_PERMISSIONS permissions...] [DIRECTORY_PERMISSIONS permissions...]
[USE_SOURCE_PERMISSIONS] [OPTIONAL] [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER]
[CONFIGURATIONS [Debug|Release|...]] [CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>] [FILES_MATCHING] [COMPONENT <component>] [FILES_MATCHING]
[[PATTERN <pattern> | REGEX <regex>] [[PATTERN <pattern> | REGEX <regex>]
@ -205,6 +219,8 @@ permissions specified in the ``FILES`` form of the command, and the
directories will be given the default permissions specified in the directories will be given the default permissions specified in the
``PROGRAMS`` form of the command. ``PROGRAMS`` form of the command.
The ``MESSAGE_NEVER`` option disables file installation status output.
Installation of directories may be controlled with fine granularity Installation of directories may be controlled with fine granularity
using the ``PATTERN`` or ``REGEX`` options. These "match" options specify a using the ``PATTERN`` or ``REGEX`` options. These "match" options specify a
globbing pattern or regular expression to match directories or files globbing pattern or regular expression to match directories or files
@ -247,7 +263,8 @@ will install the ``icons`` directory to ``share/myproj/icons`` and the
file permissions, the scripts will be given specific permissions, and any file permissions, the scripts will be given specific permissions, and any
``CVS`` directories will be excluded. ``CVS`` directories will be excluded.
------------------------------------------------------------------------------ Custom Installation Logic
^^^^^^^^^^^^^^^^^^^^^^^^^
:: ::
@ -266,7 +283,8 @@ example, the code
will print a message during installation. will print a message during installation.
------------------------------------------------------------------------------ Installing Exports
^^^^^^^^^^^^^^^^^^
:: ::

View File

@ -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

View File

@ -0,0 +1,8 @@
install-messages
----------------
* The :command:`install` command learned a ``MESSAGE_NEVER`` option
to avoid output during installation.
* The :variable:`CMAKE_INSTALL_MESSAGE` variable was introduced to
optionally reduce output installation.

View File

@ -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``.

View File

@ -1613,7 +1613,8 @@ bool cmFileCopier::InstallDirectory(const char* source,
MatchProperties const& match_properties) MatchProperties const& match_properties)
{ {
// Inform the user about this directory installation. // Inform the user about this directory installation.
this->ReportCopy(destination, TypeDir, true); this->ReportCopy(destination, TypeDir,
!cmSystemTools::FileIsDirectory(destination));
// Make sure the destination directory exists. // Make sure the destination directory exists.
if(!cmSystemTools::MakeDirectory(destination)) if(!cmSystemTools::MakeDirectory(destination))
@ -1704,6 +1705,9 @@ struct cmFileInstaller: public cmFileCopier
cmFileCopier(command, "INSTALL"), cmFileCopier(command, "INSTALL"),
InstallType(cmInstallType_FILES), InstallType(cmInstallType_FILES),
Optional(false), Optional(false),
MessageAlways(false),
MessageLazy(false),
MessageNever(false),
DestDirLength(0) DestDirLength(0)
{ {
// Installation does not use source permissions by default. // Installation does not use source permissions by default.
@ -1725,6 +1729,9 @@ struct cmFileInstaller: public cmFileCopier
protected: protected:
cmInstallType InstallType; cmInstallType InstallType;
bool Optional; bool Optional;
bool MessageAlways;
bool MessageLazy;
bool MessageNever;
int DestDirLength; int DestDirLength;
std::string Rename; std::string Rename;
@ -1740,9 +1747,12 @@ protected:
virtual void ReportCopy(const char* toFile, Type type, bool copy) virtual void ReportCopy(const char* toFile, Type type, bool copy)
{ {
std::string message = (copy? "Installing: " : "Up-to-date: "); if(!this->MessageNever && (copy || !this->MessageLazy))
message += toFile; {
this->Makefile->DisplayStatus(message.c_str(), -1); std::string message = (copy? "Installing: " : "Up-to-date: ");
message += toFile;
this->Makefile->DisplayStatus(message.c_str(), -1);
}
if(type != TypeDir) if(type != TypeDir)
{ {
// Add the file to the manifest. // Add the file to the manifest.
@ -1828,6 +1838,16 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args)
return false; return false;
} }
if(((this->MessageAlways?1:0) +
(this->MessageLazy?1:0) +
(this->MessageNever?1:0)) > 1)
{
this->FileCommand->SetError("INSTALL options MESSAGE_ALWAYS, "
"MESSAGE_LAZY, and MESSAGE_NEVER "
"are mutually exclusive.");
return false;
}
return true; return true;
} }
@ -1879,6 +1899,42 @@ bool cmFileInstaller::CheckKeyword(std::string const& arg)
this->Optional = true; this->Optional = true;
} }
} }
else if(arg == "MESSAGE_ALWAYS")
{
if(this->CurrentMatchRule)
{
this->NotAfterMatch(arg);
}
else
{
this->Doing = DoingNone;
this->MessageAlways = true;
}
}
else if(arg == "MESSAGE_LAZY")
{
if(this->CurrentMatchRule)
{
this->NotAfterMatch(arg);
}
else
{
this->Doing = DoingNone;
this->MessageLazy = true;
}
}
else if(arg == "MESSAGE_NEVER")
{
if(this->CurrentMatchRule)
{
this->NotAfterMatch(arg);
}
else
{
this->Doing = DoingNone;
this->MessageNever = true;
}
}
else if(arg == "PERMISSIONS") else if(arg == "PERMISSIONS")
{ {
if(this->CurrentMatchRule) if(this->CurrentMatchRule)
@ -2057,23 +2113,26 @@ bool cmFileInstaller::HandleInstallDestination()
this->DestDirLength = int(sdestdir.size()); this->DestDirLength = int(sdestdir.size());
} }
if ( !cmSystemTools::FileExists(destination.c_str()) ) if(this->InstallType != cmInstallType_DIRECTORY)
{ {
if ( !cmSystemTools::MakeDirectory(destination.c_str()) ) if ( !cmSystemTools::FileExists(destination.c_str()) )
{ {
std::string errstring = "cannot create directory: " + destination + if ( !cmSystemTools::MakeDirectory(destination.c_str()) )
{
std::string errstring = "cannot create directory: " + destination +
". Maybe need administrative privileges."; ". Maybe need administrative privileges.";
this->FileCommand->SetError(errstring);
return false;
}
}
if ( !cmSystemTools::FileIsDirectory(destination.c_str()) )
{
std::string errstring = "INSTALL destination: " + destination +
" is not a directory.";
this->FileCommand->SetError(errstring); this->FileCommand->SetError(errstring);
return false; return false;
} }
} }
if ( !cmSystemTools::FileIsDirectory(destination.c_str()) )
{
std::string errstring = "INSTALL destination: " + destination +
" is not a directory.";
this->FileCommand->SetError(errstring);
return false;
}
return true; return true;
} }

View File

@ -25,9 +25,12 @@
static cmInstallTargetGenerator* CreateInstallTargetGenerator(cmTarget& target, 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::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(),
message,
args.GetOptional() || forceOpt); args.GetOptional() || forceOpt);
} }
@ -36,10 +39,13 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator(
const std::vector<std::string>& absFiles, const std::vector<std::string>& absFiles,
const cmInstallCommandArguments& args, bool programs) const cmInstallCommandArguments& args, bool programs)
{ {
cmInstallGenerator::MessageLevel message =
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(),
args.GetConfigurations(), args.GetComponent().c_str(), args.GetConfigurations(), args.GetComponent().c_str(),
message,
args.GetRename().c_str(), args.GetOptional()); args.GetRename().c_str(), args.GetOptional());
} }
@ -911,6 +917,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
Doing doing = DoingDirs; Doing doing = DoingDirs;
bool in_match_mode = false; bool in_match_mode = false;
bool optional = false; bool optional = false;
bool message_never = false;
std::vector<std::string> dirs; std::vector<std::string> dirs;
const char* destination = 0; const char* destination = 0;
std::string permissions_file; std::string permissions_file;
@ -949,6 +956,21 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
optional = true; optional = true;
doing = DoingNone; doing = DoingNone;
} }
else if(args[i] == "MESSAGE_NEVER")
{
if(in_match_mode)
{
cmOStringStream e;
e << args[0] << " does not allow \""
<< args[i] << "\" after PATTERN or REGEX.";
this->SetError(e.str());
return false;
}
// Mark the rule as quiet.
message_never = true;
doing = DoingNone;
}
else if(args[i] == "PATTERN") else if(args[i] == "PATTERN")
{ {
// Switch to a new pattern match rule. // Switch to a new pattern match rule.
@ -1208,6 +1230,9 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
return false; return false;
} }
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(this->Makefile, message_never);
// Create the directory install generator. // Create the directory install generator.
this->Makefile->AddInstallGenerator( this->Makefile->AddInstallGenerator(
new cmInstallDirectoryGenerator(dirs, destination, new cmInstallDirectoryGenerator(dirs, destination,
@ -1215,6 +1240,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args)
permissions_dir.c_str(), permissions_dir.c_str(),
configurations, configurations,
component.c_str(), component.c_str(),
message,
literal_args.c_str(), literal_args.c_str(),
optional)); optional));
@ -1333,13 +1359,16 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args)
} }
} }
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(this->Makefile);
// Create the export install generator. // Create the export install generator.
cmInstallExportGenerator* exportGenerator = cmInstallExportGenerator* exportGenerator =
new cmInstallExportGenerator( new cmInstallExportGenerator(
exportSet, exportSet,
ica.GetDestination().c_str(), ica.GetDestination().c_str(),
ica.GetPermissions().c_str(), ica.GetConfigurations(), ica.GetPermissions().c_str(), ica.GetConfigurations(),
ica.GetComponent().c_str(), fname.c_str(), ica.GetComponent().c_str(), message, fname.c_str(),
name_space.GetCString(), exportOld.IsEnabled(), this->Makefile); name_space.GetCString(), exportOld.IsEnabled(), this->Makefile);
this->Makefile->AddInstallGenerator(exportGenerator); this->Makefile->AddInstallGenerator(exportGenerator);

View File

@ -21,9 +21,11 @@ cmInstallDirectoryGenerator
const char* dir_permissions, const char* dir_permissions,
std::vector<std::string> const& configurations, std::vector<std::string> const& configurations,
const char* component, const char* component,
MessageLevel message,
const char* literal_args, const char* literal_args,
bool optional): bool optional):
cmInstallGenerator(dest, configurations, component), Directories(dirs), cmInstallGenerator(dest, configurations, component, message),
Directories(dirs),
FilePermissions(file_permissions), DirPermissions(dir_permissions), FilePermissions(file_permissions), DirPermissions(dir_permissions),
LiteralArguments(literal_args), Optional(optional) LiteralArguments(literal_args), Optional(optional)
{ {

View File

@ -26,6 +26,7 @@ public:
const char* dir_permissions, const char* dir_permissions,
std::vector<std::string> const& configurations, std::vector<std::string> const& configurations,
const char* component, const char* component,
MessageLevel message,
const char* literal_args, const char* literal_args,
bool optional = false); bool optional = false);
virtual ~cmInstallDirectoryGenerator(); virtual ~cmInstallDirectoryGenerator();

View File

@ -32,10 +32,11 @@ cmInstallExportGenerator::cmInstallExportGenerator(
const char* file_permissions, const char* file_permissions,
std::vector<std::string> const& configurations, std::vector<std::string> const& configurations,
const char* component, const char* component,
MessageLevel message,
const char* filename, const char* name_space, const char* filename, const char* name_space,
bool exportOld, bool exportOld,
cmMakefile* mf) cmMakefile* mf)
:cmInstallGenerator(destination, configurations, component) :cmInstallGenerator(destination, configurations, component, message)
,ExportSet(exportSet) ,ExportSet(exportSet)
,FilePermissions(file_permissions) ,FilePermissions(file_permissions)
,FileName(filename) ,FileName(filename)

View File

@ -30,6 +30,7 @@ public:
const char* dest, const char* file_permissions, const char* dest, const char* file_permissions,
const std::vector<std::string>& configurations, const std::vector<std::string>& configurations,
const char* component, const char* component,
MessageLevel message,
const char* filename, const char* name_space, const char* filename, const char* name_space,
bool exportOld, cmMakefile* mf); bool exportOld, cmMakefile* mf);
~cmInstallExportGenerator(); ~cmInstallExportGenerator();

View File

@ -132,11 +132,13 @@ void cmInstallFilesCommand::CreateInstallGenerator() const
std::string no_component = this->Makefile->GetSafeDefinition( std::string no_component = this->Makefile->GetSafeDefinition(
"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::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,
no_permissions, no_configurations, no_permissions, no_configurations,
no_component.c_str(), no_rename)); no_component.c_str(), message, no_rename));
} }

View File

@ -23,9 +23,10 @@ cmInstallFilesGenerator
const char* file_permissions, const char* file_permissions,
std::vector<std::string> const& configurations, std::vector<std::string> const& configurations,
const char* component, const char* component,
MessageLevel message,
const char* rename, const char* rename,
bool optional): bool optional):
cmInstallGenerator(dest, configurations, component), cmInstallGenerator(dest, configurations, component, message),
Makefile(mf), Makefile(mf),
Files(files), Programs(programs), Files(files), Programs(programs),
FilePermissions(file_permissions), FilePermissions(file_permissions),

View File

@ -28,6 +28,7 @@ public:
const char* file_permissions, const char* file_permissions,
std::vector<std::string> const& configurations, std::vector<std::string> const& configurations,
const char* component, const char* component,
MessageLevel message,
const char* rename, const char* rename,
bool optional = false); bool optional = false);
virtual ~cmInstallFilesGenerator(); virtual ~cmInstallFilesGenerator();

View File

@ -11,16 +11,19 @@
============================================================================*/ ============================================================================*/
#include "cmInstallGenerator.h" #include "cmInstallGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmInstallGenerator cmInstallGenerator
::cmInstallGenerator(const char* destination, ::cmInstallGenerator(const char* destination,
std::vector<std::string> const& configurations, std::vector<std::string> const& configurations,
const char* component): const char* component,
MessageLevel message):
cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations), cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations),
Destination(destination? destination:""), Destination(destination? destination:""),
Component(component? component:"") Component(component? component:""),
Message(message)
{ {
} }
@ -96,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;
@ -180,3 +190,27 @@ std::string cmInstallGenerator::GetInstallDestination() const
result += this->Destination; result += this->Destination;
return result; return result;
} }
//----------------------------------------------------------------------------
cmInstallGenerator::MessageLevel
cmInstallGenerator::SelectMessageLevel(cmMakefile* mf, bool never)
{
if(never)
{
return MessageNever;
}
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;
}

View File

@ -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.
@ -24,9 +25,18 @@ class cmLocalGenerator;
class cmInstallGenerator: public cmScriptGenerator class cmInstallGenerator: public cmScriptGenerator
{ {
public: public:
enum MessageLevel
{
MessageDefault,
MessageAlways,
MessageLazy,
MessageNever
};
cmInstallGenerator(const char* destination, cmInstallGenerator(const char* destination,
std::vector<std::string> const& configurations, std::vector<std::string> const& configurations,
const char* component); const char* component,
MessageLevel message);
virtual ~cmInstallGenerator(); virtual ~cmInstallGenerator();
void AddInstallRule( void AddInstallRule(
@ -50,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 or 'never'. */
static MessageLevel SelectMessageLevel(cmMakefile* mf, bool never = false);
protected: protected:
virtual void GenerateScript(std::ostream& os); virtual void GenerateScript(std::ostream& os);
@ -58,6 +71,7 @@ protected:
// Information shared by most generator types. // Information shared by most generator types.
std::string Destination; std::string Destination;
std::string Component; std::string Component;
MessageLevel Message;
}; };
#endif #endif

View File

@ -93,11 +93,13 @@ void cmInstallProgramsCommand::FinalPass()
std::string no_component = this->Makefile->GetSafeDefinition( std::string no_component = this->Makefile->GetSafeDefinition(
"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::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,
no_permissions, no_configurations, no_permissions, no_configurations,
no_component.c_str(), no_rename)); no_component.c_str(), message, no_rename));
} }
/** /**

View File

@ -15,7 +15,7 @@
cmInstallScriptGenerator cmInstallScriptGenerator
::cmInstallScriptGenerator(const char* script, bool code, ::cmInstallScriptGenerator(const char* script, bool code,
const char* component) : const char* component) :
cmInstallGenerator(0, std::vector<std::string>(), component), cmInstallGenerator(0, std::vector<std::string>(), component, MessageDefault),
Script(script), Code(code) Script(script), Code(code)
{ {
} }

View File

@ -24,8 +24,10 @@ cmInstallTargetGenerator
::cmInstallTargetGenerator(cmTarget& t, const char* dest, bool implib, ::cmInstallTargetGenerator(cmTarget& t, const char* dest, bool implib,
const char* file_permissions, const char* file_permissions,
std::vector<std::string> const& configurations, std::vector<std::string> const& configurations,
const char* component, bool optional): const char* component,
cmInstallGenerator(dest, configurations, component), Target(&t), MessageLevel message,
bool optional):
cmInstallGenerator(dest, configurations, component, message), Target(&t),
ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional) ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional)
{ {
this->ActionsPerConfig = true; this->ActionsPerConfig = true;

View File

@ -24,11 +24,11 @@ class cmInstallTargetGenerator: public cmInstallGenerator
public: public:
cmInstallTargetGenerator( cmInstallTargetGenerator(
cmTarget& t, const char* dest, bool implib, cmTarget& t, const char* dest, bool implib,
const char* file_permissions = "", const char* file_permissions,
std::vector<std::string> const& configurations std::vector<std::string> const& configurations,
= std::vector<std::string>(), const char* component,
const char* component = "Unspecified", MessageLevel message,
bool optional = false bool optional
); );
virtual ~cmInstallTargetGenerator(); virtual ~cmInstallTargetGenerator();

View File

@ -2997,6 +2997,17 @@ cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local,
return relative; return relative;
} }
//----------------------------------------------------------------------------
class cmInstallTargetGeneratorLocal: public cmInstallTargetGenerator
{
public:
cmInstallTargetGeneratorLocal(cmTarget& t, const char* dest, bool implib):
cmInstallTargetGenerator(
t, dest, implib, "", std::vector<std::string>(), "Unspecified",
cmInstallGenerator::SelectMessageLevel(t.GetMakefile()),
false) {}
};
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void void
cmLocalGenerator cmLocalGenerator
@ -3042,7 +3053,8 @@ cmLocalGenerator
case cmTarget::MODULE_LIBRARY: case cmTarget::MODULE_LIBRARY:
{ {
// Use a target install generator. // Use a target install generator.
cmInstallTargetGenerator g(l->second, destination.c_str(), false); cmInstallTargetGeneratorLocal
g(l->second, destination.c_str(), false);
g.Generate(os, config, configurationTypes); g.Generate(os, config, configurationTypes);
} }
break; break;
@ -3052,16 +3064,19 @@ cmLocalGenerator
// Special code to handle DLL. Install the import library // Special code to handle DLL. Install the import library
// to the normal destination and the DLL to the runtime // to the normal destination and the DLL to the runtime
// destination. // destination.
cmInstallTargetGenerator g1(l->second, destination.c_str(), true); cmInstallTargetGeneratorLocal
g1(l->second, destination.c_str(), true);
g1.Generate(os, config, configurationTypes); g1.Generate(os, config, configurationTypes);
// We also skip over the leading slash given by the user. // We also skip over the leading slash given by the user.
destination = l->second.GetRuntimeInstallPath().substr(1); destination = l->second.GetRuntimeInstallPath().substr(1);
cmSystemTools::ConvertToUnixSlashes(destination); cmSystemTools::ConvertToUnixSlashes(destination);
cmInstallTargetGenerator g2(l->second, destination.c_str(), false); cmInstallTargetGeneratorLocal
g2(l->second, destination.c_str(), false);
g2.Generate(os, config, configurationTypes); g2.Generate(os, config, configurationTypes);
#else #else
// Use a target install generator. // Use a target install generator.
cmInstallTargetGenerator g(l->second, destination.c_str(), false); cmInstallTargetGeneratorLocal
g(l->second, destination.c_str(), false);
g.Generate(os, config, configurationTypes); g.Generate(os, config, configurationTypes);
#endif #endif
} }

View File

@ -0,0 +1,8 @@
-- Before Installing
-- Installing: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir
-- Installing: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir/empty.txt
-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir
-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir/empty.txt
-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir
-- Up-to-date: .*/Tests/RunCMake/file/INSTALL-DIRECTORY-build/dir/empty.txt
-- After Installing

View File

@ -0,0 +1,10 @@
set(src ${CMAKE_CURRENT_SOURCE_DIR}/dir)
set(dst ${CMAKE_CURRENT_BINARY_DIR}/dir)
file(REMOVE RECURSE ${dst})
message(STATUS "Before Installing")
file(INSTALL FILES ${src}/ DESTINATION ${dst} TYPE DIRECTORY)
file(INSTALL FILES ${src}/ DESTINATION ${dst} TYPE DIRECTORY)
file(INSTALL FILES ${src}/ DESTINATION ${dst} TYPE DIRECTORY MESSAGE_NEVER)
file(INSTALL FILES ${src}/ DESTINATION ${dst} TYPE DIRECTORY MESSAGE_LAZY)
file(INSTALL FILES ${src}/ DESTINATION ${dst} TYPE DIRECTORY MESSAGE_ALWAYS)
message(STATUS "After Installing")

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,32 @@
CMake Error at INSTALL-MESSAGE-bad.cmake:1 \(file\):
file INSTALL options MESSAGE_ALWAYS, MESSAGE_LAZY, and MESSAGE_NEVER are
mutually exclusive.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at INSTALL-MESSAGE-bad.cmake:2 \(file\):
file INSTALL options MESSAGE_ALWAYS, MESSAGE_LAZY, and MESSAGE_NEVER are
mutually exclusive.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at INSTALL-MESSAGE-bad.cmake:3 \(file\):
file INSTALL options MESSAGE_ALWAYS, MESSAGE_LAZY, and MESSAGE_NEVER are
mutually exclusive.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at INSTALL-MESSAGE-bad.cmake:4 \(file\):
file option MESSAGE_ALWAYS may not appear after PATTERN or REGEX.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at INSTALL-MESSAGE-bad.cmake:5 \(file\):
file option MESSAGE_LAZY may not appear after PATTERN or REGEX.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at INSTALL-MESSAGE-bad.cmake:6 \(file\):
file option MESSAGE_NEVER may not appear after PATTERN or REGEX.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,6 @@
file(INSTALL DESTINATION dir MESSAGE_ALWAYS MESSAGE_LAZY)
file(INSTALL DESTINATION dir MESSAGE_ALWAYS MESSAGE_NEVER)
file(INSTALL DESTINATION dir MESSAGE_LAZY MESSAGE_NEVER)
file(INSTALL DESTINATION dir PATTERN *.txt MESSAGE_ALWAYS)
file(INSTALL DESTINATION dir PATTERN *.txt MESSAGE_LAZY)
file(INSTALL DESTINATION dir PATTERN *.txt MESSAGE_NEVER)

View File

@ -1,3 +1,5 @@
include(RunCMake) include(RunCMake)
run_cmake(INSTALL-DIRECTORY)
run_cmake(INSTALL-MESSAGE-bad)
run_cmake(FileOpenFailRead) run_cmake(FileOpenFailRead)

View File

View File

@ -0,0 +1,13 @@
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)
if(out MATCHES "-- Installing: [^\n]*prefix/dir")
string(REGEX REPLACE "\n" "\n " out " ${out}")
set(RunCMake_TEST_FAILED
"${RunCMake_TEST_FAILED}Installation output was not quiet:\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()

View File

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

View File

@ -0,0 +1,4 @@
CMake Error at DIRECTORY-PATTERN-MESSAGE_NEVER.cmake:[0-9]+ \(install\):
install DIRECTORY does not allow "MESSAGE_NEVER" after PATTERN or REGEX.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1 @@
install(DIRECTORY src DESTINATION src PATTERN *.txt MESSAGE_NEVER)

View File

@ -0,0 +1,28 @@
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)
set(expect "
-- Up-to-date: [^\n]*/prefix/dir\r?
-- Up-to-date: [^\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}Second install did not say 'Up-to-date' as expected:\n${out}")
endif()

View File

@ -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()

View File

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

View File

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

View File

@ -1,4 +1,8 @@
include(RunCMake) include(RunCMake)
run_cmake(DIRECTORY-MESSAGE_NEVER)
run_cmake(DIRECTORY-PATTERN-MESSAGE_NEVER)
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)

View File