summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/cmCoreTryCompile.cxx16
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx5
-rw-r--r--Source/cmGeneratorTarget.cxx69
-rw-r--r--Source/cmGeneratorTarget.h7
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx13
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx3
-rw-r--r--Source/cmLocalGenerator.cxx45
-rw-r--r--Source/cmLocalGenerator.h3
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx21
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx3
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx3
-rw-r--r--Source/cmMakefileTargetGenerator.cxx2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx8
-rw-r--r--Source/cmRulePlaceholderExpander.cxx25
-rw-r--r--Source/cmRulePlaceholderExpander.h1
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx10
17 files changed, 221 insertions, 14 deletions
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 7e19812..69d5ffc 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -14,6 +14,7 @@
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
+#include "cmsys/RegularExpression.hxx"
#include "cmArgumentParser.h"
#include "cmConfigureLog.h"
@@ -83,6 +84,7 @@ std::string const kCMAKE_HIP_PLATFORM = "CMAKE_HIP_PLATFORM";
std::string const kCMAKE_HIP_RUNTIME_LIBRARY = "CMAKE_HIP_RUNTIME_LIBRARY";
std::string const kCMAKE_ISPC_INSTRUCTION_SETS = "CMAKE_ISPC_INSTRUCTION_SETS";
std::string const kCMAKE_ISPC_HEADER_SUFFIX = "CMAKE_ISPC_HEADER_SUFFIX";
+std::string const kCMAKE_LINKER_TYPE = "CMAKE_LINKER_TYPE";
std::string const kCMAKE_LINK_SEARCH_END_STATIC =
"CMAKE_LINK_SEARCH_END_STATIC";
std::string const kCMAKE_LINK_SEARCH_START_STATIC =
@@ -1114,6 +1116,20 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
vars.insert(varList.begin(), varList.end());
}
+ if (this->Makefile->GetDefinition(kCMAKE_LINKER_TYPE)) {
+ // propagate various variables to support linker selection
+ vars.insert(kCMAKE_LINKER_TYPE);
+ auto defs = this->Makefile->GetDefinitions();
+ cmsys::RegularExpression linkerTypeDef{
+ "^CMAKE_[A-Za-z]+_USING_LINKER_"
+ };
+ for (auto const& def : defs) {
+ if (linkerTypeDef.find(def)) {
+ vars.insert(def);
+ }
+ }
+ }
+
if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0083) ==
cmPolicies::NEW) {
// To ensure full support of PIE, propagate cache variables
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index d51dbd0..4e46df7 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -175,14 +175,15 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkExpression() const
cm::string_view property(this->Top()->Property);
return property == "LINK_DIRECTORIES"_s || property == "LINK_OPTIONS"_s ||
- property == "LINK_DEPENDS"_s || property == "LINK_LIBRARY_OVERRIDE"_s;
+ property == "LINK_DEPENDS"_s || property == "LINK_LIBRARY_OVERRIDE"_s ||
+ property == "LINKER_TYPE"_s;
}
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkOptionsExpression() const
{
cm::string_view property(this->Top()->Property);
- return property == "LINK_OPTIONS"_s;
+ return property == "LINK_OPTIONS"_s || property == "LINKER_TYPE"_s;
}
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkerLauncher() const
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 2ea18bd..f7a6a4e 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -868,6 +868,31 @@ cmValue cmGeneratorTarget::GetFeature(const std::string& feature,
return this->LocalGenerator->GetFeature(feature, config);
}
+std::string cmGeneratorTarget::GetLinkerTypeProperty(
+ std::string const& lang, std::string const& config) const
+{
+ std::string propName{ "LINKER_TYPE" };
+ auto linkerType = this->GetProperty(propName);
+ if (!linkerType.IsEmpty()) {
+ cmGeneratorExpressionDAGChecker dagChecker(this, propName, nullptr,
+ nullptr);
+ auto ltype =
+ cmGeneratorExpression::Evaluate(*linkerType, this->GetLocalGenerator(),
+ config, this, &dagChecker, this, lang);
+ if (this->IsDeviceLink()) {
+ cmList list{ ltype };
+ const auto DL_BEGIN = "<DEVICE_LINK>"_s;
+ const auto DL_END = "</DEVICE_LINK>"_s;
+ cm::erase_if(list, [&](const std::string& item) {
+ return item == DL_BEGIN || item == DL_END;
+ });
+ return list.to_string();
+ }
+ return ltype;
+ }
+ return std::string{};
+}
+
const char* cmGeneratorTarget::GetLinkPIEProperty(
const std::string& config) const
{
@@ -5515,6 +5540,50 @@ std::string cmGeneratorTarget::GetLinkerLanguage(
return this->GetLinkClosure(config)->LinkerLanguage;
}
+std::string cmGeneratorTarget::GetLinkerTool(const std::string& config) const
+{
+ return this->GetLinkerTool(this->GetLinkerLanguage(config), config);
+}
+
+std::string cmGeneratorTarget::GetLinkerTool(const std::string& lang,
+ const std::string& config) const
+{
+ auto usingLinker =
+ cmStrCat("CMAKE_", lang, "_USING_", this->IsDeviceLink() ? "DEVICE_" : "",
+ "LINKER_");
+ auto format = this->Makefile->GetDefinition(cmStrCat(usingLinker, "MODE"));
+ if (!format || format != "TOOL"_s) {
+ return this->Makefile->GetDefinition("CMAKE_LINKER");
+ }
+
+ auto linkerType = this->GetLinkerTypeProperty(lang, config);
+ if (linkerType.empty()) {
+ linkerType = "DEFAULT";
+ }
+ usingLinker = cmStrCat(usingLinker, linkerType);
+ auto linkerTool = this->Makefile->GetDefinition(usingLinker);
+
+ if (!linkerTool) {
+ if (this->GetGlobalGenerator()->IsVisualStudio() &&
+ linkerType == "DEFAULT"_s) {
+ return std::string{};
+ }
+
+ // fall-back to generic definition
+ linkerTool = this->Makefile->GetDefinition("CMAKE_LINKER");
+
+ if (linkerType != "DEFAULT"_s) {
+ this->LocalGenerator->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("LINKER_TYPE '", linkerType,
+ "' is unknown. Did you forgot to define '", usingLinker,
+ "' variable?"));
+ }
+ }
+
+ return linkerTool;
+}
+
std::string cmGeneratorTarget::GetPDBOutputName(
const std::string& config) const
{
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index bf49914..a32c5d8 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -205,6 +205,9 @@ public:
cmValue GetFeature(const std::string& feature,
const std::string& config) const;
+ std::string GetLinkerTypeProperty(std::string const& lang,
+ std::string const& config) const;
+
const char* GetLinkPIEProperty(const std::string& config) const;
bool IsIPOEnabled(std::string const& lang, std::string const& config) const;
@@ -788,6 +791,10 @@ public:
//! Return the preferred linker language for this target
std::string GetLinkerLanguage(const std::string& config) const;
+ //! Return the preferred linker tool for this target
+ std::string GetLinkerTool(const std::string& config) const;
+ std::string GetLinkerTool(const std::string& lang,
+ const std::string& config) const;
/** Does this target have a GNU implib to convert to MS format? */
bool HasImplibGNUtoMS(std::string const& config) const;
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 95e2187..940f49d 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -116,6 +116,19 @@ void cmGhsMultiTargetGenerator::Generate()
void cmGhsMultiTargetGenerator::GenerateTarget()
{
+ if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE &&
+ !this->GeneratorTarget
+ ->GetLinkerTypeProperty(
+ this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
+ this->ConfigName)
+ .empty()) {
+ // Green Hill MULTI does not support this feature.
+ cmSystemTools::Message(
+ cmStrCat("'LINKER_TYPE' property, specified on target '",
+ this->GeneratorTarget->GetName(),
+ "', is not supported by this generator."));
+ }
+
// Open the target file in copy-if-different mode.
std::string fproj =
cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), '/',
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 5076e6c..9f6786e 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -2500,6 +2500,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->CurrentLocalGenerator->GetStaticLibraryFlags(
extraLinkOptions, configName, llang, gtgt);
} else {
+ this->CurrentLocalGenerator->AppendLinkerTypeFlags(extraLinkOptions, gtgt,
+ configName, llang);
+
cmValue targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
this->CurrentLocalGenerator->AppendFlags(extraLinkOptions,
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index fe8d502..76e36ab 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -82,7 +82,6 @@ static auto ruleReplaceVars = { "CMAKE_${LANG}_COMPILER",
"CMAKE_CURRENT_SOURCE_DIR",
"CMAKE_CURRENT_BINARY_DIR",
"CMAKE_RANLIB",
- "CMAKE_LINKER",
"CMAKE_MT",
"CMAKE_TAPI",
"CMAKE_CUDA_HOST_COMPILER",
@@ -1604,6 +1603,7 @@ void cmLocalGenerator::GetTargetFlags(
}
std::string extraLinkFlags;
+ this->AppendLinkerTypeFlags(extraLinkFlags, target, config, linkLanguage);
this->AppendPositionIndependentLinkerFlags(extraLinkFlags, target, config,
linkLanguage);
this->AppendIPOLinkerFlags(extraLinkFlags, target, config, linkLanguage);
@@ -3200,6 +3200,49 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
}
}
+void cmLocalGenerator::AppendLinkerTypeFlags(std::string& flags,
+ cmGeneratorTarget* target,
+ const std::string& config,
+ const std::string& linkLanguage)
+{
+ switch (target->GetType()) {
+ case cmStateEnums::EXECUTABLE:
+ case cmStateEnums::SHARED_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
+ break;
+ default:
+ return;
+ }
+
+ auto usingLinker =
+ cmStrCat("CMAKE_", linkLanguage, "_USING_",
+ target->IsDeviceLink() ? "DEVICE_" : "", "LINKER_");
+
+ auto format = this->Makefile->GetDefinition(cmStrCat(usingLinker, "MODE"));
+ if (format && format != "FLAG"_s) {
+ return;
+ }
+
+ auto linkerType = target->GetLinkerTypeProperty(linkLanguage, config);
+ if (linkerType.empty()) {
+ linkerType = "DEFAULT";
+ }
+ usingLinker = cmStrCat(usingLinker, linkerType);
+ auto linkerTypeFlags = this->Makefile->GetDefinition(usingLinker);
+ if (linkerTypeFlags) {
+ if (!linkerTypeFlags.IsEmpty()) {
+ auto linkerFlags = cmExpandListWithBacktrace(linkerTypeFlags);
+ target->ResolveLinkerWrapper(linkerFlags, linkLanguage);
+ this->AppendFlags(flags, linkerFlags);
+ }
+ } else if (linkerType != "DEFAULT"_s) {
+ this->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("LINKER_TYPE '", linkerType,
+ "' is unknown. Did you forgot to define '",
+ usingLinker, "' variable?"));
+ }
+}
+
void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
cmGeneratorTarget* target,
const std::string& config,
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index a920cfe..a61def9 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -177,6 +177,9 @@ public:
void AddPchDependencies(cmGeneratorTarget* target);
void AddUnityBuild(cmGeneratorTarget* target);
virtual void AddXCConfigSources(cmGeneratorTarget* /* target */) {}
+ void AppendLinkerTypeFlags(std::string& flags, cmGeneratorTarget* target,
+ const std::string& config,
+ const std::string& linkLanguage);
void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 7b02c56..3f3779a 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -32,6 +32,7 @@
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmSourceFile.h"
@@ -1085,6 +1086,16 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
cmComputeLinkInformation& cli = *pcli;
std::string linkLanguage = cli.GetLinkLanguage();
+ if (!target->GetLinkerTypeProperty(linkLanguage, configName).empty()) {
+ // Visual Studio 10 or upper is required for this feature
+ this->GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("'LINKER_TYPE' property, specified on target '",
+ target->GetName(),
+ "', is not supported by this generator."),
+ target->GetBacktrace());
+ }
+
// Compute the variable name to lookup standard libraries for this
// language.
std::string standardLibsVar =
@@ -1161,6 +1172,16 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
cmComputeLinkInformation& cli = *pcli;
std::string linkLanguage = cli.GetLinkLanguage();
+ if (!target->GetLinkerTypeProperty(linkLanguage, configName).empty()) {
+ // Visual Studio 10 or upper is required for this feature
+ this->GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("'LINKER_TYPE' property, specified on target '",
+ target->GetName(),
+ "', is not supported by this generator."),
+ target->GetBacktrace());
+ }
+
bool isWin32Executable = target->IsWin32Executable(configName);
// Compute the variable name to lookup standard libraries for this
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 4a2b9e8..96a0d5c 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -344,6 +344,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
return;
}
+ auto linker = this->GeneratorTarget->GetLinkerTool(this->GetConfigName());
+
// Build list of dependencies.
std::vector<std::string> depends;
this->AppendLinkDepends(depends, linkLanguage);
@@ -533,6 +535,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.CMTargetType =
cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
vars.Language = linkLanguage.c_str();
+ vars.Linker = linker.c_str();
vars.AIXExports = aixExports.c_str();
vars.Objects = buildObjs.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index fc3caa1..0429155 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -441,6 +441,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
return;
}
+ auto linker = this->GeneratorTarget->GetLinkerTool(this->GetConfigName());
+
// Build list of dependencies.
std::vector<std::string> depends;
this->AppendLinkDepends(depends, linkLanguage);
@@ -766,6 +768,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
vars.CMTargetType =
cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
vars.Language = linkLanguage.c_str();
+ vars.Linker = linker.c_str();
vars.AIXExports = aixExports.c_str();
vars.Objects = buildObjs.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 0c2a719..343f6b8 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -153,6 +153,8 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
this->LocalGenerator->AppendCompileOptions(flags, opts);
this->LocalGenerator->SetLinkScriptShell(false);
+ this->LocalGenerator->AppendLinkerTypeFlags(
+ flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
this->LocalGenerator->AppendPositionIndependentLinkerFlags(
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
this->LocalGenerator->AppendDependencyInfoLinkerFlags(
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 48c30b6..5e7bb6e 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -294,6 +294,9 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule(
.c_str();
vars.Language = "CUDA";
+ std::string linker =
+ this->GetGeneratorTarget()->GetLinkerTool("CUDA", config);
+ vars.Linker = linker.c_str();
// build response file name
std::string responseFlag = this->GetMakefile()->GetSafeDefinition(
@@ -400,6 +403,9 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules(
vars.Fatbinary = "$FATBIN";
vars.RegisterFile = "$REGISTER";
vars.LinkFlags = "$LINK_FLAGS";
+ std::string linker =
+ this->GetGeneratorTarget()->GetLinkerTool("CUDA", config);
+ vars.Linker = linker.c_str();
std::string flags = this->GetFlags("CUDA", config);
vars.Flags = flags.c_str();
@@ -441,6 +447,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType = cmState::GetTargetTypeName(targetType).c_str();
+ std::string linker = this->GetGeneratorTarget()->GetLinkerTool(config);
+ vars.Linker = linker.c_str();
std::string lang = this->TargetLinkLanguage(config);
vars.Language = lang.c_str();
vars.AIXExports = "$AIX_EXPORTS";
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 638bb42..a8c81d0 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -27,6 +27,19 @@ std::string cmRulePlaceholderExpander::ExpandVariable(
return this->ReplaceValues->LinkFlags;
}
}
+ if (this->ReplaceValues->Linker) {
+ if (variable == "CMAKE_LINKER") {
+ auto result = this->OutputConverter->ConvertToOutputForExisting(
+ this->ReplaceValues->Linker);
+ if (this->ReplaceValues->Launcher) {
+ // Add launcher as part of expansion so that it always appears
+ // immediately before the command itself, regardless of whether the
+ // overall rule template contains other content at the front.
+ result = cmStrCat(this->ReplaceValues->Launcher, " ", result);
+ }
+ return result;
+ }
+ }
if (this->ReplaceValues->Manifests) {
if (variable == "MANIFESTS") {
return this->ReplaceValues->Manifests;
@@ -325,17 +338,7 @@ std::string cmRulePlaceholderExpander::ExpandVariable(
auto mapIt = this->VariableMappings.find(variable);
if (mapIt != this->VariableMappings.end()) {
if (variable.find("_FLAG") == std::string::npos) {
- std::string ret =
- this->OutputConverter->ConvertToOutputForExisting(mapIt->second);
-
- if (this->ReplaceValues->Launcher && variable == "CMAKE_LINKER") {
- // Add launcher as part of expansion so that it always appears
- // immediately before the command itself, regardless of whether the
- // overall rule template contains other content at the front.
- ret = cmStrCat(this->ReplaceValues->Launcher, " ", ret);
- }
-
- return ret;
+ return this->OutputConverter->ConvertToOutputForExisting(mapIt->second);
}
return mapIt->second;
}
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index 5d1f199..225abd4 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -53,6 +53,7 @@ public:
const char* SONameFlag = nullptr;
const char* TargetSOName = nullptr;
const char* TargetInstallNameDir = nullptr;
+ const char* Linker = nullptr;
const char* LinkFlags = nullptr;
const char* Manifests = nullptr;
const char* LanguageCompileFlags = nullptr;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index abbf29e..d93f658 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -456,6 +456,7 @@ TargetProperty const StaticTargetProperties[] = {
{ "AUTORCC_EXECUTABLE"_s, IC::CanCompileSources },
// Linking properties
+ { "LINKER_TYPE"_s, IC::CanCompileSources },
{ "ENABLE_EXPORTS"_s, IC::TargetWithSymbolExports },
{ "LINK_LIBRARIES_ONLY_TARGETS"_s, IC::NormalNonImportedTarget },
{ "LINK_SEARCH_START_STATIC"_s, IC::CanCompileSources },
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index ce94fe1..84f808d 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2987,6 +2987,16 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
e1.WritePlatformConfigTag(
"IntDir", cond, R"($(Platform)\$(Configuration)\$(ProjectName)\)");
} else {
+ if (ttype == cmStateEnums::SHARED_LIBRARY ||
+ ttype == cmStateEnums::MODULE_LIBRARY ||
+ ttype == cmStateEnums::EXECUTABLE) {
+ auto linker = this->GeneratorTarget->GetLinkerTool(config);
+ if (!linker.empty()) {
+ ConvertToWindowsSlash(linker);
+ e1.WritePlatformConfigTag("LinkToolExe", cond, linker);
+ }
+ }
+
std::string intermediateDir = cmStrCat(
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget), '/',
config, '/');