Merge topic 'cuda_clang_cmp0105'

4707ecbe6f CUDA: Support CMP0105 on Clang
15fde4c420 CUDA: Use local shorthands for variables in Clang device link code
cf7e68087d CUDA: Avoid unnecessary allocation and GetLinkLanguage()
5b0693411e CUDA: Ignore USE_WATCOM_QUOTE for device link rules

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !6709
This commit is contained in:
Brad King
2021-11-09 12:56:03 +00:00
committed by Kitware Robot
13 changed files with 105 additions and 96 deletions

View File

@@ -0,0 +1,7 @@
cuda-clang-device-link-flags
----------------------------
* Policy :policy:`CMP0105` and the ``$<DEVICE_LINK:...>`` and
``$<HOST_LINK:...>``
:manual:`generator expressions <cmake-generator-expressions(7)>`
are now supported for Clang.

View File

@@ -198,7 +198,7 @@ endif()
# Used when device linking is handled by CMake.
if(NOT CMAKE_CUDA_DEVICE_LINK_COMPILE)
set(CMAKE_CUDA_DEVICE_LINK_COMPILE "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <FLAGS> -D__CUDA_INCLUDE_COMPILER_INTERNAL_HEADERS__ -D__NV_EXTRA_INITIALIZATION=\"\" -D__NV_EXTRA_FINALIZATION=\"\" -DREGISTERLINKBINARYFILE=\\\"<REGISTER_FILE>\\\" -DFATBINFILE=\\\"<FATBINARY>\\\" ${_CMAKE_COMPILE_AS_CUDA_FLAG} -c \"${CMAKE_CUDA_COMPILER_TOOLKIT_LIBRARY_ROOT}/bin/crt/link.stub\" -o <OBJECT>")
set(CMAKE_CUDA_DEVICE_LINK_COMPILE "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <FLAGS> <LINK_FLAGS> -D__CUDA_INCLUDE_COMPILER_INTERNAL_HEADERS__ -D__NV_EXTRA_INITIALIZATION=\"\" -D__NV_EXTRA_FINALIZATION=\"\" -DREGISTERLINKBINARYFILE=\\\"<REGISTER_FILE>\\\" -DFATBINFILE=\\\"<FATBINARY>\\\" ${_CMAKE_COMPILE_AS_CUDA_FLAG} -c \"${CMAKE_CUDA_COMPILER_TOOLKIT_LIBRARY_ROOT}/bin/crt/link.stub\" -o <OBJECT>")
endif()
unset(__IMPLICIT_DLINK_FLAGS)

View File

@@ -22,6 +22,10 @@ set(_CMAKE_CUDA_WHOLE_FLAG "-c")
set(_CMAKE_CUDA_RDC_FLAG "-fgpu-rdc")
set(_CMAKE_CUDA_PTX_FLAG "--cuda-device-only -S")
# Device linking is just regular linking so these are the same.
set(CMAKE_CUDA_DEVICE_LINKER_WRAPPER_FLAG ${CMAKE_CUDA_LINKER_WRAPPER_FLAG})
set(CMAKE_CUDA_DEVICE_LINKER_WRAPPER_FLAG_SEP ${CMAKE_CUDA_LINKER_WRAPPER_FLAG_SEP})
# RulePlaceholderExpander expands crosscompile variables like sysroot and target only for CMAKE_<LANG>_COMPILER. Override the default.
set(CMAKE_CUDA_LINK_EXECUTABLE "<CMAKE_CUDA_COMPILER> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICIT_LINKS}")
set(CMAKE_CUDA_CREATE_SHARED_LIBRARY "<CMAKE_CUDA_COMPILER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICIT_LINKS}")

View File

