summaryrefslogtreecommitdiffstats
path: root/Source/cmGeneratorTarget.cxx
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2018-04-30 16:56:25 (GMT)
committerMarc Chevrier <marc.chevrier@gmail.com>2018-06-06 15:22:41 (GMT)
commit66ea1a3795f76ce921bc48f82ff228bcceed4524 (patch)
tree48d060e55c547dc5d06fcccba7186bb5beb4fc13 /Source/cmGeneratorTarget.cxx
parentc1f5a44b28047cde74e2fb10e8d68e314272f699 (diff)
downloadCMake-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.cxx96
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