diff options
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
| -rw-r--r-- | Source/cmGeneratorTarget.cxx | 82 |
1 files changed, 75 insertions, 7 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 4b4d8b9..c9de3c3 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 { @@ -1808,32 +1833,31 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths( AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(), &dagChecker, linkInterfaceSourcesEntries, IncludeRuntimeInterface::No, LinkInterfaceFor::Usage); - std::vector<std::string>::size_type numFilesBefore = files.size(); bool contextDependentInterfaceSources = processSources( this, linkInterfaceSourcesEntries, files, uniqueSrcs, debugSources); // Collect TARGET_OBJECTS of direct object link-dependencies. bool contextDependentObjects = false; - std::vector<std::string>::size_type numFilesBefore2 = files.size(); if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) { EvaluatedTargetPropertyEntries linkObjectsEntries; AddObjectEntries(this, config, &dagChecker, linkObjectsEntries); contextDependentObjects = processSources(this, linkObjectsEntries, files, uniqueSrcs, debugSources); + // Note that for imported targets or multi-config generators supporting + // cross-config builds the paths to the object files must be per-config, + // so contextDependentObjects will be true here even if object libraries + // are specified without per-config generator expressions. } // Collect this target's file sets. - std::vector<std::string>::size_type numFilesBefore3 = files.size(); EvaluatedTargetPropertyEntries fileSetEntries; AddFileSetEntries(this, config, &dagChecker, fileSetEntries); bool contextDependentFileSets = processSources(this, fileSetEntries, files, uniqueSrcs, debugSources); // Determine if sources are context-dependent or not. - if (!contextDependentDirectSources && - !(contextDependentInterfaceSources && numFilesBefore < files.size()) && - !(contextDependentObjects && numFilesBefore2 < files.size()) && - !(contextDependentFileSets && numFilesBefore3 < files.size())) { + if (!contextDependentDirectSources && !contextDependentInterfaceSources && + !contextDependentObjects && !contextDependentFileSets) { this->SourcesAreContextDependent = Tribool::False; } else { this->SourcesAreContextDependent = Tribool::True; @@ -5515,6 +5539,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 { |
