summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorGergely Meszaros <gergely.meszaros@intel.com>2024-09-17 08:29:23 (GMT)
committerGergely Meszaros <gergely.meszaros@intel.com>2024-09-23 09:17:19 (GMT)
commite3895f4a8bcce3d9caae7d0e5559e6f057725fad (patch)
tree9d481f4c26ccea1dc2da18032753e04db616a5d4 /Source
parent4185dfbe1b903f8290617cdfe14acd0881405890 (diff)
downloadCMake-e3895f4a8bcce3d9caae7d0e5559e6f057725fad.zip
CMake-e3895f4a8bcce3d9caae7d0e5559e6f057725fad.tar.gz
CMake-e3895f4a8bcce3d9caae7d0e5559e6f057725fad.tar.bz2
Linking: Preserve nested LINKER: prefixes as written
Previously LINKER:,-Xlinker and -Wl, options nested inside LINKER: prefixes would be transformed to separate prefixed options. This is confusing and undocumented behavior, instead preserve these as written. Fixes: #26298
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGeneratorTarget_Options.cxx46
1 files changed, 31 insertions, 15 deletions
diff --git a/Source/cmGeneratorTarget_Options.cxx b/Source/cmGeneratorTarget_Options.cxx
index df22b90..d8b3eb3 100644
--- a/Source/cmGeneratorTarget_Options.cxx
+++ b/Source/cmGeneratorTarget_Options.cxx
@@ -7,6 +7,7 @@
#include "cmConfigure.h"
#include <algorithm>
+#include <iterator>
#include <map>
#include <memory>
#include <string>
@@ -91,10 +92,16 @@ void processOptions(cmGeneratorTarget const* tgt,
}
}
+enum class NestedLinkerFlags
+{
+ PreserveAsSpelled,
+ Normalize,
+};
+
std::vector<BT<std::string>> wrapOptions(
std::vector<std::string>& options, const cmListFileBacktrace& bt,
const std::vector<std::string>& wrapperFlag, const std::string& wrapperSep,
- bool concatFlagAndArgs)
+ bool concatFlagAndArgs, NestedLinkerFlags nestedLinkerFlags)
{
std::vector<BT<std::string>> result;
@@ -148,6 +155,11 @@ std::vector<BT<std::string>> wrapOptions(
}
};
+ if (nestedLinkerFlags == NestedLinkerFlags::PreserveAsSpelled) {
+ insertWrapped(options);
+ return result;
+ }
+
for (std::vector<std::string>::size_type index = 0; index < options.size();
index++) {
if (cmHasLiteralPrefix(options[index], "LINKER:")) {
@@ -488,8 +500,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
// host link options must be wrapped
std::vector<std::string> options;
cmSystemTools::ParseUnixCommandLine(it->Value.c_str(), options);
- auto hostOptions = wrapOptions(options, it->Backtrace, wrapperFlag,
- wrapperSep, concatFlagAndArgs);
+ auto hostOptions =
+ wrapOptions(options, it->Backtrace, wrapperFlag, wrapperSep,
+ concatFlagAndArgs, NestedLinkerFlags::Normalize);
it = result.erase(it);
// some compilers (like gcc 4.8 or Intel 19.0 or XLC 16) do not respect
// C++11 standard: 'std::vector::insert()' do not returns an iterator,
@@ -538,12 +551,11 @@ std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper(
const std::string SHELL{ "SHELL:" };
const std::string LINKER_SHELL = LINKER + SHELL;
- std::vector<BT<std::string>>::iterator entry;
- while ((entry = std::find_if(result.begin(), result.end(),
- [&LINKER](BT<std::string> const& item) -> bool {
- return item.Value.compare(0, LINKER.length(),
- LINKER) == 0;
- })) != result.end()) {
+ for (auto entry = result.begin(); entry != result.end(); ++entry) {
+ if (entry->Value.compare(0, LINKER.length(), LINKER) != 0) {
+ continue;
+ }
+
std::string value = std::move(entry->Value);
cmListFileBacktrace bt = std::move(entry->Backtrace);
entry = result.erase(entry);
@@ -573,15 +585,19 @@ std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper(
return result;
}
- std::vector<BT<std::string>> options = wrapOptions(
- linkerOptions, bt, wrapperFlag, wrapperSep, concatFlagAndArgs);
+ // Very old versions of the C++ standard library return void for insert, so
+ // can't use it to get the new iterator
+ const auto index = entry - result.begin();
+ std::vector<BT<std::string>> options =
+ wrapOptions(linkerOptions, bt, wrapperFlag, wrapperSep,
+ concatFlagAndArgs, NestedLinkerFlags::PreserveAsSpelled);
if (joinItems) {
- result.insert(entry,
- cmJoin(cmRange<decltype(options.cbegin())>(
- options.cbegin(), options.cend()),
- " "_s));
+ result.insert(
+ entry, cmJoin(cmMakeRange(options.begin(), options.end()), " "_s));
+ entry = std::next(result.begin(), index);
} else {
result.insert(entry, options.begin(), options.end());
+ entry = std::next(result.begin(), index + options.size() - 1);
}
}
return result;