summaryrefslogtreecommitdiffstats
path: root/Source/cmMakefileLibraryTargetGenerator.cxx
diff options
context:
space:
mode:
authorRaul Tambre <raul@tambre.ee>2020-09-05 16:40:02 (GMT)
committerBrad King <brad.king@kitware.com>2020-09-24 19:19:54 (GMT)
commitc63fe018353cf6afb30980c4cac7493be7cd0a82 (patch)
tree68d2daf0cd8ab91a9feaa49392607c6cfecd2ac4 /Source/cmMakefileLibraryTargetGenerator.cxx
parentc98ec731f90eb0180c89108b7d2e42263b66d1ed (diff)
downloadCMake-c63fe018353cf6afb30980c4cac7493be7cd0a82.zip
CMake-c63fe018353cf6afb30980c4cac7493be7cd0a82.tar.gz
CMake-c63fe018353cf6afb30980c4cac7493be7cd0a82.tar.bz2
CUDA: Clang separable compilation
For NVCC the compiler takes care of device linking when passed the "-dlink" flag. Clang doesn't support such magic and requires the buildsystem to do the work that NVCC does behind the scenes. The implementation is based on Bazel's device linking documentation: https://github.com/tensorflow/tensorflow/blob/7cabcdf073abad8c46e9dda62bb8fa4682d2061e/third_party/nccl/build_defs.bzl.tpl#L259 Closes: #20726
Diffstat (limited to 'Source/cmMakefileLibraryTargetGenerator.cxx')
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx73
1 files changed, 41 insertions, 32 deletions
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 1c25fc4..b32ea6a 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -129,8 +129,7 @@ void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
const bool requiresDeviceLinking = requireDeviceLinking(
*this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
if (requiresDeviceLinking) {
- std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
- this->WriteDeviceLibraryRules(linkRuleVar, false);
+ this->WriteDeviceLibraryRules("CMAKE_CUDA_DEVICE_LINK_LIBRARY", false);
}
std::string linkLanguage =
@@ -156,8 +155,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
const bool requiresDeviceLinking = requireDeviceLinking(
*this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
if (requiresDeviceLinking) {
- std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
- this->WriteDeviceLibraryRules(linkRuleVar, relink);
+ this->WriteDeviceLibraryRules("CMAKE_CUDA_DEVICE_LINK_LIBRARY", relink);
}
}
@@ -191,8 +189,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
const bool requiresDeviceLinking = requireDeviceLinking(
*this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
if (requiresDeviceLinking) {
- std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
- this->WriteDeviceLibraryRules(linkRuleVar, relink);
+ this->WriteDeviceLibraryRules("CMAKE_CUDA_DEVICE_LINK_LIBRARY", relink);
}
}
@@ -239,29 +236,13 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
// TODO: Merge the methods that call this method to avoid
// code duplication.
std::vector<std::string> commands;
-
- // Get the language to use for linking this library.
- std::string linkLanguage = "CUDA";
std::string const objExt =
this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION");
- // Build list of dependencies.
- std::vector<std::string> depends;
- this->AppendLinkDepends(depends, linkLanguage);
-
- // Add language-specific flags.
- std::string langFlags;
- this->LocalGenerator->AddLanguageFlagsForLinking(
- langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
-
- // Create set of linking flags.
- std::string linkFlags;
- this->GetDeviceLinkFlags(linkFlags, linkLanguage);
-
// Get the name of the device object to generate.
- std::string const targetOutputReal =
+ std::string const targetOutput =
this->GeneratorTarget->ObjectDirectory + "cmake_device_link" + objExt;
- this->DeviceLinkObject = targetOutputReal;
+ this->DeviceLinkObject = targetOutput;
this->NumberOfProgressActions++;
if (!this->NoRuleMessages) {
@@ -269,7 +250,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
this->MakeEchoProgress(progress);
// Add the link message.
std::string buildEcho =
- cmStrCat("Linking ", linkLanguage, " device code ",
+ cmStrCat("Linking CUDA device code ",
this->LocalGenerator->ConvertToOutputFormat(
this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(),
@@ -278,10 +259,41 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
this->LocalGenerator->AppendEcho(
commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress);
}
+
+ if (this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID") == "Clang") {
+ this->WriteDeviceLinkRule(commands, targetOutput);
+ } else {
+ this->WriteNvidiaDeviceLibraryRules(linkRuleVar, relink, commands,
+ targetOutput);
+ }
+
+ // Write the main driver rule to build everything in this target.
+ this->WriteTargetDriverRule(targetOutput, relink);
+}
+
+void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
+ const std::string& linkRuleVar, bool relink,
+ std::vector<std::string>& commands, const std::string& targetOutput)
+{
+ std::string linkLanguage = "CUDA";
+
+ // Build list of dependencies.
+ std::vector<std::string> depends;
+ this->AppendLinkDepends(depends, linkLanguage);
+
+ // Add language-specific flags.
+ std::string langFlags;
+ this->LocalGenerator->AddLanguageFlagsForLinking(
+ langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
+
+ // Create set of linking flags.
+ std::string linkFlags;
+ this->GetDeviceLinkFlags(linkFlags, linkLanguage);
+
// Clean files associated with this library.
std::set<std::string> libCleanFiles;
libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal));
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput));
// Determine whether a link script will be used.
bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
@@ -335,7 +347,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
std::string target = this->LocalGenerator->ConvertToOutputFormat(
this->LocalGenerator->MaybeConvertToRelativePath(
- this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal),
+ this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput),
output);
std::string targetFullPathCompilePDB =
@@ -364,7 +376,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
this->LocalGenerator->CreateRulePlaceholderExpander());
// Construct the main link rule and expand placeholders.
- rulePlaceholderExpander->SetTargetImpLib(targetOutputReal);
+ rulePlaceholderExpander->SetTargetImpLib(targetOutput);
std::string linkRule = this->GetLinkRule(linkRuleVar);
cmExpandList(linkRule, real_link_commands);
@@ -399,14 +411,11 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
commands1.clear();
// Compute the list of outputs.
- std::vector<std::string> outputs(1, targetOutputReal);
+ std::vector<std::string> outputs(1, targetOutput);
// Write the build rule.
this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
commands, false);
-
- // Write the main driver rule to build everything in this target.
- this->WriteTargetDriverRule(targetOutputReal, relink);
#else
static_cast<void>(linkRuleVar);
static_cast<void>(relink);