diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 99c0761a70..df1da053ad 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -18,6 +18,7 @@ #include "cmCustomCommand.h" // IWYU pragma: keep #include "cmCustomCommandGenerator.h" #include "cmGeneratedFileStream.h" +#include "cmGeneratorExpression.h" #include "cmGeneratorOptions.h" #include "cmGeneratorTarget.h" #include "cmGlobalNinjaGenerator.h" @@ -446,8 +447,10 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules( this->GetGlobalGenerator()->AddRule(rule); } -void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, - std::string const& config) +void cmNinjaNormalTargetGenerator::WriteLinkRule( + bool useResponseFile, std::string const& config, + std::vector const& preLinkComments, + std::vector const& postBuildComments) { cmStateEnums::TargetType targetType = this->GetGeneratorTarget()->GetType(); @@ -604,9 +607,19 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage(config), ' ', this->GetVisibleTypeName(), '.'); - rule.Description = - cmStrCat("Linking ", this->TargetLinkLanguage(config), ' ', - this->GetVisibleTypeName(), " $TARGET_FILE"); + char const* presep = ""; + char const* postsep = ""; + auto prelink = cmJoin(preLinkComments, "; "); + if (!prelink.empty()) { + presep = "; "; + } + auto postbuild = cmJoin(postBuildComments, "; "); + if (!postbuild.empty()) { + postsep = "; "; + } + rule.Description = cmStrCat( + prelink, presep, "Linking ", this->TargetLinkLanguage(config), ' ', + this->GetVisibleTypeName(), " $TARGET_FILE", postsep, postbuild); rule.Restat = "$RESTAT"; this->GetGlobalGenerator()->AddRule(rule); } @@ -1398,12 +1411,19 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( >->GetPostBuildCommands() }; + std::vector preLinkComments; + std::vector postBuildComments; + std::vector preLinkCmdLines; std::vector postBuildCmdLines; + std::vector* cmdComments[3] = { &preLinkComments, + &preLinkComments, + &postBuildComments }; std::vector* cmdLineLists[3] = { &preLinkCmdLines, &preLinkCmdLines, &postBuildCmdLines }; + cmGeneratorExpression ge(*this->GetLocalGenerator()->GetCMakeInstance()); for (unsigned i = 0; i != 3; ++i) { for (cmCustomCommand const& cc : *cmdLists[i]) { @@ -1413,6 +1433,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( cmCustomCommandGenerator ccg(cc, fileConfig, this->GetLocalGenerator(), true, config); localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]); + if (cc.GetComment()) { + auto cge = ge.Parse(cc.GetComment()); + cmdComments[i]->emplace_back( + cge->Evaluate(this->GetLocalGenerator(), config)); + } std::vector const& ccByproducts = ccg.GetByproducts(); byproducts.Add(ccByproducts); std::transform( @@ -1566,7 +1591,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( bool usedResponseFile = false; globalGen->WriteBuild(this->GetImplFileStream(fileConfig), linkBuild, commandLineLengthLimit, &usedResponseFile); - this->WriteLinkRule(usedResponseFile, config); + this->WriteLinkRule(usedResponseFile, config, preLinkComments, + postBuildComments); if (symlinkNeeded) { if (targetType == cmStateEnums::EXECUTABLE) { diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h index fd2c69f314..488bcfdf6f 100644 --- a/Source/cmNinjaNormalTargetGenerator.h +++ b/Source/cmNinjaNormalTargetGenerator.h @@ -30,7 +30,9 @@ private: char const* GetVisibleTypeName() const; void WriteLanguagesRules(std::string const& config); - void WriteLinkRule(bool useResponseFile, std::string const& config); + void WriteLinkRule(bool useResponseFile, std::string const& config, + std::vector const& preLinkComments, + std::vector const& postBuildComments); void WriteDeviceLinkRules(std::string const& config); void WriteNvidiaDeviceLinkRule(bool useResponseFile, std::string const& config); diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index f4b95eb400..0b33d364c6 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -13,6 +14,7 @@ #include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" #include "cmGeneratedFileStream.h" +#include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalNinjaGenerator.h" #include "cmLocalNinjaGenerator.h" @@ -76,6 +78,8 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( cmGlobalNinjaGenerator::CCOutputs util_outputs(gg); util_outputs.ExplicitOuts.emplace_back(utilCommandName); + std::string commandDesc; + cmGeneratorExpression ge(*this->GetLocalGenerator()->GetCMakeInstance()); bool uses_terminal = false; { std::array const*, 2> const cmdLists = { @@ -87,6 +91,13 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( cmCustomCommandGenerator ccg(ci, fileConfig, lg); lg->AppendCustomCommandDeps(ccg, deps, fileConfig); lg->AppendCustomCommandLines(ccg, commands); + if (ci.GetComment()) { + if (!commandDesc.empty()) { + commandDesc += "; "; + } + auto cge = ge.Parse(ci.GetComment()); + commandDesc += cge->Evaluate(this->GetLocalGenerator(), config); + } util_outputs.Add(ccg.GetByproducts()); if (ci.GetUsesTerminal()) { uses_terminal = true; @@ -144,6 +155,8 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( cmValue echoStr = genTarget->GetProperty("EchoString"); if (echoStr) { desc = *echoStr; + } else if (!commandDesc.empty()) { + desc = commandDesc; } else { desc = "Running utility command for " + this->GetTargetName(); } diff --git a/Tests/RunCMake/Ninja/CustomCommandTargetComments.cmake b/Tests/RunCMake/Ninja/CustomCommandTargetComments.cmake new file mode 100644 index 0000000000..cfadcb3096 --- /dev/null +++ b/Tests/RunCMake/Ninja/CustomCommandTargetComments.cmake @@ -0,0 +1,12 @@ +enable_language(C) + +add_executable(hello hello.c) +add_custom_command(TARGET hello PRE_BUILD + COMMENT "pre-build: $<1:genex>" + COMMAND "${CMAKE_COMMAND}" -E echo "$") +add_custom_command(TARGET hello PRE_LINK + COMMENT "pre-link: $<1:genex>" + COMMAND "${CMAKE_COMMAND}" -E echo "$") +add_custom_command(TARGET hello POST_BUILD + COMMENT "post-build: $<1:genex>" + COMMAND "${CMAKE_COMMAND}" -E echo "$") diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index a0e59ee66d..cbf7f264df 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -389,6 +389,21 @@ function (run_ChangeBuildType) endfunction() run_ChangeBuildType() +function (run_CustomCommandTargetComments) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandTargetComments-build) + run_cmake(CustomCommandTargetComments) + unset(RunCMake_TEST_OPTIONS) + run_ninja("${RunCMake_TEST_BINARY_DIR}" ${maybe_w_dupbuild_err}) + if (NOT ninja_stdout MATCHES [[pre-build: genex; pre-link: genex; Linking C executable hello(\.exe)?; post-build: genex]]) + string(REPLACE "\n" "\n " ninja_stdout "${ninja_stdout}") + message(SEND_ERROR + "Custom command comments are not part of the description:\n" + " ${ninja_stdout}" + ) + endif () +endfunction() +run_CustomCommandTargetComments() + function(run_QtAutoMocSkipPch) set(QtX Qt${CMake_TEST_Qt_version}) if(CMake_TEST_${QtX}Core_Version VERSION_GREATER_EQUAL 5.15.0)