diff options
author | Raul Tambre <raul@tambre.ee> | 2020-09-05 16:40:02 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-09-24 19:19:54 (GMT) |
commit | c63fe018353cf6afb30980c4cac7493be7cd0a82 (patch) | |
tree | 68d2daf0cd8ab91a9feaa49392607c6cfecd2ac4 /Source/cmMakefileExecutableTargetGenerator.cxx | |
parent | c98ec731f90eb0180c89108b7d2e42263b66d1ed (diff) | |
download | CMake-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/cmMakefileExecutableTargetGenerator.cxx')
-rw-r--r-- | Source/cmMakefileExecutableTargetGenerator.cxx | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 9b5c6e6..871878c 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -91,19 +91,12 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( std::vector<std::string> commands; - // Get the language to use for linking this library. - std::string linkLanguage = "CUDA"; + // Get the name of the device object to generate. std::string const& objExt = this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION"); - - // Build list of dependencies. - std::vector<std::string> depends; - this->AppendLinkDepends(depends, 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) { @@ -111,7 +104,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( 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(), @@ -121,6 +114,29 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress); } + if (this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID") == "Clang") { + this->WriteDeviceLinkRule(commands, targetOutput); + } else { + this->WriteNvidiaDeviceExecutableRule(relink, commands, targetOutput); + } + + // Write the main driver rule to build everything in this target. + this->WriteTargetDriverRule(targetOutput, relink); +#else + static_cast<void>(relink); +#endif +} + +void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule( + bool relink, std::vector<std::string>& commands, + const std::string& targetOutput) +{ + const std::string linkLanguage = "CUDA"; + + // Build list of dependencies. + std::vector<std::string> depends; + this->AppendLinkDepends(depends, linkLanguage); + // Build a list of compiler flags and linker flags. std::string langFlags; std::string linkFlags; @@ -136,7 +152,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( // may need to be cleaned. std::vector<std::string> exeCleanFiles; exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal)); + this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput)); // Determine whether a link script will be used. bool useLinkScript = this->GlobalGenerator->GetUseLinkScript(); @@ -195,7 +211,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( : cmOutputConverter::SHELL; std::string target = this->LocalGenerator->ConvertToOutputFormat( this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal), + this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput), output); std::string targetFullPathCompilePDB = @@ -226,7 +242,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( this->LocalGenerator->CreateRulePlaceholderExpander()); // Expand placeholders in the commands. - rulePlaceholderExpander->SetTargetImpLib(targetOutputReal); + rulePlaceholderExpander->SetTargetImpLib(targetOutput); for (std::string& real_link_command : real_link_commands) { real_link_command = cmStrCat(launcher, real_link_command); rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, @@ -255,17 +271,10 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( // Write the build rule. this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, nullptr, - targetOutputReal, depends, commands, - false); - - // Write the main driver rule to build everything in this target. - this->WriteTargetDriverRule(targetOutputReal, relink); + targetOutput, depends, commands, false); // Clean all the possible executable names and symlinks. this->CleanFiles.insert(exeCleanFiles.begin(), exeCleanFiles.end()); -#else - static_cast<void>(relink); -#endif } void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) |