| 531 | } |
| 532 | |
| 533 | void cmGeneratorTarget::ExpandLinkItems(std::string const& prop, |
| 534 | cmBTStringRange entries, |
| 535 | std::string const& config, |
| 536 | cmGeneratorTarget const* headTarget, |
| 537 | UseTo usage, LinkInterfaceField field, |
| 538 | cmLinkInterface& iface) const |
| 539 | { |
| 540 | if (entries.empty()) { |
| 541 | return; |
| 542 | } |
| 543 | // Keep this logic in sync with ComputeLinkImplementationLibraries. |
| 544 | cm::GenEx::Context context(this->LocalGenerator, config, |
| 545 | headTarget->LinkerLanguage); |
| 546 | cmGeneratorExpressionDAGChecker dagChecker{ |
| 547 | this, |
| 548 | prop, |
| 549 | nullptr, |
| 550 | nullptr, |
| 551 | context, |
| 552 | cmListFileBacktrace(), |
| 553 | cmGeneratorExpressionDAGChecker::ComputingLinkLibraries::Yes, |
| 554 | }; |
| 555 | // The $<LINK_ONLY> expression may be in a link interface to specify |
| 556 | // private link dependencies that are otherwise excluded from usage |
| 557 | // requirements. |
| 558 | if (usage == UseTo::Compile) { |
| 559 | dagChecker.SetTransitivePropertiesOnly(); |
| 560 | dagChecker.SetTransitivePropertiesOnlyCMP0131(); |
| 561 | } |
| 562 | cmMakefile const* mf = this->LocalGenerator->GetMakefile(); |
| 563 | LookupLinkItemScope scope{ this->LocalGenerator }; |
| 564 | for (BT<std::string> const& entry : entries) { |
| 565 | cmGeneratorExpression ge(*this->LocalGenerator->GetCMakeInstance(), |
| 566 | entry.Backtrace); |
| 567 | std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(entry.Value); |
| 568 | cge->SetEvaluateForBuildsystem(true); |
| 569 | cmList libs{ cge->Evaluate(context, &dagChecker, headTarget, this) }; |
| 570 | |
| 571 | auto linkFeature = cmLinkItem::DEFAULT; |
| 572 | for (auto const& lib : libs) { |
| 573 | if (auto maybeLinkFeature = ParseLinkFeature(lib)) { |
| 574 | linkFeature = std::move(*maybeLinkFeature); |
| 575 | continue; |
| 576 | } |
| 577 | |
| 578 | if (cm::optional<cmLinkItem> maybeItem = this->LookupLinkItem( |
| 579 | lib, cge->GetBacktrace(), linkFeature, &scope, |
| 580 | field == LinkInterfaceField::Libraries ? LookupSelf::No |
| 581 | : LookupSelf::Yes)) { |
| 582 | cmLinkItem item = std::move(*maybeItem); |
| 583 | |
| 584 | if (field == LinkInterfaceField::HeadInclude) { |
| 585 | item.InterfaceDirectFrom = this; |
| 586 | iface.HeadInclude.emplace_back(std::move(item)); |
| 587 | continue; |
| 588 | } |
| 589 | if (field == LinkInterfaceField::HeadExclude) { |
| 590 | iface.HeadExclude.emplace_back(std::move(item)); |
no test coverage detected