@@ -1410,25 +1410,23 @@ std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags(
}
void cmLocalGenerator::GetDeviceLinkFlags(
cmLinkLineComputer* linkLineComputer, const std::string& config,
cmLinkLineComputer& linkLineComputer, const std::string& config,
std::string& linkLibs, std::string& linkFlags, std::string& frameworkPath,
std::string& linkPath, cmGeneratorTarget* target)
{
cmGeneratorTarget::DeviceLinkSetter setter(*target);
cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
const std::string linkLanguage =
linkLineComputer->GetLinkerLanguage(target, config);
if (pcli) {
// Compute the required device link libraries when
// resolving gpu lang device symbols
this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, frameworkPath,
this->OutputLinkLibraries(pcli, &linkLineComputer, linkLibs, frameworkPath,
linkPath);
}
std::vector<std::string> linkOpts;
target->GetLinkOptions(linkOpts, config, linkLanguage);
target->GetLinkOptions(linkOpts, config, "CUDA");
// LINK_OPTIONS are escaped.
this->AppendCompileOptions(linkFlags, linkOpts);
}

View File

@@ -496,7 +496,7 @@ public:
/** Fill out these strings for the given target. Libraries to link,
* flags, and linkflags. */
void GetDeviceLinkFlags(cmLinkLineComputer* linkLineComputer,
void GetDeviceLinkFlags(cmLinkLineComputer& linkLineComputer,
const std::string& config, std::string& linkLibs,
std::string& linkFlags, std::string& frameworkPath,
std::string& linkPath, cmGeneratorTarget* target);

View File

@@ -170,9 +170,6 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
// Expand the rule variables.
{
bool useWatcomQuote =
this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
@@ -181,7 +178,6 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
this->LocalGenerator,
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
linkLineComputer->SetForResponse(useResponseFileForLibs);
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
linkLineComputer->SetRelink(relink);
// Collect up flags to link in needed libraries.
@@ -193,7 +189,7 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
// rule.
std::string buildObjs;
this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects,
buildObjs, depends, useWatcomQuote);
buildObjs, depends, false);
std::string const& aixExports = this->GetAIXExports(this->GetConfigName());
@@ -204,11 +200,9 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
this->LocalGenerator->MaybeRelativeToCurBinDir(objectDir),
cmOutputConverter::SHELL);
cmOutputConverter::OutputFormat output = (useWatcomQuote)
? cmOutputConverter::WATCOMQUOTE
: cmOutputConverter::SHELL;
std::string target = this->LocalGenerator->ConvertToOutputFormat(
this->LocalGenerator->MaybeRelativeToCurBinDir(targetOutput), output);
this->LocalGenerator->MaybeRelativeToCurBinDir(targetOutput),
cmOutputConverter::SHELL);
std::string targetFullPathCompilePDB =
this->ComputeTargetCompilePDB(this->GetConfigName());

View File

@@ -308,9 +308,6 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
// Expand the rule variables.
std::vector<std::string> real_link_commands;
{
bool useWatcomQuote =
this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
@@ -321,7 +318,6 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
this->LocalGenerator,
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
linkLineComputer->SetForResponse(useResponseFileForLibs);
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
linkLineComputer->SetRelink(relink);
this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
@@ -332,11 +328,7 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
std::string buildObjs;
this->CreateObjectLists(useLinkScript, false, // useArchiveRules
useResponseFileForObjects, buildObjs, depends,
useWatcomQuote);
cmOutputConverter::OutputFormat output = (useWatcomQuote)
? cmOutputConverter::WATCOMQUOTE
: cmOutputConverter::SHELL;
false);
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
objectDir = this->LocalGenerator->ConvertToOutputFormat(
@@ -344,7 +336,8 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
cmOutputConverter::SHELL);
std::string target = this->LocalGenerator->ConvertToOutputFormat(
this->LocalGenerator->MaybeRelativeToCurBinDir(targetOutput), output);
this->LocalGenerator->MaybeRelativeToCurBinDir(targetOutput),
cmOutputConverter::SHELL);
std::string targetFullPathCompilePDB =
this->ComputeTargetCompilePDB(this->GetConfigName());

