diff options
64 files changed, 570 insertions, 170 deletions
diff --git a/.gitlab/ci/docker/fedora34/install_deps.sh b/.gitlab/ci/docker/fedora34/install_deps.sh index ece0666..dfd7db8 100755 --- a/.gitlab/ci/docker/fedora34/install_deps.sh +++ b/.gitlab/ci/docker/fedora34/install_deps.sh @@ -68,6 +68,7 @@ dnf install --setopt=install_weak_deps=False -y \ libuv-devel \ libxml2-devel \ libxslt-devel \ + mpich-devel \ openmpi-devel \ patch \ perl \ diff --git a/.gitlab/ci/env_fedora34_makefiles.cmake b/.gitlab/ci/env_fedora34_makefiles.cmake index 1d0efa7..aa84e23 100644 --- a/.gitlab/ci/env_fedora34_makefiles.cmake +++ b/.gitlab/ci/env_fedora34_makefiles.cmake @@ -1,2 +1,2 @@ set(ENV{MY_RUBY_HOME} "/usr/local/rvm/rubies/ruby-2.7.0") -set(ENV{PATH} "/usr/lib64/openmpi/bin:$ENV{PATH}") +set(ENV{PATH} "/usr/lib64/mpich/bin:$ENV{PATH}") diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml index 1bf4098..dcaa643 100644 --- a/.gitlab/os-linux.yml +++ b/.gitlab/os-linux.yml @@ -69,7 +69,7 @@ ### Fedora .fedora34: - image: "kitware/cmake:ci-fedora34-x86_64-2021-05-10" + image: "kitware/cmake:ci-fedora34-x86_64-2021-05-21" variables: GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes" diff --git a/Help/command/install.rst b/Help/command/install.rst index 993cf7f..2259176 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -619,7 +619,7 @@ Custom Installation Logic .. code-block:: cmake install([[SCRIPT <file>] [CODE <code>]] - [COMPONENT <component>] [EXCLUDE_FROM_ALL] [...]) + [COMPONENT <component>] [EXCLUDE_FROM_ALL] [ALL_COMPONENTS] [...]) The ``SCRIPT`` form will invoke the given CMake script files during installation. If the script file name is a relative path it will be @@ -634,6 +634,12 @@ example, the code will print a message during installation. +The option ``ALL_COMPONENTS`` + .. versionadded:: 3.21 + + Run the custom installation script code for every component of a + component-specific installation. + .. versionadded:: 3.14 ``<file>`` or ``<code>`` may use "generator expressions" with the syntax ``$<...>`` (in the case of ``<file>``, this refers to their use in the file diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst index 445ebeb..0e530bc 100644 --- a/Help/manual/cmake-file-api.7.rst +++ b/Help/manual/cmake-file-api.7.rst @@ -751,6 +751,11 @@ with members: Optional member that is present with boolean value ``true`` when :command:`install` is called with the ``EXCLUDE_FROM_ALL`` option. + ``isForAllComponents`` + Optional member that is present with boolean value ``true`` when + :command:`install(SCRIPT|CODE)` is called with the + ``ALL_COMPONENTS`` option. + ``isOptional`` Optional member that is present with boolean value ``true`` when :command:`install` is called with the ``OPTIONAL`` option. diff --git a/Help/release/dev/install-script-all-components.rst b/Help/release/dev/install-script-all-components.rst new file mode 100644 index 0000000..e421d3d --- /dev/null +++ b/Help/release/dev/install-script-all-components.rst @@ -0,0 +1,7 @@ +install-script-all-components +----------------------------- + +* The :command:`install(SCRIPT|CODE)` command + supports a new option ``ALL_COMPONENTS`` which allows + the corresponding code to run for every component of + a per component installation. diff --git a/Help/release/dev/message-color.rst b/Help/release/dev/message-color.rst new file mode 100644 index 0000000..4acf15e --- /dev/null +++ b/Help/release/dev/message-color.rst @@ -0,0 +1,4 @@ +message-color +------------- + +* Messages printed to a terminal now may be colored by message type. diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 026d1fc..9e25bee 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -2680,9 +2680,11 @@ function(_ep_add_download_command name) get_property(git_progress TARGET ${name} PROPERTY _EP_GIT_PROGRESS) get_property(git_config TARGET ${name} PROPERTY _EP_GIT_CONFIG) - # Make checkouts quiet when checking out a git hash (this avoids the - # very noisy detached head message) - list(PREPEND git_config advice.detachedHead=false) + # If git supports it, make checkouts quiet when checking out a git hash. + # This avoids the very noisy detached head message. + if(GIT_VERSION_STRING VERSION_GREATER_EQUAL 1.7.7) + list(PREPEND git_config advice.detachedHead=false) + endif() # For the download step, and the git clone operation, only the repository # should be recorded in a configured RepositoryInfo file. If the repo diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index c19c154..bd9e4c2 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -638,6 +638,7 @@ set(SRCS cmMathCommand.h cmMessageCommand.cxx cmMessageCommand.h + cmMessageMetadata.h cmOptionCommand.cxx cmOptionCommand.h cmOutputRequiredFilesCommand.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index f559e04..e92c2a0 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 20) -set(CMake_VERSION_PATCH 20210520) +set(CMake_VERSION_PATCH 20210525) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index a18cbb4..adfc8ef 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -19,6 +19,8 @@ #include "cmWorkingDirectory.h" #include "cmake.h" +struct cmMessageMetadata; + cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler() { this->BuildTwoConfig = false; @@ -125,7 +127,7 @@ public: : CM(cm) { cmSystemTools::SetMessageCallback( - [&s](const std::string& msg, const char* /*unused*/) { + [&s](const std::string& msg, const cmMessageMetadata& /* unused */) { s += msg; s += "\n"; }); diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index 85e256b..1ba45e5 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -19,6 +19,7 @@ #include "cmCursesStandardIncludes.h" #include "cmDocumentation.h" #include "cmDocumentationEntry.h" // IWYU pragma: keep +#include "cmMessageMetadata.h" #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -181,8 +182,8 @@ int main(int argc, char const* const* argv) return msg; }; cmSystemTools::SetMessageCallback( - [&](const std::string& message, const char* title) { - myform->AddError(cleanMessage(message), title); + [&](const std::string& message, const cmMessageMetadata& md) { + myform->AddError(cleanMessage(message), md.title); }); cmSystemTools::SetStderrCallback([&](const std::string& message) { myform->AddError(cleanMessage(message), ""); diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index a83622a..e6faef4 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -13,6 +13,7 @@ #include "cmExternalMakefileProjectGenerator.h" #include "cmGlobalGenerator.h" +#include "cmMessageMetadata.h" #include "cmState.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -37,8 +38,8 @@ QCMake::QCMake(QObject* p) cmSystemTools::SetRunCommandHideConsole(true); cmSystemTools::SetMessageCallback( - [this](std::string const& msg, const char* title) { - this->messageCallback(msg, title); + [this](std::string const& msg, const cmMessageMetadata& md) { + this->messageCallback(msg, md.title); }); cmSystemTools::SetStdoutCallback( [this](std::string const& msg) { this->stdoutCallback(msg); }); diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h index 5031c65..72ab045 100644 --- a/Source/cmCommandLineArgument.h +++ b/Source/cmCommandLineArgument.h @@ -17,10 +17,25 @@ struct cmCommandLineArgument OneOrMore }; + enum class RequiresSeparator + { + Yes, + No + }; + + enum class ParseMode + { + Valid, + Invalid, + SyntaxError, + ValueError + }; + std::string InvalidSyntaxMessage; std::string InvalidValueMessage; std::string Name; Values Type; + RequiresSeparator SeparatorNeeded; std::function<FunctionSignature> StoreCall; template <typename FunctionType> @@ -29,6 +44,19 @@ struct cmCommandLineArgument , InvalidValueMessage(cmStrCat("Invalid value used with ", n)) , Name(std::move(n)) , Type(t) + , SeparatorNeeded(RequiresSeparator::Yes) + , StoreCall(std::forward<FunctionType>(func)) + { + } + + template <typename FunctionType> + cmCommandLineArgument(std::string n, Values t, RequiresSeparator s, + FunctionType&& func) + : InvalidSyntaxMessage(cmStrCat(" is invalid syntax for ", n)) + , InvalidValueMessage(cmStrCat("Invalid value used with ", n)) + , Name(std::move(n)) + , Type(t) + , SeparatorNeeded(s) , StoreCall(std::forward<FunctionType>(func)) { } @@ -40,14 +68,39 @@ struct cmCommandLineArgument , InvalidValueMessage(std::move(failedMsg)) , Name(std::move(n)) , Type(t) + , SeparatorNeeded(RequiresSeparator::Yes) + , StoreCall(std::forward<FunctionType>(func)) + { + } + + template <typename FunctionType> + cmCommandLineArgument(std::string n, std::string failedMsg, Values t, + RequiresSeparator s, FunctionType&& func) + : InvalidSyntaxMessage(cmStrCat(" is invalid syntax for ", n)) + , InvalidValueMessage(std::move(failedMsg)) + , Name(std::move(n)) + , Type(t) + , SeparatorNeeded(s) , StoreCall(std::forward<FunctionType>(func)) { } bool matches(std::string const& input) const { - return (this->Type == Values::Zero) ? (input == this->Name) - : cmHasPrefix(input, this->Name); + bool matched = false; + if (this->Type == Values::Zero) { + matched = (input == this->Name); + } else if (this->SeparatorNeeded == RequiresSeparator::No) { + matched = cmHasPrefix(input, this->Name); + } else if (cmHasPrefix(input, this->Name)) { + if (input.size() == this->Name.size()) { + matched = true; + } else { + matched = + (input[this->Name.size()] == '=' || input[this->Name.size()] == ' '); + } + } + return matched; } template <typename T, typename... CallState> @@ -55,13 +108,6 @@ struct cmCommandLineArgument std::vector<std::string> const& allArgs, CallState&&... state) const { - enum class ParseMode - { - Valid, - Invalid, - SyntaxError, - ValueError - }; ParseMode parseState = ParseMode::Valid; if (this->Type == Values::Zero) { @@ -95,23 +141,10 @@ struct cmCommandLineArgument index = nextValueIndex; } } else { - // parse the string to get the value - auto possible_value = cm::string_view(input).substr(this->Name.size()); - if (possible_value.empty()) { - parseState = ParseMode::ValueError; - } else if (possible_value[0] == '=') { - possible_value.remove_prefix(1); - if (possible_value.empty()) { - parseState = ParseMode::ValueError; - } - } + auto value = this->extract_single_value(input, parseState); if (parseState == ParseMode::Valid) { - if (possible_value[0] == ' ') { - possible_value.remove_prefix(1); - } - - parseState = this->StoreCall(std::string(possible_value), - std::forward<CallState>(state)...) + parseState = + this->StoreCall(value, std::forward<CallState>(state)...) ? ParseMode::Valid : ParseMode::Invalid; } @@ -149,7 +182,13 @@ struct cmCommandLineArgument index = (nextValueIndex - 1); } } else { - parseState = ParseMode::SyntaxError; + auto value = this->extract_single_value(input, parseState); + if (parseState == ParseMode::Valid) { + parseState = + this->StoreCall(value, std::forward<CallState>(state)...) + ? ParseMode::Valid + : ParseMode::Invalid; + } } } @@ -161,4 +200,24 @@ struct cmCommandLineArgument } return (parseState == ParseMode::Valid); } + +private: + std::string extract_single_value(std::string const& input, + ParseMode& parseState) const + { + // parse the string to get the value + auto possible_value = cm::string_view(input).substr(this->Name.size()); + if (possible_value.empty()) { + parseState = ParseMode::ValueError; + } else if (possible_value[0] == '=') { + possible_value.remove_prefix(1); + if (possible_value.empty()) { + parseState = ParseMode::ValueError; + } + } + if (parseState == ParseMode::Valid && possible_value[0] == ' ') { + possible_value.remove_prefix(1); + } + return std::string(possible_value); + } }; diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 6b35842..945b547 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -1016,6 +1016,11 @@ Json::Value DirectoryObject::DumpInstaller(cmInstallGenerator* gen) if (gen->GetExcludeFromAll()) { installer["isExcludeFromAll"] = true; } + + if (gen->GetAllComponentsFlag()) { + installer["isForAllComponents"] = true; + } + this->AddBacktrace(installer, gen->GetBacktrace()); return installer; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index bbc0050..e2ec82a 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -52,6 +52,11 @@ class cmMessenger; +namespace { +const cmsys::RegularExpression FrameworkRegularExpression( + "^(.*/)?([^/]*)\\.framework/(.*)$"); +} + template <> cmProp cmTargetPropertyComputer::GetSources<cmGeneratorTarget>( cmGeneratorTarget const* tgt, cmMessenger* /* messenger */, @@ -2257,8 +2262,16 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const return cmSystemTools::GetFilenameName(info->Location); } // Use the soname given if any. + if (this->IsFrameworkOnApple()) { + cmsys::RegularExpressionMatch match; + if (FrameworkRegularExpression.find(info->SOName.c_str(), match)) { + auto frameworkName = match.match(2); + auto fileName = match.match(3); + return cmStrCat(frameworkName, ".framework/", fileName); + } + } if (cmHasLiteralPrefix(info->SOName, "@rpath/")) { - return info->SOName.substr(6); + return info->SOName.substr(cmStrLen("@rpath/")); } return info->SOName; } @@ -6459,9 +6472,19 @@ std::string cmGeneratorTarget::GetDirectory( const std::string& config, cmStateEnums::ArtifactType artifact) const { if (this->IsImported()) { + auto fullPath = this->Target->ImportedGetFullPath(config, artifact); + if (this->IsFrameworkOnApple()) { + cmsys::RegularExpressionMatch match; + if (FrameworkRegularExpression.find(fullPath.c_str(), match)) { + auto path = match.match(1); + if (!path.empty()) { + path.erase(path.length() - 1); + } + return path; + } + } // Return the directory from which the target is imported. - return cmSystemTools::GetFilenamePath( - this->Target->ImportedGetFullPath(config, artifact)); + return cmSystemTools::GetFilenamePath(fullPath); } if (OutputInfo const* info = this->GetOutputInfo(config)) { // Return the directory in which the target will be built. diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 565b951..6034434 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -216,22 +216,32 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, { // Write explicit outputs for (std::string const& output : build.Outputs) { - buildStr += cmStrCat(' ', this->EncodePath(output)); + buildStr = cmStrCat(buildStr, ' ', this->EncodePath(output)); if (this->ComputingUnknownDependencies) { this->CombinedBuildOutputs.insert(output); } } // Write implicit outputs - if (!build.ImplicitOuts.empty()) { - buildStr += " |"; + if (!build.ImplicitOuts.empty() || !build.WorkDirOuts.empty()) { + buildStr = cmStrCat(buildStr, " |"); for (std::string const& implicitOut : build.ImplicitOuts) { - buildStr += cmStrCat(' ', this->EncodePath(implicitOut)); + buildStr = cmStrCat(buildStr, ' ', this->EncodePath(implicitOut)); + if (this->ComputingUnknownDependencies) { + this->CombinedBuildOutputs.insert(implicitOut); + } + } + for (std::string const& workdirOut : build.WorkDirOuts) { + // Repeat some outputs, but expressed as absolute paths. + // This helps Ninja handle absolute paths found in a depfile. + // FIXME: Unfortunately this causes Ninja to stat the file twice. + // We could avoid this if Ninja Issue 1251 were fixed. + buildStr = cmStrCat(buildStr, " ${cmake_ninja_workdir}", + this->EncodePath(workdirOut)); } } - buildStr += ':'; // Write the rule. - buildStr += cmStrCat(' ', build.Rule); + buildStr = cmStrCat(buildStr, ": ", build.Rule); } std::string arguments; @@ -307,21 +317,46 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule() this->AddRule(rule); } +void cmGlobalNinjaGenerator::CCOutputs::Add( + std::vector<std::string> const& paths) +{ + for (std::string const& path : paths) { + std::string out = this->GG->ConvertToNinjaPath(path); + if (this->GG->SupportsImplicitOuts() && + !cmSystemTools::FileIsFullPath(out)) { + // This output is expressed as a relative path. Repeat it, + // but expressed as an absolute path for Ninja Issue 1251. + this->WorkDirOuts.emplace_back(out); + } + this->GG->SeenCustomCommandOutput(out); + this->ExplicitOuts.emplace_back(std::move(out)); + } +} + void cmGlobalNinjaGenerator::WriteCustomCommandBuild( - const std::string& command, const std::string& description, - const std::string& comment, const std::string& depfile, - const std::string& job_pool, bool uses_terminal, bool restat, - const cmNinjaDeps& outputs, const std::string& config, - const cmNinjaDeps& explicitDeps, const cmNinjaDeps& orderOnlyDeps) + std::string const& command, std::string const& description, + std::string const& comment, std::string const& depfile, + std::string const& job_pool, bool uses_terminal, bool restat, + std::string const& config, CCOutputs outputs, cmNinjaDeps explicitDeps, + cmNinjaDeps orderOnlyDeps) { this->AddCustomCommandRule(); + if (this->ComputingUnknownDependencies) { + // we need to track every dependency that comes in, since we are trying + // to find dependencies that are side effects of build commands + for (std::string const& dep : explicitDeps) { + this->CombinedCustomCommandExplicitDependencies.insert(dep); + } + } + { cmNinjaBuild build("CUSTOM_COMMAND"); build.Comment = comment; - build.Outputs = outputs; - build.ExplicitDeps = explicitDeps; - build.OrderOnlyDeps = orderOnlyDeps; + build.Outputs = std::move(outputs.ExplicitOuts); + build.WorkDirOuts = std::move(outputs.WorkDirOuts); + build.ExplicitDeps = std::move(explicitDeps); + build.OrderOnlyDeps = std::move(orderOnlyDeps); cmNinjaVars& vars = build.Variables; { @@ -351,14 +386,6 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild( this->WriteBuild(*this->GetImplFileStream(config), build); } } - - if (this->ComputingUnknownDependencies) { - // we need to track every dependency that comes in, since we are trying - // to find dependencies that are side effects of build commands - for (std::string const& dep : explicitDeps) { - this->CombinedCustomCommandExplicitDependencies.insert(dep); - } - } } void cmGlobalNinjaGenerator::AddMacOSXContentRule() @@ -1198,6 +1225,8 @@ void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os) const void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() { for (auto const& asd : this->AssumedSourceDependencies) { + CCOutputs outputs(this); + outputs.ExplicitOuts.emplace_back(asd.first); cmNinjaDeps orderOnlyDeps; std::copy(asd.second.begin(), asd.second.end(), std::back_inserter(orderOnlyDeps)); @@ -1206,8 +1235,8 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() "Assume dependencies for generated source file.", /*depfile*/ "", /*job_pool*/ "", /*uses_terminal*/ false, - /*restat*/ true, cmNinjaDeps(1, asd.first), "", cmNinjaDeps(), - orderOnlyDeps); + /*restat*/ true, std::string(), outputs, cmNinjaDeps(), + std::move(orderOnlyDeps)); } } diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 9f31708..7a3674e 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -110,13 +110,29 @@ public: void WriteBuild(std::ostream& os, cmNinjaBuild const& build, int cmdLineLimit = 0, bool* usedResponseFile = nullptr); - void WriteCustomCommandBuild( - const std::string& command, const std::string& description, - const std::string& comment, const std::string& depfile, - const std::string& pool, bool uses_terminal, bool restat, - const cmNinjaDeps& outputs, const std::string& config, - const cmNinjaDeps& explicitDeps = cmNinjaDeps(), - const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps()); + class CCOutputs + { + cmGlobalNinjaGenerator* GG; + + public: + CCOutputs(cmGlobalNinjaGenerator* gg) + : GG(gg) + { + } + void Add(std::vector<std::string> const& outputs); + cmNinjaDeps ExplicitOuts; + cmNinjaDeps WorkDirOuts; + }; + + void WriteCustomCommandBuild(std::string const& command, + std::string const& description, + std::string const& comment, + std::string const& depfile, + std::string const& pool, bool uses_terminal, + bool restat, std::string const& config, + CCOutputs outputs, + cmNinjaDeps explicitDeps = cmNinjaDeps(), + cmNinjaDeps orderOnlyDeps = cmNinjaDeps()); void WriteMacOSXContentBuild(std::string input, std::string output, const std::string& config); diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index d5d6d93..e973764 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -161,6 +161,7 @@ bool HandleScriptMode(std::vector<std::string> const& args, bool doing_script = false; bool doing_code = false; bool exclude_from_all = false; + bool all_components = false; // Scan the args once for COMPONENT. Only allow one. // @@ -172,6 +173,8 @@ bool HandleScriptMode(std::vector<std::string> const& args, } if (args[i] == "EXCLUDE_FROM_ALL") { exclude_from_all = true; + } else if (args[i] == "ALL_COMPONENTS") { + all_components = true; } } @@ -182,6 +185,11 @@ bool HandleScriptMode(std::vector<std::string> const& args, return false; } + if (all_components && componentCount == 1) { + status.SetError("ALL_COMPONENTS and COMPONENT are mutually exclusive"); + return false; + } + // Scan the args again, this time adding install generators each time we // encounter a SCRIPT or CODE arg: // @@ -208,14 +216,14 @@ bool HandleScriptMode(std::vector<std::string> const& args, } helper.Makefile->AddInstallGenerator( cm::make_unique<cmInstallScriptGenerator>( - script, false, component, exclude_from_all, + script, false, component, exclude_from_all, all_components, helper.Makefile->GetBacktrace())); } else if (doing_code) { doing_code = false; std::string const& code = arg; helper.Makefile->AddInstallGenerator( cm::make_unique<cmInstallScriptGenerator>( - code, true, component, exclude_from_all, + code, true, component, exclude_from_all, all_components, helper.Makefile->GetBacktrace())); } } diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx index 4eb5f69..86362e4 100644 --- a/Source/cmInstallDirectoryGenerator.cxx +++ b/Source/cmInstallDirectoryGenerator.cxx @@ -18,7 +18,7 @@ cmInstallDirectoryGenerator::cmInstallDirectoryGenerator( MessageLevel message, bool exclude_from_all, std::string literal_args, bool optional, cmListFileBacktrace backtrace) : cmInstallGenerator(dest, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , LocalGenerator(nullptr) , Directories(dirs) , FilePermissions(std::move(file_permissions)) diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index fdc3f8c..ccefd92 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -26,7 +26,7 @@ cmInstallExportGenerator::cmInstallExportGenerator( std::string filename, std::string name_space, bool exportOld, bool android, cmListFileBacktrace backtrace) : cmInstallGenerator(destination, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , ExportSet(exportSet) , FilePermissions(std::move(file_permissions)) , FileName(std::move(filename)) diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index 556c938..04aaa29 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -17,7 +17,7 @@ cmInstallFilesGenerator::cmInstallFilesGenerator( MessageLevel message, bool exclude_from_all, std::string rename, bool optional, cmListFileBacktrace backtrace) : cmInstallGenerator(dest, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , LocalGenerator(nullptr) , Files(files) , FilePermissions(std::move(file_permissions)) diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 98e3766..cf5f45e 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -11,12 +11,13 @@ cmInstallGenerator::cmInstallGenerator( std::string destination, std::vector<std::string> const& configurations, std::string component, MessageLevel message, bool exclude_from_all, - cmListFileBacktrace backtrace) + bool all_components, cmListFileBacktrace backtrace) : cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations) , Destination(std::move(destination)) , Component(std::move(component)) , Message(message) , ExcludeFromAll(exclude_from_all) + , AllComponents(all_components) , Backtrace(std::move(backtrace)) { } @@ -160,15 +161,20 @@ void cmInstallGenerator::GenerateScript(std::ostream& os) Indent indent; // Begin this block of installation. - std::string component_test = - this->CreateComponentTest(this->Component, this->ExcludeFromAll); - os << indent << "if(" << component_test << ")\n"; + if (!this->AllComponents) { + std::string component_test = + this->CreateComponentTest(this->Component, this->ExcludeFromAll); + os << indent << "if(" << component_test << ")\n"; + } // Generate the script possibly with per-configuration code. - this->GenerateScriptConfigs(os, indent.Next()); + this->GenerateScriptConfigs(os, + this->AllComponents ? indent : indent.Next()); // End this block of installation. - os << indent << "endif()\n\n"; + if (!this->AllComponents) { + os << indent << "endif()\n\n"; + } } bool cmInstallGenerator::InstallsForConfig(const std::string& config) diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h index 6cd9ff9..0117617 100644 --- a/Source/cmInstallGenerator.h +++ b/Source/cmInstallGenerator.h @@ -33,7 +33,8 @@ public: cmInstallGenerator(std::string destination, std::vector<std::string> const& configurations, std::string component, MessageLevel message, - bool exclude_from_all, cmListFileBacktrace backtrace); + bool exclude_from_all, bool all_components, + cmListFileBacktrace backtrace); ~cmInstallGenerator() override; cmInstallGenerator(cmInstallGenerator const&) = delete; @@ -65,6 +66,7 @@ public: std::string const& GetComponent() const { return this->Component; } bool GetExcludeFromAll() const { return this->ExcludeFromAll; } + bool GetAllComponentsFlag() const { return this->AllComponents; } cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; } @@ -79,5 +81,6 @@ protected: std::string const Component; MessageLevel const Message; bool const ExcludeFromAll; + bool const AllComponents; cmListFileBacktrace const Backtrace; }; diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index bb38990..bec98b6 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -14,9 +14,10 @@ cmInstallScriptGenerator::cmInstallScriptGenerator( std::string script, bool code, std::string const& component, - bool exclude_from_all, cmListFileBacktrace backtrace) + bool exclude_from_all, bool all_components, cmListFileBacktrace backtrace) : cmInstallGenerator("", std::vector<std::string>(), component, - MessageDefault, exclude_from_all, std::move(backtrace)) + MessageDefault, exclude_from_all, all_components, + std::move(backtrace)) , Script(std::move(script)) , Code(code) , AllowGenex(false) diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h index 6274f1c..2cf6a4b 100644 --- a/Source/cmInstallScriptGenerator.h +++ b/Source/cmInstallScriptGenerator.h @@ -21,7 +21,7 @@ class cmInstallScriptGenerator : public cmInstallGenerator public: cmInstallScriptGenerator( std::string script, bool code, std::string const& component, - bool exclude_from_all, + bool exclude_from_all, bool all_components, cmListFileBacktrace backtrace = cmListFileBacktrace()); ~cmInstallScriptGenerator() override; diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx index 76806e5..794694e 100644 --- a/Source/cmInstallSubdirectoryGenerator.cxx +++ b/Source/cmInstallSubdirectoryGenerator.cxx @@ -14,10 +14,10 @@ #include "cmSystemTools.h" cmInstallSubdirectoryGenerator::cmInstallSubdirectoryGenerator( - cmMakefile* makefile, std::string binaryDirectory, bool excludeFromAll, + cmMakefile* makefile, std::string binaryDirectory, cmListFileBacktrace backtrace) : cmInstallGenerator("", std::vector<std::string>(), "", MessageDefault, - excludeFromAll, std::move(backtrace)) + false, false, std::move(backtrace)) , Makefile(makefile) , BinaryDirectory(std::move(binaryDirectory)) { @@ -52,7 +52,7 @@ bool cmInstallSubdirectoryGenerator::Compute(cmLocalGenerator* lg) void cmInstallSubdirectoryGenerator::GenerateScript(std::ostream& os) { - if (!this->ExcludeFromAll) { + if (!this->Makefile->GetPropertyAsBool("EXCLUDE_FROM_ALL")) { cmPolicies::PolicyStatus status = this->LocalGenerator->GetPolicyStatus(cmPolicies::CMP0082); switch (status) { diff --git a/Source/cmInstallSubdirectoryGenerator.h b/Source/cmInstallSubdirectoryGenerator.h index 614cef9..f174d07 100644 --- a/Source/cmInstallSubdirectoryGenerator.h +++ b/Source/cmInstallSubdirectoryGenerator.h @@ -21,7 +21,6 @@ class cmInstallSubdirectoryGenerator : public cmInstallGenerator public: cmInstallSubdirectoryGenerator(cmMakefile* makefile, std::string binaryDirectory, - bool excludeFromAll, cmListFileBacktrace backtrace); ~cmInstallSubdirectoryGenerator() override; diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index eb214fa..3e79ad8 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -46,7 +46,7 @@ cmInstallTargetGenerator::cmInstallTargetGenerator( std::string const& component, MessageLevel message, bool exclude_from_all, bool optional, cmListFileBacktrace backtrace) : cmInstallGenerator(dest, configurations, component, message, - exclude_from_all, std::move(backtrace)) + exclude_from_all, false, std::move(backtrace)) , TargetName(std::move(targetName)) , Target(nullptr) , FilePermissions(std::move(file_permissions)) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 4db9216..0c686aa 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -3317,7 +3317,7 @@ void cmLocalGenerator::GenerateTargetInstallRules( // Include the user-specified pre-install script for this target. if (cmProp preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) { - cmInstallScriptGenerator g(*preinstall, false, "", false); + cmInstallScriptGenerator g(*preinstall, false, "", false, false); g.Generate(os, config, configurationTypes); } @@ -3370,7 +3370,7 @@ void cmLocalGenerator::GenerateTargetInstallRules( // Include the user-specified post-install script for this target. if (cmProp postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) { - cmInstallScriptGenerator g(*postinstall, false, "", false); + cmInstallScriptGenerator g(*postinstall, false, "", false, false); g.Generate(os, config, configurationTypes); } } diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index a8570e2..fb6c730 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -263,6 +263,7 @@ void cmLocalNinjaGenerator::WriteBuildFileTop() this->GetConfigNames().front()); } this->WriteNinjaFilesInclusionCommon(this->GetCommonFileStream()); + this->WriteNinjaWorkDir(this->GetCommonFileStream()); // For the rule file. this->WriteProjectHeader(this->GetRulesFileStream()); @@ -364,6 +365,17 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusionCommon(std::ostream& os) os << "\n"; } +void cmLocalNinjaGenerator::WriteNinjaWorkDir(std::ostream& os) +{ + cmGlobalNinjaGenerator::WriteDivider(os); + cmGlobalNinjaGenerator::WriteComment( + os, "Logical path to working directory; prefix for absolute paths."); + cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator(); + std::string ninja_workdir = this->GetBinaryDirectory(); + ng->StripNinjaOutputPathPrefixAsSuffix(ninja_workdir); // Also appends '/'. + os << "cmake_ninja_workdir = " << ng->EncodePath(ninja_workdir) << "\n"; +} + void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os) { cmGlobalNinjaGenerator::WriteDivider(os); @@ -638,16 +650,11 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( } } - cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size()); - std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(), - gg->MapToNinjaPath()); - std::transform(byproducts.begin(), byproducts.end(), - ninjaOutputs.begin() + outputs.size(), - gg->MapToNinjaPath()); + cmGlobalNinjaGenerator::CCOutputs ccOutputs(gg); + ccOutputs.Add(outputs); + ccOutputs.Add(byproducts); - for (std::string const& ninjaOutput : ninjaOutputs) { - gg->SeenCustomCommandOutput(ninjaOutput); - } + std::string mainOutput = ccOutputs.ExplicitOuts[0]; cmNinjaDeps ninjaDeps; this->AppendCustomCommandDeps(ccg, ninjaDeps, fileConfig); @@ -657,13 +664,14 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( if (cmdLines.empty()) { cmNinjaBuild build("phony"); - build.Comment = "Phony custom command for " + ninjaOutputs[0]; - build.Outputs = std::move(ninjaOutputs); + build.Comment = cmStrCat("Phony custom command for ", mainOutput); + build.Outputs = std::move(ccOutputs.ExplicitOuts); + build.WorkDirOuts = std::move(ccOutputs.WorkDirOuts); build.ExplicitDeps = std::move(ninjaDeps); build.OrderOnlyDeps = orderOnlyDeps; gg->WriteBuild(this->GetImplFileStream(fileConfig), build); } else { - std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]); + std::string customStep = cmSystemTools::GetFilenameName(mainOutput); if (this->GlobalGenerator->IsMultiConfig()) { customStep += '-'; customStep += fileConfig; @@ -673,7 +681,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( // Hash full path to make unique. customStep += '-'; cmCryptoHash hash(cmCryptoHash::AlgoSHA256); - customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7); + customStep += hash.HashString(mainOutput).substr(0, 7); std::string depfile = ccg.GetDepfile(); if (!depfile.empty()) { @@ -701,13 +709,14 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( } } + std::string comment = cmStrCat("Custom command for ", mainOutput); gg->WriteCustomCommandBuild( this->BuildCommandLine(cmdLines, ccg.GetOutputConfig(), fileConfig, customStep), - this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0], - depfile, cc->GetJobPool(), cc->GetUsesTerminal(), - /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, fileConfig, - ninjaDeps, orderOnlyDeps); + this->ConstructComment(ccg), comment, depfile, cc->GetJobPool(), + cc->GetUsesTerminal(), + /*restat*/ !symbolic || !byproducts.empty(), fileConfig, + std::move(ccOutputs), std::move(ninjaDeps), std::move(orderOnlyDeps)); } } } diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index a73fa27..6404037 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -108,6 +108,7 @@ private: const std::string& config); void WriteNinjaFilesInclusionConfig(std::ostream& os); void WriteNinjaFilesInclusionCommon(std::ostream& os); + void WriteNinjaWorkDir(std::ostream& os); void WriteProcessedMakefile(std::ostream& os); void WritePools(std::ostream& os); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index d7987c2..ffe94ba 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1844,7 +1844,7 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath, } this->AddInstallGenerator(cm::make_unique<cmInstallSubdirectoryGenerator>( - subMf, binPath, excludeFromAll, this->GetBacktrace())); + subMf, binPath, this->GetBacktrace())); } const std::string& cmMakefile::GetCurrentSourceDirectory() const diff --git a/Source/cmMessageMetadata.h b/Source/cmMessageMetadata.h new file mode 100644 index 0000000..7b56fae --- /dev/null +++ b/Source/cmMessageMetadata.h @@ -0,0 +1,11 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmsys/Terminal.h" + +struct cmMessageMetadata +{ + const char* title = nullptr; + int desiredColor = cmsysTerminal_Color_Normal; +}; diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx index af83478..1cb638a 100644 --- a/Source/cmMessenger.cxx +++ b/Source/cmMessenger.cxx @@ -3,6 +3,7 @@ #include "cmMessenger.h" #include "cmDocumentationFormatter.h" +#include "cmMessageMetadata.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -12,6 +13,8 @@ #include <sstream> +#include "cmsys/Terminal.h" + MessageType cmMessenger::ConvertMessageType(MessageType t) const { bool warningsAsErrors; @@ -84,6 +87,21 @@ static bool printMessagePreamble(MessageType t, std::ostream& msg) return true; } +static int getMessageColor(MessageType t) +{ + switch (t) { + case MessageType::INTERNAL_ERROR: + case MessageType::FATAL_ERROR: + case MessageType::AUTHOR_ERROR: + return cmsysTerminal_Color_ForegroundRed; + case MessageType::AUTHOR_WARNING: + case MessageType::WARNING: + return cmsysTerminal_Color_ForegroundYellow; + default: + return cmsysTerminal_Color_Normal; + } +} + void printMessageText(std::ostream& msg, std::string const& text) { msg << ":\n"; @@ -120,12 +138,16 @@ void displayMessage(MessageType t, std::ostringstream& msg) #endif // Output the message. + cmMessageMetadata md; + md.desiredColor = getMessageColor(t); if (t == MessageType::FATAL_ERROR || t == MessageType::INTERNAL_ERROR || t == MessageType::DEPRECATION_ERROR || t == MessageType::AUTHOR_ERROR) { cmSystemTools::SetErrorOccured(); - cmSystemTools::Message(msg.str(), "Error"); + md.title = "Error"; + cmSystemTools::Message(msg.str(), md); } else { - cmSystemTools::Message(msg.str(), "Warning"); + md.title = "Warning"; + cmSystemTools::Message(msg.str(), md); } } diff --git a/Source/cmNinjaTypes.h b/Source/cmNinjaTypes.h index 320f41b..c8a411e 100644 --- a/Source/cmNinjaTypes.h +++ b/Source/cmNinjaTypes.h @@ -53,6 +53,7 @@ public: std::string Rule; cmNinjaDeps Outputs; cmNinjaDeps ImplicitOuts; + cmNinjaDeps WorkDirOuts; // For cmake_ninja_workdir. cmNinjaDeps ExplicitDeps; cmNinjaDeps ImplicitDeps; cmNinjaDeps OrderOnlyDeps; diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 7a04c47..1f5a7ff 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -73,7 +73,8 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( cmNinjaBuild phonyBuild("phony"); std::vector<std::string> commands; cmNinjaDeps deps; - cmNinjaDeps util_outputs(1, utilCommandName); + cmGlobalNinjaGenerator::CCOutputs util_outputs(gg); + util_outputs.ExplicitOuts.emplace_back(utilCommandName); bool uses_terminal = false; { @@ -86,10 +87,7 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( cmCustomCommandGenerator ccg(ci, fileConfig, lg); lg->AppendCustomCommandDeps(ccg, deps, fileConfig); lg->AppendCustomCommandLines(ccg, commands); - std::vector<std::string> const& ccByproducts = ccg.GetByproducts(); - std::transform(ccByproducts.begin(), ccByproducts.end(), - std::back_inserter(util_outputs), - this->MapToNinjaPath()); + util_outputs.Add(ccg.GetByproducts()); if (ci.GetUsesTerminal()) { uses_terminal = true; } @@ -124,7 +122,8 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( if (genTarget->Target->GetType() != cmStateEnums::GLOBAL_TARGET) { lg->AppendTargetOutputs(genTarget, gg->GetByproductsForCleanTarget(), config); - std::copy(util_outputs.begin(), util_outputs.end(), + std::copy(util_outputs.ExplicitOuts.begin(), + util_outputs.ExplicitOuts.end(), std::back_inserter(gg->GetByproductsForCleanTarget())); } lg->AppendTargetDepends(genTarget, deps, config, fileConfig, @@ -166,10 +165,6 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( return; } - for (std::string const& util_output : util_outputs) { - gg->SeenCustomCommandOutput(util_output); - } - std::string ccConfig; if (genTarget->Target->IsPerConfig() && genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) { @@ -180,7 +175,7 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( gg->WriteCustomCommandBuild( command, desc, "Utility command for " + this->GetTargetName(), /*depfile*/ "", /*job_pool*/ "", uses_terminal, - /*restat*/ true, util_outputs, ccConfig, deps); + /*restat*/ true, ccConfig, std::move(util_outputs), std::move(deps)); } phonyBuild.ExplicitDeps.push_back(utilCommandName); diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 2fba13f..9b81bf2 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -19,6 +19,7 @@ #include <cm3p/uv.h> #include "cmDuration.h" +#include "cmMessageMetadata.h" #include "cmProcessOutput.h" #include "cmRange.h" #include "cmStringAlgorithms.h" @@ -263,8 +264,15 @@ void cmSystemTools::Stdout(const std::string& s) void cmSystemTools::Message(const std::string& m, const char* title) { + cmMessageMetadata md; + md.title = title; + Message(m, md); +} + +void cmSystemTools::Message(const std::string& m, const cmMessageMetadata& md) +{ if (s_MessageCallback) { - s_MessageCallback(m, title); + s_MessageCallback(m, md); } else { std::cerr << m << std::endl; } diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 474f591..5c3b5a9 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -19,6 +19,8 @@ #include "cmDuration.h" #include "cmProcessOutput.h" +struct cmMessageMetadata; + /** \class cmSystemTools * \brief A collection of useful functions for CMake. * @@ -40,7 +42,8 @@ public: /** Map help document name to file name. */ static std::string HelpFileName(cm::string_view); - using MessageCallback = std::function<void(const std::string&, const char*)>; + using MessageCallback = + std::function<void(const std::string&, const cmMessageMetadata&)>; /** * Set the function used by GUIs to display error messages * Function gets passed: message as a const char*, @@ -57,6 +60,7 @@ public: * Display a message. */ static void Message(const std::string& m, const char* title = nullptr); + static void Message(const std::string& m, const cmMessageMetadata& md); using OutputCallback = std::function<void(std::string const&)>; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 5440984..315bd20 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -529,25 +529,29 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) std::vector<CommandArgument> arguments = { CommandArgument{ "-D", "-D must be followed with VAR=VALUE.", - CommandArgument::Values::One, DefineLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, DefineLambda }, CommandArgument{ "-W", "-W must be followed with [no-]<name>.", - CommandArgument::Values::One, WarningLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, WarningLambda }, CommandArgument{ "-U", "-U must be followed with VAR.", - CommandArgument::Values::One, UnSetLambda }, - CommandArgument{ "-C", "-C must be followed by a file name.", CommandArgument::Values::One, - [&](std::string const& value, cmake* state) -> bool { - cmSystemTools::Stdout("loading initial cache file " + - value + "\n"); - // Resolve script path specified on command line - // relative to $PWD. - auto path = cmSystemTools::CollapseFullPath(value); - state->ReadListFile(args, path); - return true; - } }, + CommandArgument::RequiresSeparator::No, UnSetLambda }, + CommandArgument{ + "-C", "-C must be followed by a file name.", + CommandArgument::Values::One, CommandArgument::RequiresSeparator::No, + [&](std::string const& value, cmake* state) -> bool { + cmSystemTools::Stdout("loading initial cache file " + value + "\n"); + // Resolve script path specified on command line + // relative to $PWD. + auto path = cmSystemTools::CollapseFullPath(value); + state->ReadListFile(args, path); + return true; + } }, CommandArgument{ "-P", "-P must be followed by a file name.", - CommandArgument::Values::One, ScriptLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, ScriptLambda }, CommandArgument{ "--toolchain", "No file specified for --toolchain", CommandArgument::Values::One, ToolchainLambda }, CommandArgument{ "--install-prefix", @@ -830,31 +834,44 @@ void cmake::SetArgs(const std::vector<std::string>& args) std::vector<CommandArgument> arguments = { CommandArgument{ "-S", "No source directory specified for -S", - CommandArgument::Values::One, SourceArgLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, SourceArgLambda }, CommandArgument{ "-H", "No source directory specified for -H", - CommandArgument::Values::One, SourceArgLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, SourceArgLambda }, CommandArgument{ "-O", CommandArgument::Values::Zero, IgnoreAndTrueLambda }, CommandArgument{ "-B", "No build directory specified for -B", - CommandArgument::Values::One, BuildArgLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, BuildArgLambda }, CommandArgument{ "-P", "-P must be followed by a file name.", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, [&](std::string const&, cmake*) -> bool { scriptMode = true; return true; } }, CommandArgument{ "-D", "-D must be followed with VAR=VALUE.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, + IgnoreAndTrueLambda }, CommandArgument{ "-C", "-C must be followed by a file name.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, - CommandArgument{ "-U", "-U must be followed with VAR.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, + IgnoreAndTrueLambda }, + CommandArgument{ + "-U", "-U must be followed with VAR.", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, IgnoreAndTrueLambda }, CommandArgument{ "-W", "-W must be followed with [no-]<name>.", - CommandArgument::Values::One, IgnoreAndTrueLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, + IgnoreAndTrueLambda }, CommandArgument{ "-A", "No platform specified for -A", - CommandArgument::Values::One, PlatformLambda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, PlatformLambda }, CommandArgument{ "-T", "No toolset specified for -T", - CommandArgument::Values::One, ToolsetLamda }, + CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, ToolsetLamda }, CommandArgument{ "--toolchain", "No file specified for --toolchain", CommandArgument::Values::One, IgnoreAndTrueLambda }, CommandArgument{ "--install-prefix", @@ -1079,6 +1096,7 @@ void cmake::SetArgs(const std::vector<std::string>& args) bool badGeneratorName = false; CommandArgument generatorCommand( "-G", "No generator specified for -G", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, [&](std::string const& value, cmake* state) -> bool { bool valid = state->CreateAndSetGlobalGenerator(value, true); badGeneratorName = !valid; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index ad64818..d83183f 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -6,6 +6,7 @@ #include <algorithm> #include <cassert> #include <climits> +#include <cstdio> #include <cstring> #include <iostream> #include <sstream> @@ -23,6 +24,7 @@ #include "cmDocumentationEntry.h" // IWYU pragma: keep #include "cmGlobalGenerator.h" #include "cmMakefile.h" +#include "cmMessageMetadata.h" #include "cmProperty.h" #include "cmState.h" #include "cmStateTypes.h" @@ -37,6 +39,7 @@ #endif #include "cmsys/Encoding.hxx" +#include "cmsys/Terminal.h" namespace { #ifndef CMAKE_BOOTSTRAP @@ -147,10 +150,12 @@ std::string cmakemainGetStack(cmake* cm) return msg; } -void cmakemainMessageCallback(const std::string& m, const char* /*unused*/, - cmake* cm) +void cmakemainMessageCallback(const std::string& m, + const cmMessageMetadata& md, cmake* cm) { - std::cerr << m << cmakemainGetStack(cm) << std::endl; + cmsysTerminal_cfprintf(md.desiredColor, stderr, "%s", m.c_str()); + fflush(stderr); // stderr is buffered in some cases. + std::cerr << cmakemainGetStack(cm) << "\n"; } void cmakemainProgressCallback(const std::string& m, float prog, cmake* cm) @@ -271,6 +276,7 @@ int do_cmake(int ac, char const* const* av) } }, CommandArgument{ "-P", "No script specified for argument -P", CommandArgument::Values::One, + CommandArgument::RequiresSeparator::No, [&](std::string const& value) -> bool { workingMode = cmake::SCRIPT_MODE; parsedArgs.emplace_back("-P"); @@ -342,8 +348,8 @@ int do_cmake(int ac, char const* const* av) cm.SetHomeDirectory(""); cm.SetHomeOutputDirectory(""); cmSystemTools::SetMessageCallback( - [&cm](const std::string& msg, const char* title) { - cmakemainMessageCallback(msg, title, &cm); + [&cm](const std::string& msg, const cmMessageMetadata& md) { + cmakemainMessageCallback(msg, md, &cm); }); cm.SetProgressCallback([&cm](const std::string& msg, float prog) { cmakemainProgressCallback(msg, prog, &cm); @@ -476,9 +482,10 @@ int do_build(int ac, char const* const* av) listPresets = true; return true; } }, - CommandArgument{ "-j", CommandArgument::Values::ZeroOrOne, jLambda }, + CommandArgument{ "-j", CommandArgument::Values::ZeroOrOne, + CommandArgument::RequiresSeparator::No, jLambda }, CommandArgument{ "--parallel", CommandArgument::Values::ZeroOrOne, - parallelLambda }, + CommandArgument::RequiresSeparator::No, parallelLambda }, CommandArgument{ "-t", CommandArgument::Values::OneOrMore, targetLambda }, CommandArgument{ "--target", CommandArgument::Values::OneOrMore, targetLambda }, @@ -624,8 +631,8 @@ int do_build(int ac, char const* const* av) cmake cm(cmake::RoleInternal, cmState::Project); cmSystemTools::SetMessageCallback( - [&cm](const std::string& msg, const char* title) { - cmakemainMessageCallback(msg, title, &cm); + [&cm](const std::string& msg, const cmMessageMetadata& md) { + cmakemainMessageCallback(msg, md, &cm); }); cm.SetProgressCallback([&cm](const std::string& msg, float prog) { cmakemainProgressCallback(msg, prog, &cm); @@ -857,8 +864,8 @@ int do_install(int ac, char const* const* av) cmake cm(cmake::RoleScript, cmState::Script); cmSystemTools::SetMessageCallback( - [&cm](const std::string& msg, const char* title) { - cmakemainMessageCallback(msg, title, &cm); + [&cm](const std::string& msg, const cmMessageMetadata& md) { + cmakemainMessageCallback(msg, md, &cm); }); cm.SetProgressCallback([&cm](const std::string& msg, float prog) { cmakemainProgressCallback(msg, prog, &cm); @@ -938,8 +945,8 @@ int do_open(int ac, char const* const* av) cmake cm(cmake::RoleInternal, cmState::Unknown); cmSystemTools::SetMessageCallback( - [&cm](const std::string& msg, const char* title) { - cmakemainMessageCallback(msg, title, &cm); + [&cm](const std::string& msg, const cmMessageMetadata& md) { + cmakemainMessageCallback(msg, md, &cm); }); cm.SetProgressCallback([&cm](const std::string& msg, float prog) { cmakemainProgressCallback(msg, prog, &cm); diff --git a/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.cmake b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.cmake new file mode 100644 index 0000000..22e7f27 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.cmake @@ -0,0 +1,19 @@ +enable_language(C) + +add_custom_command( + OUTPUT main.c + COMMAND ${CMAKE_COMMAND} -E copy main.c.in main.c + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/main.c.in + ) +add_executable(main main.c) +set_property(TARGET main PROPERTY UNITY_BUILD ON) + +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +set(check_pairs + \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c.in\" + \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\" + ) +set(check_exes + \"$<TARGET_FILE:main>\" + ) +") diff --git a/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step1.cmake b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step1.cmake new file mode 100644 index 0000000..87576eb --- /dev/null +++ b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step1.cmake @@ -0,0 +1,3 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c.in" [[ +int main(void) { return 1; } +]]) diff --git a/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step2.cmake b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step2.cmake new file mode 100644 index 0000000..69b21b8 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/CustomCommandUnityBuild.step2.cmake @@ -0,0 +1,3 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c.in" [[ +int main(void) { return 2; } +]]) diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake index 72faddb..0a80580 100644 --- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake +++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake @@ -1,5 +1,22 @@ include(RunCMake) +if(RunCMake_GENERATOR MATCHES "Ninja") + # Detect ninja version so we know what tests can be supported. + execute_process( + COMMAND "${RunCMake_MAKE_PROGRAM}" --version + OUTPUT_VARIABLE ninja_out + ERROR_VARIABLE ninja_out + RESULT_VARIABLE ninja_res + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(ninja_res EQUAL 0 AND "x${ninja_out}" MATCHES "^x[0-9]+\\.[0-9]+") + set(ninja_version "${ninja_out}") + message(STATUS "ninja version: ${ninja_version}") + else() + message(FATAL_ERROR "'ninja --version' reported:\n${ninja_out}") + endif() +endif() + if(RunCMake_GENERATOR STREQUAL "Borland Makefiles" OR RunCMake_GENERATOR STREQUAL "Watcom WMake") set(fs_delay 3) @@ -164,3 +181,11 @@ endif() if(RunCMake_GENERATOR MATCHES "Make") run_BuildDepends(MakeDependencies) endif() + +if(RunCMake_GENERATOR MATCHES "^Visual Studio 9 " OR + (RunCMake_GENERATOR MATCHES "Ninja" AND ninja_version VERSION_LESS 1.7)) + # This build tool misses the dependency. + set(run_BuildDepends_skip_step_2 1) +endif() +run_BuildDepends(CustomCommandUnityBuild) +unset(run_BuildDepends_skip_step_2) diff --git a/Tests/RunCMake/CommandLine/build-invalid-target-syntax-stderr.txt b/Tests/RunCMake/CommandLine/build-invalid-target-syntax-stderr.txt index 5fe2539..fa3adc8 100644 --- a/Tests/RunCMake/CommandLine/build-invalid-target-syntax-stderr.txt +++ b/Tests/RunCMake/CommandLine/build-invalid-target-syntax-stderr.txt @@ -1,2 +1 @@ -^CMake Error: '--target=invalid' is invalid syntax for --target -Usage: cmake --build \[<dir> \| --preset <preset>\] \[options\] \[-- \[native-options\]\] +^Error: could not load cache diff --git a/Tests/RunCMake/CommandLine/build-unknown-command-partial-match-stderr.txt b/Tests/RunCMake/CommandLine/build-unknown-command-partial-match-stderr.txt index d69338a..e4ad6b2 100644 --- a/Tests/RunCMake/CommandLine/build-unknown-command-partial-match-stderr.txt +++ b/Tests/RunCMake/CommandLine/build-unknown-command-partial-match-stderr.txt @@ -1,2 +1,2 @@ -^CMake Error: '--targetinvalid' is invalid syntax for --target +^Unknown argument --targetinvalid Usage: cmake --build \[<dir> \| --preset <preset>\] \[options\] \[-- \[native-options\]\] diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py index 0d718a4..b9a1fbf 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py +++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py @@ -136,6 +136,10 @@ def check_directory(c): expected_keys.append("isExcludeFromAll") assert is_bool(a["isExcludeFromAll"], e["isExcludeFromAll"]) + if e["isForAllComponents"] is not None: + expected_keys.append("isForAllComponents") + assert is_bool(a["isForAllComponents"], e["isForAllComponents"]) + if e["isOptional"] is not None: expected_keys.append("isOptional") assert is_bool(a["isOptional"], e["isOptional"]) diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json index 55dd573..6d2952d 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json @@ -20,6 +20,7 @@ "^.*/Tests/RunCMake/FileAPIExternalSource/\\.$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, @@ -51,6 +52,7 @@ "^.*/Tests/RunCMake/FileAPIExternalSource$" ], "isExcludeFromAll": true, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json index ef2dd0b..44bc725 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json @@ -23,6 +23,7 @@ "^object/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?c_object_exe(\\.exe)?$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^c_object_exe::@5ed5358f70faf8d8af7a$", "targetIndex": "c_object_exe", @@ -54,6 +55,7 @@ "^object/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?cxx_object_exe(\\.exe)?$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^cxx_object_exe::@5ed5358f70faf8d8af7a$", "targetIndex": "cxx_object_exe", diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json index 4727607..99287fb 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json +++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json @@ -35,6 +35,7 @@ "^cxx/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?cxx_exe(\\.exe)?$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^cxx_exe::@a56b12a3f5c0529fb296$", "targetIndex": "cxx_exe", @@ -78,6 +79,7 @@ "^((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?c_shared_lib\\.(lib|dll\\.a)$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^c_shared_lib::@6890427a1f51a3e7e1df$", "targetIndex": "c_shared_lib", @@ -126,6 +128,7 @@ "^lib/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?c_shared_lib\\.(so\\.1|1\\.dylib)$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^c_shared_lib::@6890427a1f51a3e7e1df$", "targetIndex": "c_shared_lib", @@ -169,6 +172,7 @@ "^cxx/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?cxx_shared_lib\\.(lib|dll\\.a)$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^cxx_shared_lib::@a56b12a3f5c0529fb296$", "targetIndex": "cxx_shared_lib", @@ -213,6 +217,7 @@ "^cxx/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib|cyg|msys-)?cxx_shared_lib\\.(dll|so|dylib)$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^cxx_shared_lib::@a56b12a3f5c0529fb296$", "targetIndex": "cxx_shared_lib", @@ -256,6 +261,7 @@ "^lib/((Debug|Release|MinSizeRel|RelWithDebInfo)/)?(lib)?c_shared_lib\\.(dll|so|dylib)$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": "^c_shared_lib::@6890427a1f51a3e7e1df$", "targetIndex": "c_shared_lib", @@ -302,6 +308,7 @@ } ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": true, "targetId": null, "targetIndex": null, @@ -346,6 +353,7 @@ "^empty\\.h$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, @@ -394,6 +402,7 @@ } ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": true, "targetId": null, "targetIndex": null, @@ -445,6 +454,7 @@ } ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, @@ -488,6 +498,7 @@ "^CMakeFiles/Export/lib/cmake/foo/FooTargets\\.cmake$" ], "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, @@ -534,6 +545,7 @@ "destination": null, "paths": null, "isExcludeFromAll": null, + "isForAllComponents": null, "isOptional": null, "targetId": null, "targetIndex": null, @@ -568,6 +580,48 @@ "hasParent": false } ] + }, + { + "component": "Unspecified", + "type": "code", + "destination": null, + "paths": null, + "isExcludeFromAll": null, + "isForAllComponents": true, + "isOptional": null, + "targetId": null, + "targetIndex": null, + "targetIsImportLibrary": null, + "targetInstallNamelink": null, + "exportName": null, + "exportTargets": null, + "scriptFile": null, + "backtrace": [ + { + "file": "^codemodel-v2\\.cmake$", + "line": 54, + "command": "install", + "hasParent": true + }, + { + "file": "^codemodel-v2\\.cmake$", + "line": null, + "command": null, + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": 3, + "command": "include", + "hasParent": true + }, + { + "file": "^CMakeLists\\.txt$", + "line": null, + "command": null, + "hasParent": false + } + ] } ] } diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake index 528f075..da928eb 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake +++ b/Tests/RunCMake/FileAPI/codemodel-v2.cmake @@ -51,3 +51,4 @@ install(DIRECTORY . dir cxx/ OPTIONAL DESTINATION dir1) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/dir" "${CMAKE_CURRENT_SOURCE_DIR}/cxx/" DESTINATION dir2) install(EXPORT FooTargets DESTINATION lib/cmake/foo) install(SCRIPT InstallScript.cmake) +install(CODE "message(foo)" ALL_COMPONENTS) diff --git a/Tests/RunCMake/Framework/ImportedFrameworkTest-build-stdout.txt b/Tests/RunCMake/Framework/ImportedFrameworkTest-build-stdout.txt new file mode 100644 index 0000000..bd75ccd --- /dev/null +++ b/Tests/RunCMake/Framework/ImportedFrameworkTest-build-stdout.txt @@ -0,0 +1 @@ +xxx/no/exist/fw\.framework/Versions/A/fwxxx diff --git a/Tests/RunCMake/Framework/ImportedFrameworkTest.cmake b/Tests/RunCMake/Framework/ImportedFrameworkTest.cmake new file mode 100644 index 0000000..42edaea --- /dev/null +++ b/Tests/RunCMake/Framework/ImportedFrameworkTest.cmake @@ -0,0 +1,10 @@ +add_library(fw SHARED IMPORTED) +set_target_properties(fw PROPERTIES + FRAMEWORK TRUE + IMPORTED_LOCATION "/no/exist/fw.framework/Versions/A/fw" + IMPORTED_SONAME "@rpath/fw.framework/Versions/A/fw" + ) + +add_custom_target(print_fw ALL COMMAND + ${CMAKE_COMMAND} -E echo "xxx$<TARGET_SONAME_FILE:fw>xxx" + ) diff --git a/Tests/RunCMake/Framework/RunCMakeTest.cmake b/Tests/RunCMake/Framework/RunCMakeTest.cmake index 6ee61a3..36eaf5c 100644 --- a/Tests/RunCMake/Framework/RunCMakeTest.cmake +++ b/Tests/RunCMake/Framework/RunCMakeTest.cmake @@ -81,3 +81,15 @@ function(framework_multi_config_postfix_test) endfunction() framework_multi_config_postfix_test() + +function(imported_framework_test) + set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/ImportedFrameworkTest-build") + set(RunCMake_TEST_NO_CLEAN 1) + + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + run_cmake(ImportedFrameworkTest) + run_cmake_command(ImportedFrameworkTest-build ${CMAKE_COMMAND} --build .) +endfunction() + +imported_framework_test() diff --git a/Tests/RunCMake/add_subdirectory/CMP0082-ExcludeFromAll/CMakeLists.txt b/Tests/RunCMake/add_subdirectory/CMP0082-ExcludeFromAll/CMakeLists.txt index 1bd7f49..32bb1a9 100644 --- a/Tests/RunCMake/add_subdirectory/CMP0082-ExcludeFromAll/CMakeLists.txt +++ b/Tests/RunCMake/add_subdirectory/CMP0082-ExcludeFromAll/CMakeLists.txt @@ -1 +1,2 @@ install(CODE "message(STATUS \"exclude\")") +set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL TRUE) diff --git a/Tests/RunCMake/add_subdirectory/CMP0082-NEW.cmake b/Tests/RunCMake/add_subdirectory/CMP0082-NEW.cmake index 56c1b81..8ebf21b 100644 --- a/Tests/RunCMake/add_subdirectory/CMP0082-NEW.cmake +++ b/Tests/RunCMake/add_subdirectory/CMP0082-NEW.cmake @@ -1,3 +1,3 @@ add_subdirectory(CMP0082) -add_subdirectory(CMP0082-ExcludeFromAll EXCLUDE_FROM_ALL) +add_subdirectory(CMP0082-ExcludeFromAll) install(CODE "message(STATUS \"top\")") diff --git a/Tests/RunCMake/add_subdirectory/CMP0082-OLD.cmake b/Tests/RunCMake/add_subdirectory/CMP0082-OLD.cmake index 56c1b81..8ebf21b 100644 --- a/Tests/RunCMake/add_subdirectory/CMP0082-OLD.cmake +++ b/Tests/RunCMake/add_subdirectory/CMP0082-OLD.cmake @@ -1,3 +1,3 @@ add_subdirectory(CMP0082) -add_subdirectory(CMP0082-ExcludeFromAll EXCLUDE_FROM_ALL) +add_subdirectory(CMP0082-ExcludeFromAll) install(CODE "message(STATUS \"top\")") diff --git a/Tests/RunCMake/add_subdirectory/CMP0082-WARN.cmake b/Tests/RunCMake/add_subdirectory/CMP0082-WARN.cmake index 56c1b81..8ebf21b 100644 --- a/Tests/RunCMake/add_subdirectory/CMP0082-WARN.cmake +++ b/Tests/RunCMake/add_subdirectory/CMP0082-WARN.cmake @@ -1,3 +1,3 @@ add_subdirectory(CMP0082) -add_subdirectory(CMP0082-ExcludeFromAll EXCLUDE_FROM_ALL) +add_subdirectory(CMP0082-ExcludeFromAll) install(CODE "message(STATUS \"top\")") diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake index 3e56746..94887a0 100644 --- a/Tests/RunCMake/install/RunCMakeTest.cmake +++ b/Tests/RunCMake/install/RunCMakeTest.cmake @@ -179,3 +179,4 @@ run_install_test(FILES-EXCLUDE_FROM_ALL) run_install_test(TARGETS-EXCLUDE_FROM_ALL) run_install_test(TARGETS-NAMELINK_COMPONENT) run_install_test(SCRIPT-COMPONENT) +run_install_test(SCRIPT-ALL_COMPONENTS) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake new file mode 100644 index 0000000..48d8e1a --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake @@ -0,0 +1 @@ +check_installed([[^empty1.txt;empty2.txt$]]) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake new file mode 100644 index 0000000..48d8e1a --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake @@ -0,0 +1 @@ +check_installed([[^empty1.txt;empty2.txt$]]) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake new file mode 100644 index 0000000..48d8e1a --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake @@ -0,0 +1 @@ +check_installed([[^empty1.txt;empty2.txt$]]) diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake new file mode 100644 index 0000000..aa3f9d1 --- /dev/null +++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake @@ -0,0 +1,5 @@ +install( + SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/install_script.cmake" + CODE "write_empty_file(empty2.txt)" + ALL_COMPONENTS + ) |