summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorRobert Maynard <robert.maynard@kitware.com>2020-09-02 18:53:41 (GMT)
committerZack Galbreath <zack.galbreath@kitware.com>2021-06-07 19:25:33 (GMT)
commit947dbed0aa502c70a9e165757450bd8409036980 (patch)
tree0a45b31986184368c7ad6df72d9f9186c7a24b4c /Source
parentb50bfc89131e55685aa41146254b37d26049b4d5 (diff)
downloadCMake-947dbed0aa502c70a9e165757450bd8409036980.zip
CMake-947dbed0aa502c70a9e165757450bd8409036980.tar.gz
CMake-947dbed0aa502c70a9e165757450bd8409036980.tar.bz2
HIP: Automatically inject the `hip::device` runtime target
Any target that might need to link to hip code needs the `hip::device` target
Diffstat (limited to 'Source')
-rw-r--r--Source/cmComputeLinkDepends.cxx14
-rw-r--r--Source/cmGeneratorTarget.cxx196
-rw-r--r--Source/cmGeneratorTarget.h6
-rw-r--r--Source/cmLinkItem.h5
4 files changed, 195 insertions, 26 deletions
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 4a6518fd..0b27e34 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -7,6 +7,7 @@
#include <cstdio>
#include <iterator>
#include <sstream>
+#include <unordered_map>
#include <utility>
#include <cm/memory>
@@ -371,6 +372,12 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry qe)
// This target provides its own link interface information.
this->AddLinkEntries(depender_index, iface->Libraries);
this->AddLinkObjects(iface->Objects);
+ for (auto const& language : iface->Languages) {
+ auto runtimeEntries = iface->LanguageRuntimeLibraries.find(language);
+ if (runtimeEntries != iface->LanguageRuntimeLibraries.end()) {
+ this->AddLinkEntries(depender_index, runtimeEntries->second);
+ }
+ }
if (isIface) {
return;
@@ -516,6 +523,13 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
this->Target->GetLinkImplementation(this->Config);
this->AddLinkEntries(-1, impl->Libraries);
this->AddLinkObjects(impl->Objects);
+
+ for (auto const& language : impl->Languages) {
+ auto runtimeEntries = impl->LanguageRuntimeLibraries.find(language);
+ if (runtimeEntries != impl->LanguageRuntimeLibraries.end()) {
+ this->AddLinkEntries(-1, runtimeEntries->second);
+ }
+ }
for (cmLinkItem const& wi : impl->WrongConfigLibraries) {
this->CheckWrongConfigItem(wi);
}
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 812535b..cb10117 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1235,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());
@@ -1474,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);
}
}
}
@@ -1656,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);
@@ -3587,7 +3651,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 =
@@ -3812,7 +3876,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);
@@ -3854,7 +3918,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);
@@ -3898,7 +3963,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 =
@@ -3956,7 +4021,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,
@@ -4341,7 +4406,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,
@@ -4600,7 +4665,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,
@@ -4639,7 +4704,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",
@@ -6382,6 +6447,7 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
iface.AllDone = true;
if (iface.Exists) {
this->ComputeLinkInterface(config, iface, head, secondPass);
+ this->ComputeLinkInterfaceRuntimeLibraries(config, iface);
}
}
@@ -6905,6 +6971,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
@@ -7169,6 +7312,7 @@ const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
if (!impl.LanguagesDone) {
impl.LanguagesDone = true;
this->ComputeLinkImplementationLanguages(config, impl);
+ this->ComputeLinkImplementationRuntimeLibraries(config, impl);
}
return &impl;
}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index ab9ccfd..ed66fb1 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -1111,6 +1111,12 @@ private:
cmProp GetPropertyWithPairedLanguageSupport(std::string const& lang,
const char* suffix) const;
+ void ComputeLinkImplementationRuntimeLibraries(
+ const std::string& config, cmOptionalLinkImplementation& impl) const;
+
+ void ComputeLinkInterfaceRuntimeLibraries(
+ const std::string& config, cmOptionalLinkInterface& iface) const;
+
public:
const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure(
const std::string& config) const;
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index db44938..0863edd 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -7,6 +7,7 @@
#include <map>
#include <ostream>
#include <string>
+#include <unordered_map>
#include <vector>
#include <cmext/algorithm>
@@ -80,6 +81,8 @@ struct cmLinkInterface : public cmLinkInterfaceLibraries
{
// Languages whose runtime libraries must be linked.
std::vector<std::string> Languages;
+ std::unordered_map<std::string, std::vector<cmLinkItem>>
+ LanguageRuntimeLibraries;
// Shared library dependencies needed for linking on some platforms.
std::vector<cmLinkItem> SharedDeps;
@@ -115,6 +118,8 @@ struct cmLinkImplementation : public cmLinkImplementationLibraries
{
// Languages whose runtime libraries must be linked.
std::vector<std::string> Languages;
+ std::unordered_map<std::string, std::vector<cmLinkImplItem>>
+ LanguageRuntimeLibraries;
// Whether the list depends on a link language genex.
bool HadLinkLanguageSensitiveCondition = false;