From 3c685a578a44063bb027787426d2c8b7202a7979 Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Sat, 1 Jul 2023 14:20:15 +0200 Subject: LINK_OPTIONS: ensure correct dollar escaping Ensure correct escaping for Ninja and Makefile generators. Fixes: #25049 --- Source/cmGlobalGenerator.h | 2 ++ Source/cmGlobalNinjaGenerator.cxx | 12 ++++++------ Source/cmGlobalNinjaGenerator.h | 4 ++-- Source/cmLocalGenerator.cxx | 11 +++++++++++ Source/cmMakefileTargetGenerator.cxx | 6 ++++++ Source/cmNinjaNormalTargetGenerator.cxx | 4 ---- .../LINK_OPTIONS-dollar-option-check.cmake | 4 ++++ .../LINK_OPTIONS-dollar-option-result.txt | 1 + Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake | 4 ++++ Tests/RunCMake/target_link_options/RunCMakeTest.cmake | 2 +- 10 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-check.cmake create mode 100644 Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-result.txt diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index bc59514..735c4ba 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -637,6 +637,8 @@ public: }; StripCommandStyle GetStripCommandStyle(std::string const& strip); + virtual std::string& EncodeLiteral(std::string& lit) { return lit; } + protected: // for a project collect all its targets by following depend // information, and also collect all the targets diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index e405909..71084cc 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -181,14 +181,13 @@ std::string cmGlobalNinjaGenerator::EncodeRuleName(std::string const& name) return encoded; } -std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string& lit) +std::string cmGlobalNinjaGenerator::GetEncodedLiteral(const std::string& lit) { std::string result = lit; - EncodeLiteralInplace(result); - return result; + return this->EncodeLiteral(result); } -void cmGlobalNinjaGenerator::EncodeLiteralInplace(std::string& lit) +std::string& cmGlobalNinjaGenerator::EncodeLiteral(std::string& lit) { cmSystemTools::ReplaceString(lit, "$", "$$"); cmSystemTools::ReplaceString(lit, "\n", "$\n"); @@ -196,6 +195,7 @@ void cmGlobalNinjaGenerator::EncodeLiteralInplace(std::string& lit) cmSystemTools::ReplaceString(lit, cmStrCat('$', this->GetCMakeCFGIntDir()), this->GetCMakeCFGIntDir()); } + return lit; } std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path) @@ -207,7 +207,7 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path) else std::replace(result.begin(), result.end(), '/', '\\'); #endif - this->EncodeLiteralInplace(result); + this->EncodeLiteral(result); cmSystemTools::ReplaceString(result, " ", "$ "); cmSystemTools::ReplaceString(result, ":", "$:"); return result; @@ -394,7 +394,7 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild( #endif vars["COMMAND"] = std::move(cmd); } - vars["DESC"] = this->EncodeLiteral(description); + vars["DESC"] = this->GetEncodedLiteral(description); if (restat) { vars["restat"] = "1"; } diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 95d64e3..4b026eb 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -77,8 +77,8 @@ public: static void WriteDivider(std::ostream& os); static std::string EncodeRuleName(std::string const& name); - std::string EncodeLiteral(const std::string& lit); - void EncodeLiteralInplace(std::string& lit); + std::string& EncodeLiteral(std::string& lit) override; + std::string GetEncodedLiteral(const std::string& lit); std::string EncodePath(const std::string& path); std::unique_ptr CreateLinkLineComputer( diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 7ad4023..cf1eb96 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1431,11 +1431,14 @@ void cmLocalGenerator::GetDeviceLinkFlags( } this->AddVisibilityPresetFlags(linkFlags, target, "CUDA"); + this->GetGlobalGenerator()->EncodeLiteral(linkFlags); std::vector linkOpts; target->GetLinkOptions(linkOpts, config, "CUDA"); + this->SetLinkScriptShell(this->GetGlobalGenerator()->GetUseLinkScript()); // LINK_OPTIONS are escaped. this->AppendCompileOptions(linkFlags, linkOpts); + this->SetLinkScriptShell(false); } void cmLocalGenerator::GetTargetFlags( @@ -1501,13 +1504,17 @@ void cmLocalGenerator::GetTargetFlags( } if (!sharedLibFlags.empty()) { + this->GetGlobalGenerator()->EncodeLiteral(sharedLibFlags); linkFlags.emplace_back(std::move(sharedLibFlags)); } std::vector> linkOpts = target->GetLinkOptions(config, linkLanguage); + this->SetLinkScriptShell(this->GetGlobalGenerator()->GetUseLinkScript()); // LINK_OPTIONS are escaped. this->AppendCompileOptions(linkFlags, linkOpts); + this->SetLinkScriptShell(false); + if (pcli) { this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, frameworkPath, linkPath); @@ -1581,13 +1588,16 @@ void cmLocalGenerator::GetTargetFlags( } if (!exeFlags.empty()) { + this->GetGlobalGenerator()->EncodeLiteral(exeFlags); linkFlags.emplace_back(std::move(exeFlags)); } std::vector> linkOpts = target->GetLinkOptions(config, linkLanguage); + this->SetLinkScriptShell(this->GetGlobalGenerator()->GetUseLinkScript()); // LINK_OPTIONS are escaped. this->AppendCompileOptions(linkFlags, linkOpts); + this->SetLinkScriptShell(false); } break; default: break; @@ -1603,6 +1613,7 @@ void cmLocalGenerator::GetTargetFlags( config); if (!extraLinkFlags.empty()) { + this->GetGlobalGenerator()->EncodeLiteral(extraLinkFlags); linkFlags.emplace_back(std::move(extraLinkFlags)); } } diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 1dd48b3..5e3bf61 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -126,8 +126,11 @@ void cmMakefileTargetGenerator::GetDeviceLinkFlags( std::vector linkOpts; this->GeneratorTarget->GetLinkOptions(linkOpts, this->GetConfigName(), linkLanguage); + this->LocalGenerator->SetLinkScriptShell( + this->GlobalGenerator->GetUseLinkScript()); // LINK_OPTIONS are escaped. this->LocalGenerator->AppendCompileOptions(linkFlags, linkOpts); + this->LocalGenerator->SetLinkScriptShell(false); } void cmMakefileTargetGenerator::GetTargetLinkFlags( @@ -144,8 +147,11 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags( std::vector opts; this->GeneratorTarget->GetLinkOptions(opts, this->GetConfigName(), linkLanguage); + this->LocalGenerator->SetLinkScriptShell( + this->GlobalGenerator->GetUseLinkScript()); // LINK_OPTIONS are escaped. this->LocalGenerator->AppendCompileOptions(flags, opts); + this->LocalGenerator->SetLinkScriptShell(false); this->LocalGenerator->AppendPositionIndependentLinkerFlags( flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 063ca6b..a5280fb 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -952,8 +952,6 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement( this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, vars); - vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]); - vars["MANIFESTS"] = this->GetManifests(config); vars["LINK_PATH"] = frameworkPath + linkPath; @@ -1271,8 +1269,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( vars["LINK_FLAGS"], this->GetGeneratorTarget(), this->TargetLinkLanguage(config)); - vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]); - vars["MANIFESTS"] = this->GetManifests(config); vars["AIX_EXPORTS"] = this->GetAIXExports(config); diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-check.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-check.cmake new file mode 100644 index 0000000..0f897fe --- /dev/null +++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-check.cmake @@ -0,0 +1,4 @@ + +if (NOT actual_stdout MATCHES "BADFLAG_\\$dollar") + set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_$dollar'.") +endif() diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-result.txt b/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-dollar-option-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake index bb04841..879151b 100644 --- a/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake +++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake @@ -53,3 +53,7 @@ target_link_options(LinkOptions_mod PRIVATE $<$:${pre}BADFLAG_RE # executable with generator expression add_executable(LinkOptions_exe LinkOptionsExe.c) target_link_options(LinkOptions_exe PRIVATE $<$:${pre}BADFLAG_RELEASE${obj}>) + +# executable with dollar character +add_executable(LinkOptions_dollar_exe LinkOptionsExe.c) +target_link_options(LinkOptions_dollar_exe PRIVATE "${pre}BADFLAG_$dollar${obj}") diff --git a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake index 1a29ecf..ff0c5a8 100644 --- a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake @@ -30,7 +30,7 @@ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel") run_cmake_target(LINK_OPTIONS shared LinkOptions_shared --config Release) run_cmake_target(LINK_OPTIONS mod LinkOptions_mod --config Release) run_cmake_target(LINK_OPTIONS exe LinkOptions_exe --config Release) - + run_cmake_target(LINK_OPTIONS dollar-option LinkOptions_dollar_exe --config Release) run_cmake(genex_LINK_LANGUAGE) -- cgit v0.12