diff options
author | Marc Chevrier <marc.chevrier@gmail.com> | 2018-04-30 16:56:25 (GMT) |
---|---|---|
committer | Marc Chevrier <marc.chevrier@gmail.com> | 2018-06-06 15:22:41 (GMT) |
commit | 66ea1a3795f76ce921bc48f82ff228bcceed4524 (patch) | |
tree | 48d060e55c547dc5d06fcccba7186bb5beb4fc13 /Source/cmGeneratorTarget.cxx | |
parent | c1f5a44b28047cde74e2fb10e8d68e314272f699 (diff) | |
download | CMake-66ea1a3795f76ce921bc48f82ff228bcceed4524.zip CMake-66ea1a3795f76ce921bc48f82ff228bcceed4524.tar.gz CMake-66ea1a3795f76ce921bc48f82ff228bcceed4524.tar.bz2 |
LINK_OPTIONS: Add support of "LINKER:" prefix
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 96 |
1 files changed, 95 insertions, 1 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index f5418a5..41e55a5 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -2861,7 +2861,8 @@ void cmGeneratorTarget::GetCompileDefinitions( cmDeleteAll(linkInterfaceCompileDefinitionsEntries); } -static void processLinkOptions( +namespace { +void processLinkOptions( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, std::vector<std::string>& options, @@ -2873,6 +2874,7 @@ static void processLinkOptions( config, debugOptions, "link options", language, OptionsParse::Shell); } +} void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result, const std::string& config, @@ -2912,6 +2914,98 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result, language); cmDeleteAll(linkInterfaceLinkOptionsEntries); + + // Last step: replace "LINKER:" prefixed elements by + // actual linker wrapper + const std::string wrapper(this->Makefile->GetSafeDefinition( + "CMAKE_" + language + "_LINKER_WRAPPER_FLAG")); + std::vector<std::string> wrapperFlag; + cmSystemTools::ExpandListArgument(wrapper, wrapperFlag); + const std::string wrapperSep(this->Makefile->GetSafeDefinition( + "CMAKE_" + language + "_LINKER_WRAPPER_FLAG_SEP")); + bool concatFlagAndArgs = true; + if (!wrapperFlag.empty() && wrapperFlag.back() == " ") { + concatFlagAndArgs = false; + wrapperFlag.pop_back(); + } + + const std::string LINKER{ "LINKER:" }; + const std::string SHELL{ "SHELL:" }; + const std::string LINKER_SHELL = LINKER + SHELL; + + std::vector<std::string>::iterator entry; + while ((entry = std::find_if(result.begin(), result.end(), + [&LINKER](const std::string& item) -> bool { + return item.compare(0, LINKER.length(), + LINKER) == 0; + })) != result.end()) { + std::vector<std::string> linkerOptions; + if (entry->compare(0, LINKER_SHELL.length(), LINKER_SHELL) == 0) { + cmSystemTools::ParseUnixCommandLine( + entry->c_str() + LINKER_SHELL.length(), linkerOptions); + } else { + linkerOptions = + cmSystemTools::tokenize(entry->substr(LINKER.length()), ","); + } + entry = result.erase(entry); + + if (linkerOptions.empty() || + (linkerOptions.size() == 1 && linkerOptions.front().empty())) { + continue; + } + + // for now, raise an error if prefix SHELL: is part of arguments + if (std::find_if(linkerOptions.begin(), linkerOptions.end(), + [&SHELL](const std::string& item) -> bool { + return item.find(SHELL) != std::string::npos; + }) != linkerOptions.end()) { + this->LocalGenerator->GetCMakeInstance()->IssueMessage( + cmake::FATAL_ERROR, + "'SHELL:' prefix is not supported as part of 'LINKER:' arguments.", + this->GetBacktrace()); + return; + } + + if (wrapperFlag.empty()) { + // nothing specified, insert elements as is + result.insert(entry, linkerOptions.begin(), linkerOptions.end()); + } else { + std::vector<std::string> options; + + if (!wrapperSep.empty()) { + if (concatFlagAndArgs) { + // insert flag elements except last one + options.insert(options.end(), wrapperFlag.begin(), + wrapperFlag.end() - 1); + // concatenate last flag element and all LINKER list values + // in one option + options.push_back(wrapperFlag.back() + + cmJoin(linkerOptions, wrapperSep)); + } else { + options.insert(options.end(), wrapperFlag.begin(), + wrapperFlag.end()); + // concatenate all LINKER list values in one option + options.push_back(cmJoin(linkerOptions, wrapperSep)); + } + } else { + // prefix each element of LINKER list with wrapper + if (concatFlagAndArgs) { + std::transform( + linkerOptions.begin(), linkerOptions.end(), linkerOptions.begin(), + [&wrapperFlag](const std::string& value) -> std::string { + return wrapperFlag.back() + value; + }); + } + for (const auto& value : linkerOptions) { + options.insert(options.end(), wrapperFlag.begin(), + concatFlagAndArgs ? wrapperFlag.end() - 1 + : wrapperFlag.end()); + options.push_back(value); + } + } + result.insert(entry, options.begin(), options.end()); + } + } } void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const |