View File

@@ -1530,9 +1530,9 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
return;
}
cmLocalUnixMakefileGenerator3* localGen{ this->LocalGenerator };
std::vector<std::string> architectures = cmExpandedList(architecturesStr);
std::string const& relPath =
this->LocalGenerator->GetHomeRelativeOutputPath();
std::string const& relPath = localGen->GetHomeRelativeOutputPath();
// Ensure there are no duplicates.
const std::vector<std::string> linkDeps = [&]() -> std::vector<std::string> {
@@ -1552,12 +1552,12 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
const std::string objectDir = this->GeneratorTarget->ObjectDirectory;
const std::string relObjectDir =
this->LocalGenerator->MaybeRelativeToCurBinDir(objectDir);
localGen->MaybeRelativeToCurBinDir(objectDir);
// Construct a list of files associated with this executable that
// may need to be cleaned.
std::vector<std::string> cleanFiles;
cleanFiles.push_back(this->LocalGenerator->MaybeRelativeToCurBinDir(output));
cleanFiles.push_back(localGen->MaybeRelativeToCurBinDir(output));
std::string profiles;
std::vector<std::string> fatbinaryDepends;
@@ -1594,8 +1594,8 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
" -arch=sm_", architecture, registerFileCmd, " -o=$@ ",
cmJoin(linkDeps, " "));
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, nullptr, cubin,
linkDeps, { command }, false);
localGen->WriteMakeRule(*this->BuildFileStream, nullptr, cubin, linkDeps,
{ command }, false);
}
// Combine all architectures into a single fatbinary.
@@ -1609,9 +1609,8 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
const std::string fatbinaryOutputRel =
cmStrCat(relPath, relObjectDir, "cmake_cuda_fatbin.h");
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, nullptr,
fatbinaryOutputRel, fatbinaryDepends,
{ fatbinaryCommand }, false);
localGen->WriteMakeRule(*this->BuildFileStream, nullptr, fatbinaryOutputRel,
fatbinaryDepends, { fatbinaryCommand }, false);
// Compile the stub that registers the kernels and contains the
// fatbinaries.
@@ -1625,18 +1624,21 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
vars.Fatbinary = fatbinaryOutput.c_str();
vars.RegisterFile = registerFile.c_str();
std::string linkFlags;
this->GetDeviceLinkFlags(linkFlags, "CUDA");
vars.LinkFlags = linkFlags.c_str();
std::string flags = this->GetFlags("CUDA", this->GetConfigName());
vars.Flags = flags.c_str();
std::string compileCmd = this->GetLinkRule("CMAKE_CUDA_DEVICE_LINK_COMPILE");
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
this->LocalGenerator->CreateRulePlaceholderExpander());
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
compileCmd, vars);
localGen->CreateRulePlaceholderExpander());
rulePlaceholderExpander->ExpandRuleVariables(localGen, compileCmd, vars);
commands.emplace_back(compileCmd);
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, nullptr, output,
{ fatbinaryOutputRel }, commands, false);
localGen->WriteMakeRule(*this->BuildFileStream, nullptr, output,
{ fatbinaryOutputRel }, commands, false);
// Clean all the possible executable names and symlinks.
this->CleanFiles.insert(cleanFiles.begin(), cleanFiles.end());

View File

