diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 51ad99389895b19359796729fae463a935bd6f0c..081cc41fc37ed14a1a547e7e89ba9916a1ae22c1 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -407,7 +407,8 @@ void cmLocalNinjaGenerator::AppendCustomCommandDeps( } std::string cmLocalNinjaGenerator::WriteCommandScript( - std::vector<std::string> const& cmdLines, std::string const& customStep, + std::vector<std::string> const& cmdLines, std::string const& outputConfig, + std::string const& commandConfig, std::string const& customStep, cmGeneratorTarget const* target) const { std::string scriptPath; @@ -416,9 +417,13 @@ std::string cmLocalNinjaGenerator::WriteCommandScript( } else { scriptPath = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles"); } + scriptPath += this->GetGlobalNinjaGenerator()->ConfigDirectory(outputConfig); cmSystemTools::MakeDirectory(scriptPath); scriptPath += '/'; scriptPath += customStep; + if (this->GlobalGenerator->IsMultiConfig()) { + scriptPath += cmStrCat('-', commandConfig); + } #ifdef _WIN32 scriptPath += ".bat"; #else @@ -461,7 +466,8 @@ std::string cmLocalNinjaGenerator::WriteCommandScript( } std::string cmLocalNinjaGenerator::BuildCommandLine( - std::vector<std::string> const& cmdLines, std::string const& customStep, + std::vector<std::string> const& cmdLines, std::string const& outputConfig, + std::string const& commandConfig, std::string const& customStep, cmGeneratorTarget const* target) const { // If we have no commands but we need to build a command anyway, use noop. @@ -480,8 +486,8 @@ std::string cmLocalNinjaGenerator::BuildCommandLine( cmdLinesTotal += cmd.length() + 6; } if (cmdLinesTotal > cmSystemTools::CalculateCommandLineLengthLimit() / 2) { - std::string const scriptPath = - this->WriteCommandScript(cmdLines, customStep, target); + std::string const scriptPath = this->WriteCommandScript( + cmdLines, outputConfig, commandConfig, customStep, target); std::string cmd #ifndef _WIN32 = "/bin/sh " @@ -694,7 +700,8 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( } gg->WriteCustomCommandBuild( - this->BuildCommandLine(cmdLines, customStep), + 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, diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index 5b850f3d09fe125f5d6ac67ff6024546a54f59f3..0734c5cad609f1324e8d7674288b019c93254fba 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -60,7 +60,8 @@ public: } std::string BuildCommandLine( - std::vector<std::string> const& cmdLines, + std::vector<std::string> const& cmdLines, std::string const& outputConfig, + std::string const& commandConfig, std::string const& customStep = std::string(), cmGeneratorTarget const* target = nullptr) const; @@ -119,6 +120,8 @@ private: std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg); std::string WriteCommandScript(std::vector<std::string> const& cmdLines, + std::string const& outputConfig, + std::string const& commandConfig, std::string const& customStep, cmGeneratorTarget const* target) const; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 49e5e4cc65f9111f6c99b61440b0d6ac3e9dc884..1597d2c19e34ed47cc5b3b9b7b0dedf936526c41 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -287,7 +287,8 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule( // If there is no ranlib the command will be ":". Skip it. cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands()); - rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(linkCmds, config, config); // Write the linker rule with response file if needed. rule.Comment = @@ -310,7 +311,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules( cmNinjaRule rule(this->LanguageLinkerCudaDeviceRule(config)); rule.Command = this->GetLocalGenerator()->BuildCommandLine( { cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_DEVICE_LINKER"), - " -arch=$ARCH $REGISTER -o=$out $in") }); + " -arch=$ARCH $REGISTER -o=$out $in") }, + config, config); rule.Comment = "Rule for CUDA device linking."; rule.Description = "Linking CUDA $out"; this->GetGlobalGenerator()->AddRule(rule); @@ -336,7 +338,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules( compileCmd, vars); rule.Name = this->LanguageLinkerCudaDeviceCompileRule(config); - rule.Command = this->GetLocalGenerator()->BuildCommandLine({ compileCmd }); + rule.Command = this->GetLocalGenerator()->BuildCommandLine({ compileCmd }, + config, config); rule.Comment = "Rule for compiling CUDA device stubs."; rule.Description = "Compiling CUDA device stub $out"; this->GetGlobalGenerator()->AddRule(rule); @@ -345,7 +348,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules( rule.Command = this->GetLocalGenerator()->BuildCommandLine( { cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_FATBINARY"), " -64 -cmdline=--compile-only -compress-all -link " - "--embedded-fatbin=$out $PROFILES") }); + "--embedded-fatbin=$out $PROFILES") }, + config, config); rule.Comment = "Rule for CUDA fatbinaries."; rule.Description = "Creating fatbinary $out"; this->GetGlobalGenerator()->AddRule(rule); @@ -475,7 +479,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, linkCmds.insert(linkCmds.begin(), "$PRE_LINK"); linkCmds.emplace_back("$POST_BUILD"); - rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(linkCmds, config, config); // Write the linker rule with response file if needed. rule.Comment = @@ -500,7 +505,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, std::vector<std::string> cmd; cmd.push_back(cmakeCommand + " -E cmake_symlink_executable $in $out"); cmd.emplace_back("$POST_BUILD"); - rule.Command = this->GetLocalGenerator()->BuildCommandLine(cmd); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(cmd, config, config); } rule.Description = "Creating executable symlink $out"; rule.Comment = "Rule for creating executable symlink."; @@ -512,7 +518,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, cmd.push_back(cmakeCommand + " -E cmake_symlink_library $in $SONAME $out"); cmd.emplace_back("$POST_BUILD"); - rule.Command = this->GetLocalGenerator()->BuildCommandLine(cmd); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(cmd, config, config); } rule.Description = "Creating library symlink $out"; rule.Comment = "Rule for creating library symlink."; @@ -1310,10 +1317,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( preLinkCmdLines.push_back("cd " + homeOutDir); } - vars["PRE_LINK"] = localGen.BuildCommandLine(preLinkCmdLines, "pre-link", - this->GeneratorTarget); - std::string postBuildCmdLine = localGen.BuildCommandLine( - postBuildCmdLines, "post-build", this->GeneratorTarget); + vars["PRE_LINK"] = localGen.BuildCommandLine( + preLinkCmdLines, config, fileConfig, "pre-link", this->GeneratorTarget); + std::string postBuildCmdLine = + localGen.BuildCommandLine(postBuildCmdLines, config, fileConfig, + "post-build", this->GeneratorTarget); cmNinjaVars symlinkVars; bool const symlinkNeeded = diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 672b5797ed4943049637c2f59101c344247385e0..b4838d66795d071c0957868036e7bc2b556bd2be 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -537,7 +537,8 @@ cmNinjaRule GetScanRule( cmRulePlaceholderExpander::RuleVariables const& vars, const std::string& responseFlag, const std::string& flags, cmRulePlaceholderExpander* const rulePlaceholderExpander, - cmLocalNinjaGenerator* generator, std::vector<std::string> scanCmds) + cmLocalNinjaGenerator* generator, std::vector<std::string> scanCmds, + const std::string& outputConfig) { cmNinjaRule rule(ruleName); // Scanning always uses a depfile for preprocessor dependencies. @@ -578,7 +579,8 @@ cmNinjaRule GetScanRule( for (std::string& scanCmd : scanCmds) { rulePlaceholderExpander->ExpandRuleVariables(generator, scanCmd, scanVars); } - rule.Command = generator->BuildCommandLine(scanCmds); + rule.Command = + generator->BuildCommandLine(scanCmds, outputConfig, outputConfig); return rule; } @@ -670,7 +672,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, auto scanRule = GetScanRule( scanRuleName, vars, responseFlag, flags, rulePlaceholderExpander.get(), - this->GetLocalGenerator(), std::move(scanCommands)); + this->GetLocalGenerator(), std::move(scanCommands), config); scanRule.Comment = cmStrCat("Rule for generating ", lang, " dependencies."); @@ -700,7 +702,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, auto scanRule = GetScanRule( scanRuleName, vars, "", flags, rulePlaceholderExpander.get(), - this->GetLocalGenerator(), std::move(scanCommands)); + this->GetLocalGenerator(), std::move(scanCommands), config); // Write the rule for generating dependencies for the given language. scanRule.Comment = cmStrCat("Rule for generating ", lang, @@ -732,7 +734,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, ddModmapArg, " --dd=$out @", rule.RspFile); ddCmds.emplace_back(std::move(ccmd)); } - rule.Command = this->GetLocalGenerator()->BuildCommandLine(ddCmds); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(ddCmds, config, config); } rule.Comment = cmStrCat("Rule to generate ninja dyndep files for ", lang, '.'); @@ -928,7 +931,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, vars); } - rule.Command = this->GetLocalGenerator()->BuildCommandLine(compileCmds); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(compileCmds, config, config); // Write the rule for compiling file of the given language. rule.Comment = cmStrCat("Rule for compiling ", lang, " files."); @@ -1246,7 +1250,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( this->ExportObjectCompileCommand( language, sourceFileName, objectDir, objectFileName, objectFileDir, - vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]); + vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"], config); objBuild.Outputs.push_back(objectFileName); if (firstForConfig) { @@ -1617,7 +1621,8 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand( std::string const& language, std::string const& sourceFileName, std::string const& objectDir, std::string const& objectFileName, std::string const& objectFileDir, std::string const& flags, - std::string const& defines, std::string const& includes) + std::string const& defines, std::string const& includes, + std::string const& outputConfig) { if (!this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS")) { return; @@ -1679,8 +1684,8 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand( compileObjectVars); } - std::string cmdLine = - this->GetLocalGenerator()->BuildCommandLine(compileCmds); + std::string cmdLine = this->GetLocalGenerator()->BuildCommandLine( + compileCmds, outputConfig, outputConfig); this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName); } diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 79dc6227e78b9a478a3facc4d168918ec54d6168..3a28cef94c9e734a875babdd9d12dcad21886d06 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -162,7 +162,8 @@ protected: std::string const& language, std::string const& sourceFileName, std::string const& objectDir, std::string const& objectFileName, std::string const& objectFileDir, std::string const& flags, - std::string const& defines, std::string const& includes); + std::string const& defines, std::string const& includes, + std::string const& outputConfig); void AdditionalCleanFiles(const std::string& config); diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 92c5b521ba6e59570bcf8a6ee934d3a13823dbba..7a04c470bcd6f7ecedb23c1b62a9b4e30cd970dd 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -139,8 +139,8 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( gg->WriteBuild(this->GetCommonFileStream(), phonyBuild); } } else { - std::string command = - lg->BuildCommandLine(commands, "utility", this->GeneratorTarget); + std::string command = lg->BuildCommandLine( + commands, config, fileConfig, "utility", this->GeneratorTarget); std::string desc; cmProp echoStr = genTarget->GetProperty("EchoString"); if (echoStr) { diff --git a/Tests/RunCMake/NinjaMultiConfig/LongCommandLine-release-config-build-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/LongCommandLine-release-config-build-stdout.txt new file mode 100644 index 0000000000000000000000000000000000000000..628b6bc3356744f30638135bb714761476ab8444 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/LongCommandLine-release-config-build-stdout.txt @@ -0,0 +1,2 @@ + +Post-build Debug Release \.*$ diff --git a/Tests/RunCMake/NinjaMultiConfig/LongCommandLine.cmake b/Tests/RunCMake/NinjaMultiConfig/LongCommandLine.cmake index 00aa896af2ba992eccdd76600f945981fa1ca80c..de528be4665c5196a8f8012e86e00eaff0cfb244 100644 --- a/Tests/RunCMake/NinjaMultiConfig/LongCommandLine.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/LongCommandLine.cmake @@ -14,3 +14,10 @@ add_custom_target( ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gen.txt" ) + +add_executable(exe main.c) + +add_custom_command( + TARGET exe POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "Post-build $<CONFIG> $<COMMAND_CONFIG:$<CONFIG>> ${very_long}" + ) diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake index aa427391ea93e7e13977fbffd2afd0b5504d4250..e7acbc2845cb04700676486d63eef35226a28e47 100644 --- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake @@ -198,8 +198,11 @@ run_cmake_build(PostBuild release Release Exe) run_cmake_build(PostBuild debug-in-release-graph Release Exe:Debug) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LongCommandLine-build) +set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(LongCommandLine) +unset(RunCMake_TEST_OPTIONS) run_cmake_build(LongCommandLine release Release custom) +run_cmake_build(LongCommandLine release-config Release exe:Debug) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Framework-build) set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")