/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file LICENSE.rst or https://cmake.org/licensing for details. */ #include "cmEvaluatedTargetProperty.h" #include #include #include "cmGenExContext.h" #include "cmGenExEvaluation.h" #include "cmGeneratorFileSets.h" #include "cmGeneratorTarget.h" #include "cmLinkItem.h" #include "cmList.h" #include "cmTargetPropertyEntry.h" struct cmGeneratorExpressionDAGChecker; namespace cm { EvaluatedTargetPropertyEntry::EvaluatedTargetPropertyEntry( cmLinkItem const& item, cmListFileBacktrace bt) : LinkItem(item) , Backtrace(std::move(bt)) { } EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry( cmGeneratorTarget const* thisTarget, cm::GenEx::Context const& context, cmGeneratorExpressionDAGChecker* dagChecker, cm::TargetPropertyEntry& entry) { EvaluatedTargetPropertyEntry ee(entry.LinkItem, entry.GetBacktrace()); cmExpandList(entry.Evaluate(context, thisTarget, dagChecker), ee.Values); if (entry.GetHadContextSensitiveCondition()) { ee.ContextDependent = true; } return ee; } EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries( cmGeneratorTarget const* thisTarget, cm::GenEx::Context const& context, cmGeneratorExpressionDAGChecker* dagChecker, std::vector> const& in) { EvaluatedTargetPropertyEntries out; out.Entries.reserve(in.size()); for (auto const& entry : in) { out.Entries.emplace_back( EvaluateTargetPropertyEntry(thisTarget, context, dagChecker, *entry)); } return out; } namespace { void addInterfaceEntry(cmGeneratorTarget const* headTarget, std::string const& prop, cm::GenEx::Context const& context, cmGeneratorExpressionDAGChecker* dagChecker, EvaluatedTargetPropertyEntries& entries, cmGeneratorTarget::UseTo usage, std::vector const& libraries) { for (cmLinkItem const& lib : libraries) { if (lib.Target) { EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace); // Pretend $ appeared in our // caller's property and hand-evaluate it as if it were compiled. // Create a context as cmCompiledGeneratorExpression::Evaluate does. cm::GenEx::Evaluation eval(context, false, headTarget, headTarget, true, lib.Backtrace); cmExpandList( lib.Target->EvaluateInterfaceProperty(prop, &eval, dagChecker, usage), ee.Values); ee.ContextDependent = eval.HadContextSensitiveCondition; entries.Entries.emplace_back(std::move(ee)); } } } void addInterfaceFileSetsEntry(cmGeneratorTarget const* headTarget, cm::string_view type, std::string const& prop, cm::GenEx::Context const& context, cmGeneratorExpressionDAGChecker* dagChecker, EvaluatedTargetPropertyEntries& entries, std::vector const& libraries) { for (cmLinkItem const& lib : libraries) { if (lib.Target) { EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace); // Pretend $ appeared in our // caller's property and hand-evaluate it as if it were compiled. // Create a context as cmCompiledGeneratorExpression::Evaluate does. cm::GenEx::Evaluation eval(context, false, headTarget, headTarget, true, lib.Backtrace); cmExpandList( lib.Target->GetGeneratorFileSets()->EvaluateInterfaceProperty( type, prop, &eval, dagChecker), ee.Values); ee.ContextDependent = eval.HadContextSensitiveCondition; entries.Entries.emplace_back(std::move(ee)); } } } } void AddInterfaceEntries(cmGeneratorTarget const* headTarget, std::string const& prop, cm::GenEx::Context const& context, cmGeneratorExpressionDAGChecker* dagChecker, EvaluatedTargetPropertyEntries& entries, IncludeRuntimeInterface searchRuntime, cmGeneratorTarget::UseTo usage) { if (searchRuntime == IncludeRuntimeInterface::Yes) { if (cmLinkImplementation const* impl = headTarget->GetLinkImplementation(context.Config, usage)) { entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition; auto runtimeLibIt = impl->LanguageRuntimeLibraries.find(context.Language); if (runtimeLibIt != impl->LanguageRuntimeLibraries.end()) { addInterfaceEntry(headTarget, prop, context, dagChecker, entries, usage, runtimeLibIt->second); } addInterfaceEntry(headTarget, prop, context, dagChecker, entries, usage, impl->Libraries); } } else { if (cmLinkImplementationLibraries const* impl = headTarget->GetLinkImplementationLibraries(context.Config, usage)) { entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition; addInterfaceEntry(headTarget, prop, context, dagChecker, entries, usage, impl->Libraries); } } } void AddInterfaceFileSetsEntries(cmGeneratorTarget const* headTarget, cm::string_view type, std::string const& prop, cm::GenEx::Context const& context, cmGeneratorExpressionDAGChecker* dagChecker, EvaluatedTargetPropertyEntries& entries) { if (cmLinkImplementationLibraries const* impl = headTarget->GetLinkImplementationLibraries( context.Config, cmGeneratorTarget::UseTo::Compile)) { entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition; addInterfaceFileSetsEntry(headTarget, type, prop, context, dagChecker, entries, impl->Libraries); } } }