@@ -326,6 +326,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules(
vars.Object = "$out";
vars.Fatbinary = "$FATBIN";
vars.RegisterFile = "$REGISTER";
vars.LinkFlags = "$LINK_FLAGS";
std::string flags = this->GetFlags("CUDA", config);
vars.Flags = flags.c_str();
@@ -744,9 +745,10 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatements(
return deps;
}();
cmGlobalNinjaGenerator* globalGen{ this->GetGlobalGenerator() };
const std::string objectDir =
cmStrCat(this->GeneratorTarget->GetSupportDirectory(),
this->GetGlobalGenerator()->ConfigDirectory(config));
globalGen->ConfigDirectory(config));
const std::string ninjaOutputDir = this->ConvertToNinjaPath(objectDir);
cmNinjaBuild fatbinary(this->LanguageLinkerCudaFatbinaryRule(config));
@@ -777,26 +779,37 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatements(
cmStrCat(" -im=profile=sm_", architecture, ",file=", cubin);
fatbinary.ExplicitDeps.emplace_back(cubin);
this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(), dlink);
globalGen->WriteBuild(this->GetCommonFileStream(), dlink);
}
// Combine all architectures into a single fatbinary.
fatbinary.Outputs = { cmStrCat(ninjaOutputDir, "/cmake_cuda_fatbin.h") };
this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(),
fatbinary);
globalGen->WriteBuild(this->GetCommonFileStream(), fatbinary);
// Compile the stub that registers the kernels and contains the fatbinaries.
cmLocalNinjaGenerator* localGen{ this->GetLocalGenerator() };
cmNinjaBuild dcompile(this->LanguageLinkerCudaDeviceCompileRule(config));
dcompile.Outputs = { output };
dcompile.ExplicitDeps = { cmStrCat(ninjaOutputDir, "/cmake_cuda_fatbin.h") };
dcompile.Variables["FATBIN"] =
this->GetLocalGenerator()->ConvertToOutputFormat(
cmStrCat(objectDir, "/cmake_cuda_fatbin.h"), cmOutputConverter::SHELL);
dcompile.Variables["REGISTER"] =
this->GetLocalGenerator()->ConvertToOutputFormat(
cmStrCat(objectDir, "/cmake_cuda_register.h"), cmOutputConverter::SHELL);
this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(),
dcompile);
dcompile.Variables["FATBIN"] = localGen->ConvertToOutputFormat(
cmStrCat(objectDir, "/cmake_cuda_fatbin.h"), cmOutputConverter::SHELL);
dcompile.Variables["REGISTER"] = localGen->ConvertToOutputFormat(
cmStrCat(objectDir, "/cmake_cuda_register.h"), cmOutputConverter::SHELL);
cmNinjaLinkLineDeviceComputer linkLineComputer(
localGen, localGen->GetStateSnapshot().GetDirectory(), globalGen);
linkLineComputer.SetUseNinjaMulti(globalGen->IsMultiConfig());
// Link libraries and paths are only used during the final executable/library
// link.
std::string frameworkPath;
std::string linkPath;
std::string linkLibs;
localGen->GetDeviceLinkFlags(linkLineComputer, config, linkLibs,
dcompile.Variables["LINK_FLAGS"], frameworkPath,
linkPath, this->GetGeneratorTarget());
globalGen->WriteBuild(this->GetCommonFileStream(), dcompile);
}
void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement(
@@ -850,24 +863,19 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement(
std::string createRule =
genTarget->GetCreateRuleVariable(this->TargetLinkLanguage(config), config);
const bool useWatcomQuote =
this->GetMakefile()->IsOn(createRule + "_USE_WATCOM_QUOTE");
cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
vars["TARGET_FILE"] =
localGen.ConvertToOutputFormat(output, cmOutputConverter::SHELL);
std::unique_ptr<cmLinkLineComputer> linkLineComputer(
new cmNinjaLinkLineDeviceComputer(
this->GetLocalGenerator(),
this->GetLocalGenerator()->GetStateSnapshot().GetDirectory(),
globalGen));
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
linkLineComputer->SetUseNinjaMulti(globalGen->IsMultiConfig());
cmNinjaLinkLineDeviceComputer linkLineComputer(
this->GetLocalGenerator(),
this->GetLocalGenerator()->GetStateSnapshot().GetDirectory(), globalGen);
linkLineComputer.SetUseNinjaMulti(globalGen->IsMultiConfig());
localGen.GetDeviceLinkFlags(linkLineComputer.get(), config,
vars["LINK_LIBRARIES"], vars["LINK_FLAGS"],
frameworkPath, linkPath, genTarget);
localGen.GetDeviceLinkFlags(linkLineComputer, config, vars["LINK_LIBRARIES"],
vars["LINK_FLAGS"], frameworkPath, linkPath,
genTarget);
this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, vars);

View File

@@ -448,7 +448,7 @@ run_cmake_command(NoUnusedVariables ${CMAKE_COMMAND} ${CMAKE_CURRENT_LIST_DIR}
)
# CudaSimple uses separable compilation, which is currently only supported on NVCC.
if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang")
if(CMake_TEST_CUDA)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CudaSimple-build)
run_cmake_configure(CudaSimple)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)

