diff options
48 files changed, 586 insertions, 224 deletions
diff --git a/Help/command/file.rst b/Help/command/file.rst index 869350a..58e3a26 100644 --- a/Help/command/file.rst +++ b/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). diff --git a/Help/command/install.rst b/Help/command/install.rst index 47108f0..4c52abf 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -1,8 +1,15 @@ install ------- +.. only:: html + + .. contents:: + Specify rules to run at install time. +Introduction +^^^^^^^^^^^^ + This command generates installation rules for a project. Rules specified by calls to this command within a source directory are 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 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 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 to a full path. ------------------------------------------------------------------------------- +Installing Directories +^^^^^^^^^^^^^^^^^^^^^^ :: install(DIRECTORY dirs... DESTINATION <dir> [FILE_PERMISSIONS permissions...] [DIRECTORY_PERMISSIONS permissions...] - [USE_SOURCE_PERMISSIONS] [OPTIONAL] + [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT <component>] [FILES_MATCHING] [[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 ``PROGRAMS`` form of the command. +The ``MESSAGE_NEVER`` option disables file installation status output. + Installation of directories may be controlled with fine granularity using the ``PATTERN`` or ``REGEX`` options. These "match" options specify a 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 ``CVS`` directories will be excluded. ------------------------------------------------------------------------------- +Custom Installation Logic +^^^^^^^^^^^^^^^^^^^^^^^^^ :: @@ -266,7 +283,8 @@ example, the code will print a message during installation. ------------------------------------------------------------------------------- +Installing Exports +^^^^^^^^^^^^^^^^^^ :: diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index df434c5..0e4c4a0 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/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 diff --git a/Help/release/dev/install-messages.rst b/Help/release/dev/install-messages.rst new file mode 100644 index 0000000..e023ef7 --- /dev/null +++ b/Help/release/dev/install-messages.rst @@ -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. diff --git a/Help/variable/CMAKE_INSTALL_MESSAGE.rst b/Help/variable/CMAKE_INSTALL_MESSAGE.rst new file mode 100644 index 0000000..304df26 --- /dev/null +++ b/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``. diff --git a/Modules/FindJPEG.cmake b/Modules/FindJPEG.cmake index 90e4485..86bb6e5 100644 --- a/Modules/FindJPEG.cmake +++ b/Modules/FindJPEG.cmake @@ -33,7 +33,7 @@ find_path(JPEG_INCLUDE_DIR jpeglib.h) -set(JPEG_NAMES ${JPEG_NAMES} jpeg) +set(JPEG_NAMES ${JPEG_NAMES} jpeg libjpeg) find_library(JPEG_LIBRARY NAMES ${JPEG_NAMES} ) # handle the QUIETLY and REQUIRED arguments and set JPEG_FOUND to TRUE if diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index 918e2ec..31ab48d 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -73,7 +73,7 @@ macro(SWIG_MODULE_INITIALIZE name language) set(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}") set(SWIG_MODULE_${name}_REAL_NAME "${name}") - if (CMAKE_SWIG_FLAGS MATCHES "-noproxy") + if (";${CMAKE_SWIG_FLAGS};" MATCHES ";-noproxy;") set (SWIG_MODULE_${name}_NOPROXY TRUE) endif () if("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "UNKNOWN") diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index f44b85e..b074230 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 0) -set(CMake_VERSION_PATCH 20140625) +set(CMake_VERSION_PATCH 20140630) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 91f92c5..9336bed 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -637,8 +637,8 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( if ( globalGenerator->GetPreinstallTargetName() ) { globalGenerator->FindMakeProgram(this->MakefileMap); - const char* cmakeMakeProgram - = this->MakefileMap->GetDefinition("CMAKE_MAKE_PROGRAM"); + std::string cmakeMakeProgram + = this->MakefileMap->GetSafeDefinition("CMAKE_MAKE_PROGRAM"); std::vector<std::string> buildCommand; globalGenerator->GenerateBuildCommand(buildCommand, cmakeMakeProgram, installProjectName, installDirectory, diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 655f3ba..61c6eb3 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -1613,7 +1613,8 @@ bool cmFileCopier::InstallDirectory(const char* source, MatchProperties const& match_properties) { // 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. if(!cmSystemTools::MakeDirectory(destination)) @@ -1704,6 +1705,9 @@ struct cmFileInstaller: public cmFileCopier cmFileCopier(command, "INSTALL"), InstallType(cmInstallType_FILES), Optional(false), + MessageAlways(false), + MessageLazy(false), + MessageNever(false), DestDirLength(0) { // Installation does not use source permissions by default. @@ -1725,6 +1729,9 @@ struct cmFileInstaller: public cmFileCopier protected: cmInstallType InstallType; bool Optional; + bool MessageAlways; + bool MessageLazy; + bool MessageNever; int DestDirLength; std::string Rename; @@ -1740,9 +1747,12 @@ protected: virtual void ReportCopy(const char* toFile, Type type, bool copy) { - std::string message = (copy? "Installing: " : "Up-to-date: "); - message += toFile; - this->Makefile->DisplayStatus(message.c_str(), -1); + if(!this->MessageNever && (copy || !this->MessageLazy)) + { + std::string message = (copy? "Installing: " : "Up-to-date: "); + message += toFile; + this->Makefile->DisplayStatus(message.c_str(), -1); + } if(type != TypeDir) { // Add the file to the manifest. @@ -1828,6 +1838,16 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args) 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; } @@ -1879,6 +1899,42 @@ bool cmFileInstaller::CheckKeyword(std::string const& arg) 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") { if(this->CurrentMatchRule) @@ -2057,23 +2113,26 @@ bool cmFileInstaller::HandleInstallDestination() 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."; + 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); 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; } diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 0041122..ec500d9 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -25,9 +25,12 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator(cmTarget& target, const cmInstallCommandArguments& args, bool impLib, bool forceOpt = false) { + cmInstallGenerator::MessageLevel message = + cmInstallGenerator::SelectMessageLevel(target.GetMakefile()); return new cmInstallTargetGenerator(target, args.GetDestination().c_str(), impLib, args.GetPermissions().c_str(), args.GetConfigurations(), args.GetComponent().c_str(), + message, args.GetOptional() || forceOpt); } @@ -36,10 +39,13 @@ static cmInstallFilesGenerator* CreateInstallFilesGenerator( const std::vector<std::string>& absFiles, const cmInstallCommandArguments& args, bool programs) { + cmInstallGenerator::MessageLevel message = + cmInstallGenerator::SelectMessageLevel(mf); return new cmInstallFilesGenerator(mf, absFiles, args.GetDestination().c_str(), programs, args.GetPermissions().c_str(), args.GetConfigurations(), args.GetComponent().c_str(), + message, args.GetRename().c_str(), args.GetOptional()); } @@ -911,6 +917,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) Doing doing = DoingDirs; bool in_match_mode = false; bool optional = false; + bool message_never = false; std::vector<std::string> dirs; const char* destination = 0; std::string permissions_file; @@ -949,6 +956,21 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) optional = true; 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") { // Switch to a new pattern match rule. @@ -1208,6 +1230,9 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) return false; } + cmInstallGenerator::MessageLevel message = + cmInstallGenerator::SelectMessageLevel(this->Makefile, message_never); + // Create the directory install generator. this->Makefile->AddInstallGenerator( new cmInstallDirectoryGenerator(dirs, destination, @@ -1215,6 +1240,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) permissions_dir.c_str(), configurations, component.c_str(), + message, literal_args.c_str(), 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. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator( exportSet, ica.GetDestination().c_str(), 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); this->Makefile->AddInstallGenerator(exportGenerator); diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx index ddf7d08..8c13bab 100644 --- a/Source/cmInstallDirectoryGenerator.cxx +++ b/Source/cmInstallDirectoryGenerator.cxx @@ -21,9 +21,11 @@ cmInstallDirectoryGenerator const char* dir_permissions, std::vector<std::string> const& configurations, const char* component, + MessageLevel message, const char* literal_args, bool optional): - cmInstallGenerator(dest, configurations, component), Directories(dirs), + cmInstallGenerator(dest, configurations, component, message), + Directories(dirs), FilePermissions(file_permissions), DirPermissions(dir_permissions), LiteralArguments(literal_args), Optional(optional) { diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h index d76ef3c..165ab91 100644 --- a/Source/cmInstallDirectoryGenerator.h +++ b/Source/cmInstallDirectoryGenerator.h @@ -26,6 +26,7 @@ public: const char* dir_permissions, std::vector<std::string> const& configurations, const char* component, + MessageLevel message, const char* literal_args, bool optional = false); virtual ~cmInstallDirectoryGenerator(); diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 9a17052..ddfd6c5 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -32,10 +32,11 @@ cmInstallExportGenerator::cmInstallExportGenerator( const char* file_permissions, std::vector<std::string> const& configurations, const char* component, + MessageLevel message, const char* filename, const char* name_space, bool exportOld, cmMakefile* mf) - :cmInstallGenerator(destination, configurations, component) + :cmInstallGenerator(destination, configurations, component, message) ,ExportSet(exportSet) ,FilePermissions(file_permissions) ,FileName(filename) diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index 37b5593..eb8c28b 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -30,6 +30,7 @@ public: const char* dest, const char* file_permissions, const std::vector<std::string>& configurations, const char* component, + MessageLevel message, const char* filename, const char* name_space, bool exportOld, cmMakefile* mf); ~cmInstallExportGenerator(); diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx index 7eabbef..f106e1a 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -132,11 +132,13 @@ void cmInstallFilesCommand::CreateInstallGenerator() const std::string no_component = this->Makefile->GetSafeDefinition( "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); std::vector<std::string> no_configurations; + cmInstallGenerator::MessageLevel message = + cmInstallGenerator::SelectMessageLevel(this->Makefile); this->Makefile->AddInstallGenerator( new cmInstallFilesGenerator(this->Makefile, this->Files, destination.c_str(), false, no_permissions, no_configurations, - no_component.c_str(), no_rename)); + no_component.c_str(), message, no_rename)); } diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index b2be82e..91b102a 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -23,9 +23,10 @@ cmInstallFilesGenerator const char* file_permissions, std::vector<std::string> const& configurations, const char* component, + MessageLevel message, const char* rename, bool optional): - cmInstallGenerator(dest, configurations, component), + cmInstallGenerator(dest, configurations, component, message), Makefile(mf), Files(files), Programs(programs), FilePermissions(file_permissions), diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h index 23bf935..0dbd712 100644 --- a/Source/cmInstallFilesGenerator.h +++ b/Source/cmInstallFilesGenerator.h @@ -28,6 +28,7 @@ public: const char* file_permissions, std::vector<std::string> const& configurations, const char* component, + MessageLevel message, const char* rename, bool optional = false); virtual ~cmInstallFilesGenerator(); diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 9370e48..b261cbf 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -11,16 +11,19 @@ ============================================================================*/ #include "cmInstallGenerator.h" +#include "cmMakefile.h" #include "cmSystemTools.h" //---------------------------------------------------------------------------- cmInstallGenerator ::cmInstallGenerator(const char* destination, std::vector<std::string> const& configurations, - const char* component): + const char* component, + MessageLevel message): cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations), Destination(destination? destination:""), - Component(component? component:"") + Component(component? component:""), + Message(message) { } @@ -96,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; @@ -180,3 +190,27 @@ std::string cmInstallGenerator::GetInstallDestination() const result += this->Destination; 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; +} diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h index c72e9e9..38aac91 100644 --- a/Source/cmInstallGenerator.h +++ b/Source/cmInstallGenerator.h @@ -16,6 +16,7 @@ #include "cmScriptGenerator.h" class cmLocalGenerator; +class cmMakefile; /** \class cmInstallGenerator * \brief Support class for generating install scripts. @@ -24,9 +25,18 @@ class cmLocalGenerator; class cmInstallGenerator: public cmScriptGenerator { public: + enum MessageLevel + { + MessageDefault, + MessageAlways, + MessageLazy, + MessageNever + }; + cmInstallGenerator(const char* destination, std::vector<std::string> const& configurations, - const char* component); + const char* component, + MessageLevel message); virtual ~cmInstallGenerator(); void AddInstallRule( @@ -50,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 or 'never'. */ + static MessageLevel SelectMessageLevel(cmMakefile* mf, bool never = false); + protected: virtual void GenerateScript(std::ostream& os); @@ -58,6 +71,7 @@ protected: // Information shared by most generator types. std::string Destination; std::string Component; + MessageLevel Message; }; #endif diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx index 597f7ee..0405769 100644 --- a/Source/cmInstallProgramsCommand.cxx +++ b/Source/cmInstallProgramsCommand.cxx @@ -93,11 +93,13 @@ void cmInstallProgramsCommand::FinalPass() std::string no_component = this->Makefile->GetSafeDefinition( "CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"); std::vector<std::string> no_configurations; + cmInstallGenerator::MessageLevel message = + cmInstallGenerator::SelectMessageLevel(this->Makefile); this->Makefile->AddInstallGenerator( new cmInstallFilesGenerator(this->Makefile, this->Files, destination.c_str(), true, no_permissions, no_configurations, - no_component.c_str(), no_rename)); + no_component.c_str(), message, no_rename)); } /** diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index 1ecf021..933aa07 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -15,7 +15,7 @@ cmInstallScriptGenerator ::cmInstallScriptGenerator(const char* script, bool code, const char* component) : - cmInstallGenerator(0, std::vector<std::string>(), component), + cmInstallGenerator(0, std::vector<std::string>(), component, MessageDefault), Script(script), Code(code) { } diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index ec2b518..85df91d 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -24,8 +24,10 @@ cmInstallTargetGenerator ::cmInstallTargetGenerator(cmTarget& t, const char* dest, bool implib, const char* file_permissions, std::vector<std::string> const& configurations, - const char* component, bool optional): - cmInstallGenerator(dest, configurations, component), Target(&t), + const char* component, + MessageLevel message, + bool optional): + cmInstallGenerator(dest, configurations, component, message), Target(&t), ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional) { this->ActionsPerConfig = true; diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index 0f21da7..7e5cc71 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -24,11 +24,11 @@ class cmInstallTargetGenerator: public cmInstallGenerator public: cmInstallTargetGenerator( cmTarget& t, const char* dest, bool implib, - const char* file_permissions = "", - std::vector<std::string> const& configurations - = std::vector<std::string>(), - const char* component = "Unspecified", - bool optional = false + const char* file_permissions, + std::vector<std::string> const& configurations, + const char* component, + MessageLevel message, + bool optional ); virtual ~cmInstallTargetGenerator(); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index abfc3ed..5380d06 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2998,6 +2998,17 @@ cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local, } //---------------------------------------------------------------------------- +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 cmLocalGenerator ::GenerateTargetInstallRules( @@ -3042,7 +3053,8 @@ cmLocalGenerator case cmTarget::MODULE_LIBRARY: { // 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); } break; @@ -3052,16 +3064,19 @@ cmLocalGenerator // Special code to handle DLL. Install the import library // to the normal destination and the DLL to the runtime // destination. - cmInstallTargetGenerator g1(l->second, destination.c_str(), true); + cmInstallTargetGeneratorLocal + g1(l->second, destination.c_str(), true); g1.Generate(os, config, configurationTypes); // We also skip over the leading slash given by the user. destination = l->second.GetRuntimeInstallPath().substr(1); cmSystemTools::ConvertToUnixSlashes(destination); - cmInstallTargetGenerator g2(l->second, destination.c_str(), false); + cmInstallTargetGeneratorLocal + g2(l->second, destination.c_str(), false); g2.Generate(os, config, configurationTypes); #else // 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); #endif } diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index e29e698..0ab722e 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -2129,6 +2129,11 @@ void cmSystemTools::FindCMakeResources(const char* argv0) cmSystemToolsCMakeCommand = exe_dir; cmSystemToolsCMakeCommand += "/cmake"; cmSystemToolsCMakeCommand += cmSystemTools::GetExecutableExtension(); +#ifndef CMAKE_BUILD_WITH_CMAKE + // The bootstrap cmake does not provide the other tools, + // so use the directory where they are about to be built. + exe_dir = CMAKE_BOOTSTRAP_BINARY_DIR "/bin"; +#endif cmSystemToolsCTestCommand = exe_dir; cmSystemToolsCTestCommand += "/ctest"; cmSystemToolsCTestCommand += cmSystemTools::GetExecutableExtension(); @@ -2181,7 +2186,7 @@ void cmSystemTools::FindCMakeResources(const char* argv0) } #else // Bootstrap build knows its source. - cmSystemToolsCMakeRoot = CMAKE_ROOT_DIR; + cmSystemToolsCMakeRoot = CMAKE_BOOTSTRAP_SOURCE_DIR; #endif } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 71d03df..aa0ed56 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -126,11 +126,13 @@ public: typedef std::map<TargetConfigPair, OptionalLinkInterface> LinkInterfaceMapType; LinkInterfaceMapType LinkInterfaceMap; + LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap; bool PolicyWarnedCMP0022; typedef std::map<TargetConfigPair, cmTarget::LinkInterface> ImportLinkInterfaceMapType; ImportLinkInterfaceMapType ImportLinkInterfaceMap; + ImportLinkInterfaceMapType ImportLinkInterfaceUsageRequirementsOnlyMap; typedef std::map<std::string, cmTarget::OutputInfo> OutputInfoMapType; OutputInfoMapType OutputInfoMap; @@ -142,8 +144,15 @@ public: CompileInfoMapType CompileInfoMap; // Cache link implementation computation from each configuration. + struct OptionalLinkImplementation: public cmTarget::LinkImplementation + { + OptionalLinkImplementation(): + LibrariesDone(false), LanguagesDone(false) {} + bool LibrariesDone; + bool LanguagesDone; + }; typedef std::map<TargetConfigPair, - cmTarget::LinkImplementation> LinkImplMapType; + OptionalLinkImplementation> LinkImplMapType; LinkImplMapType LinkImplMap; typedef std::map<std::string, cmTarget::LinkClosure> LinkClosureMapType; @@ -172,25 +181,25 @@ public: std::vector<TargetPropertyEntry*> SourceEntries; std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries; - mutable std::map<std::string, std::vector<TargetPropertyEntry*> > - CachedLinkInterfaceIncludeDirectoriesEntries; - mutable std::map<std::string, std::vector<TargetPropertyEntry*> > - CachedLinkInterfaceCompileOptionsEntries; - mutable std::map<std::string, std::vector<TargetPropertyEntry*> > - CachedLinkInterfaceCompileDefinitionsEntries; - mutable std::map<std::string, std::vector<TargetPropertyEntry*> > - CachedLinkInterfaceSourcesEntries; - mutable std::map<std::string, std::vector<TargetPropertyEntry*> > - CachedLinkInterfaceCompileFeaturesEntries; - mutable std::map<std::string, std::vector<cmTarget const*> > - CachedLinkImplementationClosure; - - mutable std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone; - mutable std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone; - mutable std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone; - mutable std::map<std::string, bool> CacheLinkInterfaceSourcesDone; - mutable std::map<std::string, bool> CacheLinkInterfaceCompileFeaturesDone; - mutable std::map<std::string, bool> CacheLinkImplementationClosureDone; + std::map<std::string, std::vector<TargetPropertyEntry*> > + CachedLinkInterfaceIncludeDirectoriesEntries; + std::map<std::string, std::vector<TargetPropertyEntry*> > + CachedLinkInterfaceCompileOptionsEntries; + std::map<std::string, std::vector<TargetPropertyEntry*> > + CachedLinkInterfaceCompileDefinitionsEntries; + std::map<std::string, std::vector<TargetPropertyEntry*> > + CachedLinkInterfaceSourcesEntries; + std::map<std::string, std::vector<TargetPropertyEntry*> > + CachedLinkInterfaceCompileFeaturesEntries; + std::map<std::string, std::vector<cmTarget const*> > + CachedLinkImplementationClosure; + + std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone; + std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone; + std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone; + std::map<std::string, bool> CacheLinkInterfaceSourcesDone; + std::map<std::string, bool> CacheLinkInterfaceCompileFeaturesDone; + std::map<std::string, bool> CacheLinkImplementationClosureDone; }; //---------------------------------------------------------------------------- @@ -510,7 +519,9 @@ void cmTarget::ClearLinkMaps() this->LinkImplementationLanguageIsContextDependent = true; this->Internal->LinkImplMap.clear(); this->Internal->LinkInterfaceMap.clear(); + this->Internal->LinkInterfaceUsageRequirementsOnlyMap.clear(); this->Internal->ImportLinkInterfaceMap.clear(); + this->Internal->ImportLinkInterfaceUsageRequirementsOnlyMap.clear(); this->Internal->LinkClosureMap.clear(); for (cmTargetLinkInformationMap::const_iterator it = this->LinkInformation.begin(); @@ -3688,10 +3699,15 @@ void cmTarget::ExpandLinkItems(std::string const& prop, std::string const& value, std::string const& config, cmTarget const* headTarget, + bool usage_requirements_only, std::vector<cmLinkItem>& items) const { cmGeneratorExpression ge; cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0); + if(usage_requirements_only) + { + dagChecker.SetTransitivePropertiesOnly(); + } std::vector<std::string> libs; cmSystemTools::ExpandListArgument(ge.Parse(value)->Evaluate( this->Makefile, @@ -6032,7 +6048,7 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface( // Imported targets have their own link interface. if(this->IsImported()) { - return this->GetImportLinkInterface(config, head); + return this->GetImportLinkInterface(config, head, false); } // Link interfaces are not supported for executables that do not @@ -6053,7 +6069,8 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface( // Compute the link interface for this configuration. cmTargetInternals::OptionalLinkInterface iface; iface.ExplicitLibraries = - this->ComputeLinkInterfaceLibraries(config, iface, head, iface.Exists); + this->ComputeLinkInterfaceLibraries(config, iface, head, false, + iface.Exists); if (iface.Exists) { this->Internal->ComputeLinkInterface(this, config, iface, @@ -6076,12 +6093,13 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface( //---------------------------------------------------------------------------- cmTarget::LinkInterface const* cmTarget::GetLinkInterfaceLibraries(const std::string& config, - cmTarget const* head) const + cmTarget const* head, + bool usage_requirements_only) const { // Imported targets have their own link interface. if(this->IsImported()) { - return this->GetImportLinkInterface(config, head); + return this->GetImportLinkInterface(config, head, usage_requirements_only); } // Link interfaces are not supported for executables that do not @@ -6094,21 +6112,24 @@ cmTarget::GetLinkInterfaceLibraries(const std::string& config, // Lookup any existing link interface for this configuration. TargetConfigPair key(head, cmSystemTools::UpperCase(config)); + cmTargetInternals::LinkInterfaceMapType& lim = + (usage_requirements_only ? + this->Internal->LinkInterfaceUsageRequirementsOnlyMap : + this->Internal->LinkInterfaceMap); - cmTargetInternals::LinkInterfaceMapType::iterator - i = this->Internal->LinkInterfaceMap.find(key); - if(i == this->Internal->LinkInterfaceMap.end()) + cmTargetInternals::LinkInterfaceMapType::iterator i = lim.find(key); + if(i == lim.end()) { // Compute the link interface for this configuration. cmTargetInternals::OptionalLinkInterface iface; - iface.ExplicitLibraries = this->ComputeLinkInterfaceLibraries(config, - iface, - head, - iface.Exists); + iface.ExplicitLibraries = + this->ComputeLinkInterfaceLibraries(config, iface, head, + usage_requirements_only, + iface.Exists); // Store the information for this configuration. cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface); - i = this->Internal->LinkInterfaceMap.insert(entry).first; + i = lim.insert(entry).first; } return i->second.Exists ? &i->second : 0; @@ -6117,7 +6138,8 @@ cmTarget::GetLinkInterfaceLibraries(const std::string& config, //---------------------------------------------------------------------------- cmTarget::LinkInterface const* cmTarget::GetImportLinkInterface(const std::string& config, - cmTarget const* headTarget) const + cmTarget const* headTarget, + bool usage_requirements_only) const { cmTarget::ImportInfo const* info = this->GetImportInfo(config); if(!info) @@ -6126,16 +6148,20 @@ cmTarget::GetImportLinkInterface(const std::string& config, } TargetConfigPair key(headTarget, cmSystemTools::UpperCase(config)); + cmTargetInternals::ImportLinkInterfaceMapType& lim = + (usage_requirements_only ? + this->Internal->ImportLinkInterfaceUsageRequirementsOnlyMap : + this->Internal->ImportLinkInterfaceMap); - cmTargetInternals::ImportLinkInterfaceMapType::iterator i = - this->Internal->ImportLinkInterfaceMap.find(key); - if(i == this->Internal->ImportLinkInterfaceMap.end()) + cmTargetInternals::ImportLinkInterfaceMapType::iterator i = lim.find(key); + if(i == lim.end()) { LinkInterface iface; iface.Multiplicity = info->Multiplicity; cmSystemTools::ExpandListArgument(info->Languages, iface.Languages); this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config, - headTarget, iface.Libraries); + headTarget, usage_requirements_only, + iface.Libraries); { std::vector<std::string> deps; cmSystemTools::ExpandListArgument(info->SharedDeps, deps); @@ -6144,7 +6170,7 @@ cmTarget::GetImportLinkInterface(const std::string& config, cmTargetInternals::ImportLinkInterfaceMapType::value_type entry(key, iface); - i = this->Internal->ImportLinkInterfaceMap.insert(entry).first; + i = lim.insert(entry).first; } return &i->second; } @@ -6160,7 +6186,7 @@ void processILibs(const std::string& config, { tgts.push_back(item.Target); if(cmTarget::LinkInterface const* iface = - item.Target->GetLinkInterfaceLibraries(config, headTarget)) + item.Target->GetLinkInterfaceLibraries(config, headTarget, false)) { for(std::vector<cmLinkItem>::const_iterator it = iface->Libraries.begin(); @@ -6200,15 +6226,18 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config, cmTarget const* headTarget, std::vector<cmTarget const*> &tgts) const { - cmTarget::LinkInterface const* iface - = this->GetLinkInterfaceLibraries(config, headTarget); - if (!iface) - { - return; - } - if(this->GetType() != STATIC_LIBRARY - || this->GetPolicyStatusCMP0022() == cmPolicies::WARN - || this->GetPolicyStatusCMP0022() == cmPolicies::OLD) + // The $<LINK_ONLY> expression may be in a link interface to specify private + // link dependencies that are otherwise excluded from usage requirements. + // Currently $<LINK_ONLY> is internal to CMake and only ever added by + // target_link_libraries for PRIVATE dependencies of STATIC libraries in + // INTERFACE_LINK_LIBRARIES which is used under CMP0022 NEW behavior. + bool usage_requirements_only = + this->GetType() == STATIC_LIBRARY && + this->GetPolicyStatusCMP0022() != cmPolicies::WARN && + this->GetPolicyStatusCMP0022() != cmPolicies::OLD; + if(cmTarget::LinkInterface const* iface = + this->GetLinkInterfaceLibraries(config, headTarget, + usage_requirements_only)) { for(std::vector<cmLinkItem>::const_iterator it = iface->Libraries.begin(); it != iface->Libraries.end(); ++it) @@ -6218,37 +6247,6 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config, tgts.push_back(it->Target); } } - return; - } - - const char* linkIfaceProp = "INTERFACE_LINK_LIBRARIES"; - const char* interfaceLibs = this->GetProperty(linkIfaceProp); - - if (!interfaceLibs) - { - return; - } - - // The interface libraries have been explicitly set. - cmGeneratorExpression ge; - cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), - linkIfaceProp, 0, 0); - dagChecker.SetTransitivePropertiesOnly(); - std::vector<std::string> libs; - cmSystemTools::ExpandListArgument(ge.Parse(interfaceLibs)->Evaluate( - this->Makefile, - config, - false, - headTarget, - this, &dagChecker), libs); - - for(std::vector<std::string>::const_iterator it = libs.begin(); - it != libs.end(); ++it) - { - if (cmTarget const* tgt = this->FindTargetToLink(*it)) - { - tgts.push_back(tgt); - } } } @@ -6256,6 +6254,7 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config, const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, LinkInterface& iface, cmTarget const* headTarget, + bool usage_requirements_only, bool &exists) const { // Construct the property name suffix for this configuration. @@ -6341,7 +6340,8 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, { // The interface libraries have been explicitly set. this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, - headTarget, iface.Libraries); + headTarget, usage_requirements_only, + iface.Libraries); } else if (this->PolicyStatusCMP0022 == cmPolicies::WARN || this->PolicyStatusCMP0022 == cmPolicies::OLD) @@ -6355,7 +6355,7 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, this->GetLinkImplementationLibrariesInternal(config, headTarget); iface.Libraries = impl->Libraries; if(this->PolicyStatusCMP0022 == cmPolicies::WARN && - !this->Internal->PolicyWarnedCMP0022) + !this->Internal->PolicyWarnedCMP0022 && !usage_requirements_only) { // Compare the link implementation fallback link interface to the // preferred new link interface property and warn if different. @@ -6364,7 +6364,8 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config, if(const char* newExplicitLibraries = this->GetProperty(newProp)) { this->ExpandLinkItems(newProp, newExplicitLibraries, config, - headTarget, ifaceLibs); + headTarget, usage_requirements_only, + ifaceLibs); } if (ifaceLibs != impl->Libraries) { @@ -6525,28 +6526,21 @@ cmTarget::GetLinkImplementation(const std::string& config) const return 0; } - // Lookup any existing link implementation for this configuration. + // Populate the link implementation for this configuration. TargetConfigPair key(this, cmSystemTools::UpperCase(config)); - - cmTargetInternals::LinkImplMapType::iterator - i = this->Internal->LinkImplMap.find(key); - if(i == this->Internal->LinkImplMap.end()) + cmTargetInternals::OptionalLinkImplementation& + impl = this->Internal->LinkImplMap[key]; + if(!impl.LibrariesDone) { - // Compute the link implementation for this configuration. - LinkImplementation impl; + impl.LibrariesDone = true; this->ComputeLinkImplementation(config, impl, this); - this->ComputeLinkImplementationLanguages(config, impl, this); - - // Store the information for this configuration. - cmTargetInternals::LinkImplMapType::value_type entry(key, impl); - i = this->Internal->LinkImplMap.insert(entry).first; } - else if (i->second.Languages.empty()) + if(!impl.LanguagesDone) { - this->ComputeLinkImplementationLanguages(config, i->second, this); + impl.LanguagesDone = true; + this->ComputeLinkImplementationLanguages(config, impl, this); } - - return &i->second; + return &impl; } //---------------------------------------------------------------------------- @@ -6567,23 +6561,16 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config, return 0; } - // Lookup any existing link implementation for this configuration. + // Populate the link implementation libraries for this configuration. TargetConfigPair key(head, cmSystemTools::UpperCase(config)); - - cmTargetInternals::LinkImplMapType::iterator - i = this->Internal->LinkImplMap.find(key); - if(i == this->Internal->LinkImplMap.end()) + cmTargetInternals::OptionalLinkImplementation& + impl = this->Internal->LinkImplMap[key]; + if(!impl.LibrariesDone) { - // Compute the link implementation for this configuration. - LinkImplementation impl; - this->ComputeLinkImplementation(config, impl, head); - - // Store the information for this configuration. - cmTargetInternals::LinkImplMapType::value_type entry(key, impl); - i = this->Internal->LinkImplMap.insert(entry).first; + impl.LibrariesDone = true; + this->ComputeLinkImplementation(config, impl, this); } - - return &i->second; + return &impl; } //---------------------------------------------------------------------------- @@ -6592,15 +6579,18 @@ void cmTarget::ComputeLinkImplementation(const std::string& config, cmTarget const* head) const { // Collect libraries directly linked in this configuration. - std::vector<std::string> llibs; - if(const char *prop = this->GetProperty("LINK_LIBRARIES")) + for (std::vector<cmValueWithOrigin>::const_iterator + le = this->Internal->LinkImplementationPropertyEntries.begin(), + end = this->Internal->LinkImplementationPropertyEntries.end(); + le != end; ++le) { - cmGeneratorExpression ge; - const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop); - + std::vector<std::string> llibs; cmGeneratorExpressionDAGChecker dagChecker( this->GetName(), "LINK_LIBRARIES", 0, 0); + cmGeneratorExpression ge(&le->Backtrace); + cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge = + ge.Parse(le->Value); cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile, config, false, @@ -6608,66 +6598,65 @@ void cmTarget::ComputeLinkImplementation(const std::string& config, &dagChecker), llibs); - std::set<std::string> const& seenProps = cge->GetSeenTargetProperties(); - for (std::set<std::string>::const_iterator it = seenProps.begin(); - it != seenProps.end(); ++it) + for(std::vector<std::string>::const_iterator li = llibs.begin(); + li != llibs.end(); ++li) { - if (!this->GetProperty(*it)) - { - this->LinkImplicitNullProperties.insert(*it); - } - } - cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards); - } - - for(std::vector<std::string>::const_iterator li = llibs.begin(); - li != llibs.end(); ++li) - { - // Skip entries that resolve to the target itself or are empty. - std::string name = this->CheckCMP0004(*li); - if(name == this->GetName() || name.empty()) - { - if(name == this->GetName()) + // Skip entries that resolve to the target itself or are empty. + std::string name = this->CheckCMP0004(*li); + if(name == this->GetName() || name.empty()) { - bool noMessage = false; - cmake::MessageType messageType = cmake::FATAL_ERROR; - cmOStringStream e; - switch(this->GetPolicyStatusCMP0038()) + if(name == this->GetName()) { - case cmPolicies::WARN: + bool noMessage = false; + cmake::MessageType messageType = cmake::FATAL_ERROR; + cmOStringStream e; + switch(this->GetPolicyStatusCMP0038()) { - e << (this->Makefile->GetPolicies() - ->GetPolicyWarning(cmPolicies::CMP0038)) << "\n"; - messageType = cmake::AUTHOR_WARNING; + case cmPolicies::WARN: + { + e << (this->Makefile->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0038)) << "\n"; + messageType = cmake::AUTHOR_WARNING; + } + break; + case cmPolicies::OLD: + noMessage = true; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + // Issue the fatal message. + break; } - break; - case cmPolicies::OLD: - noMessage = true; - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::NEW: - // Issue the fatal message. - break; - } - if(!noMessage) - { - e << "Target \"" << this->GetName() << "\" links to itself."; - this->Makefile->GetCMakeInstance()->IssueMessage(messageType, - e.str(), - this->GetBacktrace()); - if (messageType == cmake::FATAL_ERROR) + if(!noMessage) { - return; + e << "Target \"" << this->GetName() << "\" links to itself."; + this->Makefile->GetCMakeInstance()->IssueMessage( + messageType, e.str(), this->GetBacktrace()); + if (messageType == cmake::FATAL_ERROR) + { + return; + } } } + continue; } - continue; + + // The entry is meant for this configuration. + impl.Libraries.push_back( + cmLinkItem(name, this->FindTargetToLink(name))); } - // The entry is meant for this configuration. - impl.Libraries.push_back( - cmLinkItem(name, this->FindTargetToLink(name))); + std::set<std::string> const& seenProps = cge->GetSeenTargetProperties(); + for (std::set<std::string>::const_iterator it = seenProps.begin(); + it != seenProps.end(); ++it) + { + if (!this->GetProperty(*it)) + { + this->LinkImplicitNullProperties.insert(*it); + } + } + cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards); } cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 3f534f2..9d1f966 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -280,7 +280,8 @@ public: LinkInterface const* GetLinkInterface(const std::string& config, cmTarget const* headTarget) const; LinkInterface const* GetLinkInterfaceLibraries(const std::string& config, - cmTarget const* headTarget) const; + cmTarget const* headTarget, + bool usage_requirements_only) const; void GetTransitivePropertyTargets(const std::string& config, cmTarget const* headTarget, std::vector<cmTarget const*> &libs) const; @@ -756,12 +757,13 @@ private: const std::string& config) const; LinkInterface const* - GetImportLinkInterface(const std::string& config, - cmTarget const* head) const; + GetImportLinkInterface(const std::string& config, cmTarget const* head, + bool usage_requirements_only) const; const char* ComputeLinkInterfaceLibraries(const std::string& config, LinkInterface& iface, cmTarget const* head, + bool usage_requirements_only, bool &exists) const; LinkImplementation const* @@ -777,6 +779,7 @@ private: void ExpandLinkItems(std::string const& prop, std::string const& value, std::string const& config, cmTarget const* headTarget, + bool usage_requirements_only, std::vector<cmLinkItem>& items) const; void LookupLinkItems(std::vector<std::string> const& names, std::vector<cmLinkItem>& items) const; diff --git a/Tests/CTestTestTimeout/CMakeLists.txt b/Tests/CTestTestTimeout/CMakeLists.txt index 2e3bd6a..c6cbc47 100644 --- a/Tests/CTestTestTimeout/CMakeLists.txt +++ b/Tests/CTestTestTimeout/CMakeLists.txt @@ -3,11 +3,8 @@ project(CTestTestTimeout) include(CTest) if(NOT TIMEOUT) - if(CYGWIN) - set(TIMEOUT 4) # Cygwin CMake sometimes takes > 1 second to load! - else() - set(TIMEOUT 1) - endif() + # Give the process time to load and start running. + set(TIMEOUT 4) endif() add_definitions(-DTIMEOUT=${TIMEOUT}) diff --git a/Tests/RunCMake/file/INSTALL-DIRECTORY-stdout.txt b/Tests/RunCMake/file/INSTALL-DIRECTORY-stdout.txt new file mode 100644 index 0000000..561a6b1 --- /dev/null +++ b/Tests/RunCMake/file/INSTALL-DIRECTORY-stdout.txt @@ -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 diff --git a/Tests/RunCMake/file/INSTALL-DIRECTORY.cmake b/Tests/RunCMake/file/INSTALL-DIRECTORY.cmake new file mode 100644 index 0000000..0bc1d18 --- /dev/null +++ b/Tests/RunCMake/file/INSTALL-DIRECTORY.cmake @@ -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") diff --git a/Tests/RunCMake/file/INSTALL-MESSAGE-bad-result.txt b/Tests/RunCMake/file/INSTALL-MESSAGE-bad-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/INSTALL-MESSAGE-bad-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/INSTALL-MESSAGE-bad-stderr.txt b/Tests/RunCMake/file/INSTALL-MESSAGE-bad-stderr.txt new file mode 100644 index 0000000..557b817 --- /dev/null +++ b/Tests/RunCMake/file/INSTALL-MESSAGE-bad-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/file/INSTALL-MESSAGE-bad.cmake b/Tests/RunCMake/file/INSTALL-MESSAGE-bad.cmake new file mode 100644 index 0000000..f878c69 --- /dev/null +++ b/Tests/RunCMake/file/INSTALL-MESSAGE-bad.cmake @@ -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) diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake index 7b05229..bf14263 100644 --- a/Tests/RunCMake/file/RunCMakeTest.cmake +++ b/Tests/RunCMake/file/RunCMakeTest.cmake @@ -1,3 +1,5 @@ include(RunCMake) +run_cmake(INSTALL-DIRECTORY) +run_cmake(INSTALL-MESSAGE-bad) run_cmake(FileOpenFailRead) diff --git a/Tests/RunCMake/file/dir/empty.txt b/Tests/RunCMake/file/dir/empty.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/file/dir/empty.txt diff --git a/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER-check.cmake b/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER-check.cmake new file mode 100644 index 0000000..2c716e1 --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER-check.cmake @@ -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() diff --git a/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER.cmake b/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER.cmake new file mode 100644 index 0000000..eefb837 --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-MESSAGE_NEVER.cmake @@ -0,0 +1,3 @@ +set(CMAKE_INSTALL_MESSAGE "ALWAYS") +set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/prefix") +install(DIRECTORY dir/ DESTINATION dir MESSAGE_NEVER) diff --git a/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-result.txt b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-stderr.txt b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-stderr.txt new file mode 100644 index 0000000..166ba6f --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER.cmake b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER.cmake new file mode 100644 index 0000000..de844f7 --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-PATTERN-MESSAGE_NEVER.cmake @@ -0,0 +1 @@ +install(DIRECTORY src DESTINATION src PATTERN *.txt MESSAGE_NEVER) diff --git a/Tests/RunCMake/install/DIRECTORY-message-check.cmake b/Tests/RunCMake/install/DIRECTORY-message-check.cmake new file mode 100644 index 0000000..857681f --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-message-check.cmake @@ -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() diff --git a/Tests/RunCMake/install/DIRECTORY-message-lazy-check.cmake b/Tests/RunCMake/install/DIRECTORY-message-lazy-check.cmake new file mode 100644 index 0000000..c7e6018 --- /dev/null +++ b/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() diff --git a/Tests/RunCMake/install/DIRECTORY-message-lazy.cmake b/Tests/RunCMake/install/DIRECTORY-message-lazy.cmake new file mode 100644 index 0000000..ed43567 --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/install/DIRECTORY-message.cmake b/Tests/RunCMake/install/DIRECTORY-message.cmake new file mode 100644 index 0000000..913ed15 --- /dev/null +++ b/Tests/RunCMake/install/DIRECTORY-message.cmake @@ -0,0 +1,3 @@ +set(CMAKE_INSTALL_MESSAGE "ALWAYS") +set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/prefix") +install(DIRECTORY dir/ DESTINATION dir) diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake index c8dc379..53b91f3 100644 --- a/Tests/RunCMake/install/RunCMakeTest.cmake +++ b/Tests/RunCMake/install/RunCMakeTest.cmake @@ -1,4 +1,8 @@ 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(SkipInstallRulesNoWarning1) run_cmake(SkipInstallRulesNoWarning2) diff --git a/Tests/RunCMake/install/dir/empty.txt b/Tests/RunCMake/install/dir/empty.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/install/dir/empty.txt @@ -1477,9 +1477,11 @@ fi # When bootstrapping on MinGW with MSYS we must convert the source # directory to a windows path. if ${cmake_system_mingw}; then - cmake_root_dir=`cd "${cmake_source_dir}"; pwd -W` + CMAKE_BOOTSTRAP_SOURCE_DIR=`cd "${cmake_source_dir}"; pwd -W` + CMAKE_BOOTSTRAP_BINARY_DIR=`cd "${cmake_binary_dir}"; pwd -W` else - cmake_root_dir="${cmake_source_dir}" + CMAKE_BOOTSTRAP_SOURCE_DIR="${cmake_source_dir}" + CMAKE_BOOTSTRAP_BINARY_DIR="${cmake_binary_dir}" fi # Write CMake version @@ -1487,7 +1489,8 @@ cmake_report cmVersionConfig.h${_tmp} "#define CMake_VERSION_MAJOR ${cmake_versi cmake_report cmVersionConfig.h${_tmp} "#define CMake_VERSION_MINOR ${cmake_version_minor}" cmake_report cmVersionConfig.h${_tmp} "#define CMake_VERSION_PATCH ${cmake_version_patch}" cmake_report cmVersionConfig.h${_tmp} "#define CMake_VERSION \"${cmake_version}\"" -cmake_report cmConfigure.h${_tmp} "#define CMAKE_ROOT_DIR \"${cmake_root_dir}\"" +cmake_report cmConfigure.h${_tmp} "#define CMAKE_BOOTSTRAP_SOURCE_DIR \"${CMAKE_BOOTSTRAP_SOURCE_DIR}\"" +cmake_report cmConfigure.h${_tmp} "#define CMAKE_BOOTSTRAP_BINARY_DIR \"${CMAKE_BOOTSTRAP_BINARY_DIR}\"" cmake_report cmConfigure.h${_tmp} "#define CMAKE_DATA_DIR \"/bootstrap-not-insalled\"" cmake_report cmConfigure.h${_tmp} "#define CMAKE_BOOTSTRAP" |