summaryrefslogtreecommitdiff
path: root/Source/cmGeneratorTarget.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r--Source/cmGeneratorTarget.cxx362
1 files changed, 304 insertions, 58 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index efac06a9d..f1ef130af 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -52,6 +52,11 @@
class cmMessenger;
+namespace {
+const cmsys::RegularExpression FrameworkRegularExpression(
+ "^(.*/)?([^/]*)\\.framework/(.*)$");
+}
+
template <>
cmProp cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
cmGeneratorTarget const* tgt, cmMessenger* /* messenger */,
@@ -692,6 +697,7 @@ void cmGeneratorTarget::ClearSourcesCache()
this->SourcesAreContextDependent = Tribool::Indeterminate;
this->Objects.clear();
this->VisitedConfigsForObjects.clear();
+ this->LinkImplMap.clear();
}
void cmGeneratorTarget::AddSourceCommon(const std::string& src, bool before)
@@ -970,11 +976,11 @@ cmProp cmGeneratorTarget::GetPropertyWithPairedLanguageSupport(
std::string const& lang, const char* suffix) const
{
cmProp propertyValue = this->Target->GetProperty(cmStrCat(lang, suffix));
- if (propertyValue == nullptr) {
+ if (!propertyValue) {
// Check if we should use the value set by another language.
if (lang == "OBJC") {
propertyValue = this->GetPropertyWithPairedLanguageSupport("C", suffix);
- } else if (lang == "OBJCXX" || lang == "CUDA") {
+ } else if (lang == "OBJCXX" || lang == "CUDA" || lang == "HIP") {
propertyValue =
this->GetPropertyWithPairedLanguageSupport("CXX", suffix);
}
@@ -1062,6 +1068,20 @@ const std::string& cmGeneratorTarget::GetLocation(
return location;
}
+cm::optional<std::string> cmGeneratorTarget::MaybeGetLocation(
+ std::string const& config) const
+{
+ cm::optional<std::string> location;
+ if (cmGeneratorTarget::ImportInfo const* imp = this->GetImportInfo(config)) {
+ if (!imp->Location.empty()) {
+ location = imp->Location;
+ }
+ } else {
+ location = this->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
+ }
+ return location;
+}
+
std::vector<cmCustomCommand> const& cmGeneratorTarget::GetPreBuildCommands()
const
{
@@ -1101,7 +1121,7 @@ void cmGeneratorTarget::AppendLanguageSideEffects(
std::map<std::string, std::set<cmGeneratorTarget const*>>& sideEffects) const
{
static const std::set<cm::string_view> LANGS_WITH_NO_SIDE_EFFECTS = {
- "C"_s, "CXX"_s, "OBJC"_s, "OBJCXX"_s, "ASM"_s, "CUDA"_s,
+ "C"_s, "CXX"_s, "OBJC"_s, "OBJCXX"_s, "ASM"_s, "CUDA"_s, "HIP"_s
};
for (auto const& lang : this->GetAllConfigCompileLanguages()) {
@@ -1215,6 +1235,20 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
&dagChecker, result, excludeImported, language);
}
+ cmLinkImplementation const* impl = this->GetLinkImplementation(config);
+ if (impl != nullptr) {
+ auto runtimeEntries = impl->LanguageRuntimeLibraries.find(language);
+ if (runtimeEntries != impl->LanguageRuntimeLibraries.end()) {
+ for (auto const& lib : runtimeEntries->second) {
+ if (lib.Target) {
+ handleSystemIncludesDep(this->LocalGenerator, lib.Target, config,
+ this, &dagChecker, result, excludeImported,
+ language);
+ }
+ }
+ }
+ }
+
std::for_each(result.begin(), result.end(),
cmSystemTools::ConvertToUnixSlashes);
std::sort(result.begin(), result.end());
@@ -1454,31 +1488,80 @@ void AddLangSpecificImplicitIncludeDirectories(
}
}
+void addInterfaceEntry(cmGeneratorTarget const* headTarget,
+ std::string const& config, std::string const& prop,
+ std::string const& lang,
+ cmGeneratorExpressionDAGChecker* dagChecker,
+ EvaluatedTargetPropertyEntries& entries,
+ bool usage_requirements_only,
+ std::vector<cmLinkImplItem> const& libraries)
+{
+ for (cmLinkImplItem const& lib : libraries) {
+ if (lib.Target) {
+ EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
+ // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
+ // caller's property and hand-evaluate it as if it were compiled.
+ // Create a context as cmCompiledGeneratorExpression::Evaluate does.
+ cmGeneratorExpressionContext context(
+ headTarget->GetLocalGenerator(), config, false, headTarget, headTarget,
+ true, lib.Backtrace, lang);
+ cmExpandList(lib.Target->EvaluateInterfaceProperty(
+ prop, &context, dagChecker, usage_requirements_only),
+ ee.Values);
+ ee.ContextDependent = context.HadContextSensitiveCondition;
+ entries.Entries.emplace_back(std::move(ee));
+ }
+ }
+}
+
+// IncludeRuntimeInterface is used to break the cycle in computing
+// the necessary transitive dependencies of targets that can occur
+// now that we have implicit language runtime targets.
+//
+// To determine the set of languages that a target has we need to iterate
+// all the sources which includes transitive INTERFACE sources.
+// Therefore we can't determine what language runtimes are needed
+// for a target until after all sources are computed.
+//
+// Therefore while computing the applicable INTERFACE_SOURCES we
+// must ignore anything in LanguageRuntimeLibraries or we would
+// create a cycle ( INTERFACE_SOURCES requires LanguageRuntimeLibraries,
+// LanguageRuntimeLibraries requires INTERFACE_SOURCES).
+//
+enum class IncludeRuntimeInterface
+{
+ Yes,
+ No
+};
void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
std::string const& config, std::string const& prop,
std::string const& lang,
cmGeneratorExpressionDAGChecker* dagChecker,
EvaluatedTargetPropertyEntries& entries,
+ IncludeRuntimeInterface searchRuntime,
bool usage_requirements_only = true)
{
- if (cmLinkImplementationLibraries const* impl =
- headTarget->GetLinkImplementationLibraries(config)) {
- entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
- for (cmLinkImplItem const& lib : impl->Libraries) {
- if (lib.Target) {
- EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
- // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
- // caller's property and hand-evaluate it as if it were compiled.
- // Create a context as cmCompiledGeneratorExpression::Evaluate does.
- cmGeneratorExpressionContext context(
- headTarget->GetLocalGenerator(), config, false, headTarget,
- headTarget, true, lib.Backtrace, lang);
- cmExpandList(lib.Target->EvaluateInterfaceProperty(
- prop, &context, dagChecker, usage_requirements_only),
- ee.Values);
- ee.ContextDependent = context.HadContextSensitiveCondition;
- entries.Entries.emplace_back(std::move(ee));
+ if (searchRuntime == IncludeRuntimeInterface::Yes) {
+ if (cmLinkImplementation const* impl =
+ headTarget->GetLinkImplementation(config)) {
+ entries.HadContextSensitiveCondition =
+ impl->HadContextSensitiveCondition;
+
+ auto runtimeLibIt = impl->LanguageRuntimeLibraries.find(lang);
+ if (runtimeLibIt != impl->LanguageRuntimeLibraries.end()) {
+ addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries,
+ usage_requirements_only, runtimeLibIt->second);
}
+ addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries,
+ usage_requirements_only, impl->Libraries);
+ }
+ } else {
+ if (cmLinkImplementationLibraries const* impl =
+ headTarget->GetLinkImplementationLibraries(config)) {
+ entries.HadContextSensitiveCondition =
+ impl->HadContextSensitiveCondition;
+ addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries,
+ usage_requirements_only, impl->Libraries);
}
}
}
@@ -1636,7 +1719,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
// Collect INTERFACE_SOURCES of all direct link-dependencies.
EvaluatedTargetPropertyEntries linkInterfaceSourcesEntries;
AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(),
- &dagChecker, linkInterfaceSourcesEntries);
+ &dagChecker, linkInterfaceSourcesEntries,
+ IncludeRuntimeInterface::No, true);
std::vector<std::string>::size_type numFilesBefore = files.size();
bool contextDependentInterfaceSources = processSources(
this, linkInterfaceSourcesEntries, files, uniqueSrcs, debugSources);
@@ -2243,8 +2327,16 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const
return cmSystemTools::GetFilenameName(info->Location);
}
// Use the soname given if any.
+ if (this->IsFrameworkOnApple()) {
+ cmsys::RegularExpressionMatch match;
+ if (FrameworkRegularExpression.find(info->SOName.c_str(), match)) {
+ auto frameworkName = match.match(2);
+ auto fileName = match.match(3);
+ return cmStrCat(frameworkName, ".framework/", fileName);
+ }
+ }
if (cmHasLiteralPrefix(info->SOName, "@rpath/")) {
- return info->SOName.substr(6);
+ return info->SOName.substr(cmStrLen("@rpath/"));
}
return info->SOName;
}
@@ -3323,6 +3415,29 @@ void cmGeneratorTarget::AddISPCTargetFlags(std::string& flags) const
}
}
+void cmGeneratorTarget::AddHIPArchitectureFlags(std::string& flags) const
+{
+ const std::string& property = this->GetSafeProperty("HIP_ARCHITECTURES");
+
+ if (property.empty()) {
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ "HIP_ARCHITECTURES is empty for target \"" +
+ this->GetName() + "\".");
+ }
+
+ // If HIP_ARCHITECTURES is false we don't add any architectures.
+ if (cmIsOff(property)) {
+ return;
+ }
+
+ std::vector<std::string> options;
+ cmExpandList(property, options);
+
+ for (std::string& option : options) {
+ flags += " --offload-arch=" + option;
+ }
+}
+
void cmGeneratorTarget::AddCUDAToolkitFlags(std::string& flags) const
{
std::string const& compiler =
@@ -3542,7 +3657,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
}
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
- &dagChecker, entries);
+ &dagChecker, entries, IncludeRuntimeInterface::Yes);
if (this->Makefile->IsOn("APPLE")) {
if (cmLinkImplementationLibraries const* impl =
@@ -3767,7 +3882,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
this, config, language, &dagChecker, this->CompileOptionsEntries);
AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS", language,
- &dagChecker, entries);
+ &dagChecker, entries, IncludeRuntimeInterface::Yes);
processOptions(this, entries, result, uniqueOptions, debugOptions,
"compile options", OptionsParse::Shell);
@@ -3809,7 +3924,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
this, config, std::string(), &dagChecker, this->CompileFeaturesEntries);
AddInterfaceEntries(this, config, "INTERFACE_COMPILE_FEATURES",
- std::string(), &dagChecker, entries);
+ std::string(), &dagChecker, entries,
+ IncludeRuntimeInterface::Yes);
processOptions(this, entries, result, uniqueFeatures, debugFeatures,
"compile features", OptionsParse::None);
@@ -3853,7 +3969,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
this, config, language, &dagChecker, this->CompileDefinitionsEntries);
AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS", language,
- &dagChecker, entries);
+ &dagChecker, entries, IncludeRuntimeInterface::Yes);
if (!config.empty()) {
std::string configPropName =
@@ -3911,7 +4027,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
this, config, language, &dagChecker, this->PrecompileHeadersEntries);
AddInterfaceEntries(this, config, "INTERFACE_PRECOMPILE_HEADERS", language,
- &dagChecker, entries);
+ &dagChecker, entries, IncludeRuntimeInterface::Yes);
std::vector<BT<std::string>> list;
processOptions(this, entries, list, uniqueOptions, debugDefines,
@@ -4296,7 +4412,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
this, config, language, &dagChecker, this->LinkOptionsEntries);
AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language,
- &dagChecker, entries,
+ &dagChecker, entries, IncludeRuntimeInterface::Yes,
this->GetPolicyStatusCMP0099() != cmPolicies::NEW);
processOptions(this, entries, result, uniqueOptions, debugOptions,
@@ -4555,7 +4671,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
this, config, language, &dagChecker, this->LinkDirectoriesEntries);
AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language,
- &dagChecker, entries,
+ &dagChecker, entries, IncludeRuntimeInterface::Yes,
this->GetPolicyStatusCMP0099() != cmPolicies::NEW);
processLinkDirectories(this, entries, result, uniqueDirectories,
@@ -4594,7 +4710,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
}
}
AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language,
- &dagChecker, entries,
+ &dagChecker, entries, IncludeRuntimeInterface::Yes,
this->GetPolicyStatusCMP0099() != cmPolicies::NEW);
processOptions(this, entries, result, uniqueOptions, false, "link depends",
@@ -4701,13 +4817,13 @@ bool cmGeneratorTarget::ComputeCompileFeatures(
cmStrCat(cmSystemTools::UpperCase(config), '-', language.first);
BTs<std::string> const* standardToCopy =
this->GetLanguageStandardProperty(language.second, config);
- if (standardToCopy != nullptr) {
+ if (standardToCopy) {
this->LanguageStandardMap[key] = *standardToCopy;
generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
} else {
cmProp defaultStandard = this->Makefile->GetDefinition(
cmStrCat("CMAKE_", language.second, "_STANDARD_DEFAULT"));
- if (defaultStandard != nullptr) {
+ if (defaultStandard) {
this->LanguageStandardMap[key] = BTs<std::string>(*defaultStandard);
generatorTargetLanguageStandard = &this->LanguageStandardMap[key];
}
@@ -4715,7 +4831,7 @@ bool cmGeneratorTarget::ComputeCompileFeatures(
// Custom updates for the CUDA standard.
if (generatorTargetLanguageStandard != nullptr &&
- language.first == "CUDA") {
+ (language.first == "CUDA")) {
if (generatorTargetLanguageStandard->Value == "98") {
this->LanguageStandardMap[key].Value = "03";
}
@@ -6229,29 +6345,28 @@ bool cmGeneratorTarget::IsLinkLookupScope(std::string const& n,
return false;
}
-void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
- cmListFileBacktrace const& bt,
- std::vector<cmLinkItem>& items) const
+cm::optional<cmLinkItem> cmGeneratorTarget::LookupLinkItem(
+ std::string const& n, cmListFileBacktrace const& bt,
+ LookupLinkItemScope* scope) const
{
- cmLocalGenerator const* lg = this->LocalGenerator;
- for (std::string const& n : names) {
- if (this->IsLinkLookupScope(n, lg)) {
- continue;
- }
+ cm::optional<cmLinkItem> maybeItem;
+ if (this->IsLinkLookupScope(n, scope->LG)) {
+ return maybeItem;
+ }
- std::string name = this->CheckCMP0004(n);
- if (name == this->GetName() || name.empty()) {
- continue;
- }
- items.push_back(this->ResolveLinkItem(name, bt, lg));
+ std::string name = this->CheckCMP0004(n);
+ if (name == this->GetName() || name.empty()) {
+ return maybeItem;
}
+ maybeItem = this->ResolveLinkItem(name, bt, scope->LG);
+ return maybeItem;
}
void cmGeneratorTarget::ExpandLinkItems(
std::string const& prop, std::string const& value, std::string const& config,
cmGeneratorTarget const* headTarget, bool usage_requirements_only,
- std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition,
- bool& hadContextSensitiveCondition,
+ std::vector<cmLinkItem>& items, std::vector<cmLinkItem>& objects,
+ bool& hadHeadSensitiveCondition, bool& hadContextSensitiveCondition,
bool& hadLinkLanguageSensitiveCondition) const
{
// Keep this logic in sync with ComputeLinkImplementationLibraries.
@@ -6265,10 +6380,30 @@ void cmGeneratorTarget::ExpandLinkItems(
}
std::vector<std::string> libs;
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+ cge->SetEvaluateForBuildsystem(true);
cmExpandList(cge->Evaluate(this->LocalGenerator, config, headTarget,
&dagChecker, this, headTarget->LinkerLanguage),
libs);
- this->LookupLinkItems(libs, cge->GetBacktrace(), items);
+ cmMakefile const* mf = this->LocalGenerator->GetMakefile();
+ LookupLinkItemScope scope{ this->LocalGenerator };
+ for (std::string const& lib : libs) {
+ if (cm::optional<cmLinkItem> maybeItem =
+ this->LookupLinkItem(lib, cge->GetBacktrace(), &scope)) {
+ if (!maybeItem->Target) {
+ // Report explicitly linked object files separately.
+ std::string const& maybeObj = maybeItem->AsStr();
+ if (cmSystemTools::FileIsFullPath(maybeObj)) {
+ cmSourceFile const* sf =
+ mf->GetSource(maybeObj, cmSourceFileLocationKind::Known);
+ if (sf && sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
+ objects.emplace_back(std::move(*maybeItem));
+ continue;
+ }
+ }
+ }
+ items.emplace_back(std::move(*maybeItem));
+ }
+ }
hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
hadContextSensitiveCondition = cge->GetHadContextSensitiveCondition();
hadLinkLanguageSensitiveCondition =
@@ -6319,6 +6454,7 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
iface.AllDone = true;
if (iface.Exists) {
this->ComputeLinkInterface(config, iface, head, secondPass);
+ this->ComputeLinkInterfaceRuntimeLibraries(config, iface);
}
}
@@ -6446,9 +6582,19 @@ std::string cmGeneratorTarget::GetDirectory(
const std::string& config, cmStateEnums::ArtifactType artifact) const
{
if (this->IsImported()) {
+ auto fullPath = this->Target->ImportedGetFullPath(config, artifact);
+ if (this->IsFrameworkOnApple()) {
+ cmsys::RegularExpressionMatch match;
+ if (FrameworkRegularExpression.find(fullPath.c_str(), match)) {
+ auto path = match.match(1);
+ if (!path.empty()) {
+ path.erase(path.length() - 1);
+ }
+ return path;
+ }
+ }
// Return the directory from which the target is imported.
- return cmSystemTools::GetFilenamePath(
- this->Target->ImportedGetFullPath(config, artifact));
+ return cmSystemTools::GetFilenamePath(fullPath);
}
if (OutputInfo const* info = this->GetOutputInfo(config)) {
// Return the directory in which the target will be built.
@@ -6757,13 +6903,13 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
return;
}
iface.Exists = true;
- iface.Explicit = cmp0022NEW || explicitLibraries != nullptr;
+ iface.Explicit = cmp0022NEW || explicitLibraries;
if (explicitLibraries) {
// The interface libraries have been explicitly set.
this->ExpandLinkItems(linkIfaceProp, *explicitLibraries, config,
headTarget, usage_requirements_only, iface.Libraries,
- iface.HadHeadSensitiveCondition,
+ iface.Objects, iface.HadHeadSensitiveCondition,
iface.HadContextSensitiveCondition,
iface.HadLinkLanguageSensitiveCondition);
return;
@@ -6787,6 +6933,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// Compare the link implementation fallback link interface to the
// preferred new link interface property and warn if different.
std::vector<cmLinkItem> ifaceLibs;
+ std::vector<cmLinkItem> ifaceObjects;
static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
if (cmProp newExplicitLibraries = this->GetProperty(newProp)) {
bool hadHeadSensitiveConditionDummy = false;
@@ -6794,7 +6941,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
bool hadLinkLanguageSensitiveConditionDummy = false;
this->ExpandLinkItems(newProp, *newExplicitLibraries, config,
headTarget, usage_requirements_only, ifaceLibs,
- hadHeadSensitiveConditionDummy,
+ ifaceObjects, hadHeadSensitiveConditionDummy,
hadContextSensitiveConditionDummy,
hadLinkLanguageSensitiveConditionDummy);
}
@@ -6831,6 +6978,83 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
}
}
+namespace {
+
+template <typename ReturnType>
+ReturnType constructItem(cmGeneratorTarget* target,
+ cmListFileBacktrace const& bt);
+
+template <>
+inline cmLinkImplItem constructItem(cmGeneratorTarget* target,
+ cmListFileBacktrace const& bt)
+{
+ return cmLinkImplItem(cmLinkItem(target, false, bt), false);
+}
+
+template <>
+inline cmLinkItem constructItem(cmGeneratorTarget* target,
+ cmListFileBacktrace const& bt)
+{
+ return cmLinkItem(target, false, bt);
+}
+
+template <typename ValueType>
+std::vector<ValueType> computeImplicitLanguageTargets(
+ std::string const& lang, std::string const& config,
+ cmGeneratorTarget const* currentTarget)
+{
+ cmListFileBacktrace bt;
+ std::vector<ValueType> result;
+ cmLocalGenerator* lg = currentTarget->GetLocalGenerator();
+
+ std::string const& runtimeLibrary =
+ currentTarget->GetRuntimeLinkLibrary(lang, config);
+ if (cmProp runtimeLinkOptions = currentTarget->Makefile->GetDefinition(
+ "CMAKE_" + lang + "_RUNTIME_LIBRARIES_" + runtimeLibrary)) {
+ std::vector<std::string> libsVec = cmExpandedList(*runtimeLinkOptions);
+ result.reserve(libsVec.size());
+
+ for (std::string const& i : libsVec) {
+ cmGeneratorTarget::TargetOrString resolved =
+ currentTarget->ResolveTargetReference(i, lg);
+ if (resolved.Target) {
+ result.emplace_back(constructItem<ValueType>(resolved.Target, bt));
+ }
+ }
+ }
+
+ return result;
+}
+}
+
+void cmGeneratorTarget::ComputeLinkInterfaceRuntimeLibraries(
+ const std::string& config, cmOptionalLinkInterface& iface) const
+{
+ for (std::string const& lang : iface.Languages) {
+ if ((lang == "CUDA" || lang == "HIP") &&
+ iface.LanguageRuntimeLibraries.find(lang) ==
+ iface.LanguageRuntimeLibraries.end()) {
+ auto implicitTargets =
+ computeImplicitLanguageTargets<cmLinkItem>(lang, config, this);
+ iface.LanguageRuntimeLibraries[lang] = std::move(implicitTargets);
+ }
+ }
+}
+
+void cmGeneratorTarget::ComputeLinkImplementationRuntimeLibraries(
+ const std::string& config, cmOptionalLinkImplementation& impl) const
+{
+ for (std::string const& lang : impl.Languages) {
+ if ((lang == "CUDA" || lang == "HIP") &&
+ impl.LanguageRuntimeLibraries.find(lang) ==
+ impl.LanguageRuntimeLibraries.end()) {
+ auto implicitTargets =
+ computeImplicitLanguageTargets<cmLinkImplItem>(lang, config, this);
+ impl.LanguageRuntimeLibraries[lang] = std::move(implicitTargets);
+ }
+ }
+}
+
const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
const std::string& config, cmGeneratorTarget const* headTarget,
bool usage_requirements_only, bool secondPass) const
@@ -6862,11 +7086,17 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
cmExpandList(info->Languages, iface.Languages);
this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
headTarget, usage_requirements_only, iface.Libraries,
- iface.HadHeadSensitiveCondition,
+ iface.Objects, iface.HadHeadSensitiveCondition,
iface.HadContextSensitiveCondition,
iface.HadLinkLanguageSensitiveCondition);
std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
- this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps);
+ LookupLinkItemScope scope{ this->LocalGenerator };
+ for (std::string const& dep : deps) {
+ if (cm::optional<cmLinkItem> maybeItem =
+ this->LookupLinkItem(dep, cmListFileBacktrace(), &scope)) {
+ iface.SharedDeps.emplace_back(std::move(*maybeItem));
+ }
+ }
}
return &iface;
@@ -7090,6 +7320,7 @@ const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
if (!impl.LanguagesDone) {
impl.LanguagesDone = true;
this->ComputeLinkImplementationLanguages(config, impl);
+ this->ComputeLinkImplementationRuntimeLibraries(config, impl);
}
return &impl;
}
@@ -7379,6 +7610,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cmGeneratorTarget const* head) const
{
cmLocalGenerator const* lg = this->LocalGenerator;
+ cmMakefile const* mf = lg->GetMakefile();
cmStringRange entryRange = this->Target->GetLinkImplementationEntries();
cmBacktraceRange btRange = this->Target->GetLinkImplementationBacktraces();
cmBacktraceRange::const_iterator btIt = btRange.begin();
@@ -7392,6 +7624,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
nullptr);
cmGeneratorExpression ge(*btIt);
std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le);
+ cge->SetEvaluateForBuildsystem(true);
std::string const& evaluated =
cge->Evaluate(this->LocalGenerator, config, head, &dagChecker, nullptr,
this->LinkerLanguage);
@@ -7452,8 +7685,21 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
}
// The entry is meant for this configuration.
- impl.Libraries.emplace_back(this->ResolveLinkItem(name, *btIt, lg),
- evaluated != *le);
+ cmLinkItem item = this->ResolveLinkItem(name, *btIt, lg);
+ if (!item.Target) {
+ // Report explicitly linked object files separately.
+ std::string const& maybeObj = item.AsStr();
+ if (cmSystemTools::FileIsFullPath(maybeObj)) {
+ cmSourceFile const* sf =
+ mf->GetSource(maybeObj, cmSourceFileLocationKind::Known);
+ if (sf && sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
+ impl.Objects.emplace_back(std::move(item));
+ continue;
+ }
+ }
+ }
+
+ impl.Libraries.emplace_back(std::move(item), evaluated != *le);
}
std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();