View File

@@ -53,16 +53,13 @@ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
run_cmake_target(genex_DEVICE_LINK interface LinkOptions_shared_interface --config Release)
run_cmake_target(genex_DEVICE_LINK private LinkOptions_private --config Release)
if (CMake_TEST_CUDA)
# Separable compilation is only supported on NVCC.
if(NOT CMake_TEST_CUDA STREQUAL "Clang")
run_cmake_target(genex_DEVICE_LINK CMP0105_UNSET LinkOptions_CMP0105_UNSET --config Release)
run_cmake_target(genex_DEVICE_LINK CMP0105_OLD LinkOptions_CMP0105_OLD --config Release)
run_cmake_target(genex_DEVICE_LINK CMP0105_NEW LinkOptions_CMP0105_NEW --config Release)
run_cmake_target(genex_DEVICE_LINK device LinkOptions_device --config Release)
run_cmake_target(genex_DEVICE_LINK CMP0105_UNSET LinkOptions_CMP0105_UNSET --config Release)
run_cmake_target(genex_DEVICE_LINK CMP0105_OLD LinkOptions_CMP0105_OLD --config Release)
run_cmake_target(genex_DEVICE_LINK CMP0105_NEW LinkOptions_CMP0105_NEW --config Release)
run_cmake_target(genex_DEVICE_LINK device LinkOptions_device --config Release)
if (RunCMake_GENERATOR MATCHES "(Ninja|Unix Makefiles)")
run_cmake_target(genex_DEVICE_LINK host_link_options LinkOptions_host_link_options --config Release ${VERBOSE})
endif()
if (RunCMake_GENERATOR MATCHES "(Ninja|Unix Makefiles)")
run_cmake_target(genex_DEVICE_LINK host_link_options LinkOptions_host_link_options --config Release ${VERBOSE})
endif()
run_cmake_target(genex_DEVICE_LINK no_device LinkOptions_no_device --config Release)

View File

@@ -1,4 +1,9 @@
if (NOT actual_stdout MATCHES "-Xlinker=OPT1 -Xlinker=OPT2 -Xlinker=OPT3 -Xlinker=OPT4 -Xlinker=OPT5")
set (RunCMake_TEST_FAILED "Not found expected '-Xlinker=OPT1 -Xlinker=OPT2 -Xlinker=OPT3 -Xlinker=OPT4 -Xlinker=OPT5'.")
if(CMake_TEST_CUDA STREQUAL "NVIDIA")
set(expected "-Xlinker=OPT1 -Xlinker=OPT2 -Xlinker=OPT3 -Xlinker=OPT4 -Xlinker=OPT5")
elseif(CMake_TEST_CUDA STREQUAL "Clang")
set(expected "-Wl,OPT1 -Xlinker OPT2 -Xlinker OPT3 -Xlinker OPT4")
endif()
if(NOT actual_stdout MATCHES "${expected}")
set(RunCMake_TEST_FAILED "Not found expected '${expected}'")
endif()

View File

@@ -25,32 +25,33 @@ target_link_options (LinkOptions_private PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEV
if (CMake_TEST_CUDA)
enable_language(CUDA)
# Separable compilation is only supported on NVCC.
if(NOT CMake_TEST_CUDA STREQUAL "Clang")
add_executable(LinkOptions_CMP0105_UNSET LinkOptionsDevice.cu)
set_property(TARGET LinkOptions_CMP0105_UNSET PROPERTY CUDA_SEPARABLE_COMPILATION ON)
target_link_options(LinkOptions_CMP0105_UNSET PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>)
add_executable(LinkOptions_CMP0105_UNSET LinkOptionsDevice.cu)
set_property(TARGET LinkOptions_CMP0105_UNSET PROPERTY CUDA_SEPARABLE_COMPILATION ON)
target_link_options(LinkOptions_CMP0105_UNSET PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>)
cmake_policy(SET CMP0105 OLD)
cmake_policy(SET CMP0105 OLD)
add_executable(LinkOptions_CMP0105_OLD LinkOptionsDevice.cu)
set_property(TARGET LinkOptions_CMP0105_OLD PROPERTY CUDA_SEPARABLE_COMPILATION ON)
target_link_options(LinkOptions_CMP0105_OLD PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>)
add_executable(LinkOptions_CMP0105_OLD LinkOptionsDevice.cu)
set_property(TARGET LinkOptions_CMP0105_OLD PROPERTY CUDA_SEPARABLE_COMPILATION ON)
target_link_options(LinkOptions_CMP0105_OLD PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>)
cmake_policy(SET CMP0105 NEW)
cmake_policy(SET CMP0105 NEW)
add_executable(LinkOptions_CMP0105_NEW LinkOptionsDevice.cu)
set_property(TARGET LinkOptions_CMP0105_NEW PROPERTY CUDA_SEPARABLE_COMPILATION ON)
target_link_options(LinkOptions_CMP0105_NEW PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>)
add_executable(LinkOptions_CMP0105_NEW LinkOptionsDevice.cu)
set_property(TARGET LinkOptions_CMP0105_NEW PROPERTY CUDA_SEPARABLE_COMPILATION ON)
target_link_options(LinkOptions_CMP0105_NEW PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>)
add_executable(LinkOptions_device LinkOptionsDevice.cu)
set_property(TARGET LinkOptions_device PROPERTY CUDA_SEPARABLE_COMPILATION ON)
target_link_options(LinkOptions_device PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>
$<HOST_LINK:${pre}BADFLAG_NORMAL_LINK${obj}>)
add_executable(LinkOptions_device LinkOptionsDevice.cu)
set_property(TARGET LinkOptions_device PROPERTY CUDA_SEPARABLE_COMPILATION ON)
target_link_options(LinkOptions_device PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>
$<HOST_LINK:${pre}BADFLAG_NORMAL_LINK${obj}>)
add_executable(LinkOptions_host_link_options LinkOptionsDevice.cu)
set_property(TARGET LinkOptions_host_link_options PROPERTY CUDA_SEPARABLE_COMPILATION ON)
add_executable(LinkOptions_host_link_options LinkOptionsDevice.cu)
set_property(TARGET LinkOptions_host_link_options PROPERTY CUDA_SEPARABLE_COMPILATION ON)
if(CMake_TEST_CUDA STREQUAL "NVIDIA")
target_link_options(LinkOptions_host_link_options PRIVATE -Wl,OPT1 -Xlinker=OPT2 "SHELL:-Xlinker OPT3" "SHELL:LINKER:OPT4 LINKER:OPT5")
elseif(CMake_TEST_CUDA STREQUAL "Clang")
target_link_options(LinkOptions_host_link_options PRIVATE -Wl,OPT1 "SHELL:-Xlinker OPT2" "SHELL:LINKER:OPT3 LINKER:OPT4")
endif()
add_executable(LinkOptions_no_device LinkOptionsDevice.cu)