xmake
xmake copied to clipboard
cuda 文件对应的 object target 无法配置 devlink
Xmake 版本
xmake v2.8.5
操作系统版本和架构
Linux 720ce3a659a2 5.15.90.1-microsoft-standard-WSL2 #1 SMP Fri Jan 27 02:56:13 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
描述问题
按照 xmake 文档,对于 cuda static target,可以通过 policy 开启 devlink:
对于一些简单的场景,可以直接将 cuda 相关源码编译成 static 对象:
它也能正常 compile - devlink - ar:
但是如果是将 cuda 编译成 object target,就会缺少 devlink 的一步,即使我配置了对应的 policy:
期待的结果
希望 cuda 源码的 object target 可以在配置相应的 policy 后,生成对应的 cuda_test_kernel_gpucode.cu.o,然后添加到 target:objectfiles() 里。
工程配置
target("zgpu.cuda_util.cuda_test_kernel", function()
set_kind("object")
add_files("cuda_test_kernel.cu")
add_deps("zgpu.cuda_util.cuda_base_memory")
set_optimize("faster")
add_values("cuda.build.devlink", true)
end)
target("zgpu.cuda_util.cuda_base_memory_test", function()
set_kind("binary")
set_default(false)
add_tests("default")
add_files("cuda_base_memory_test.cc")
add_deps("zgpu.cuda_util.cuda_base_memory",
"zgpu.cuda_util.cuda_test_kernel")
add_packages("gtest")
end)
附加信息和错误日志
无
Bot detected the issue body's language is not English, translate it automatically.
Title: The object target corresponding to the cuda file cannot be configured with devlink
测试了一下,这样就 ok 了,感觉是之前的 devlink 对 object 支持不够友好:
rule("cuda_devlink", function()
on_config(function(target)
import("core.platform.platform")
-- get cuda sdk
local cuda = assert(target:data("cuda"), "Cuda SDK not found!")
-- add arch
if target:is_arch("i386", "x86") then
target:add("cuflags", "-m32", {force = true})
target:add("culdflags", "-m32", {force = true})
else
target:add("cuflags", "-m64", {force = true})
target:add("culdflags", "-m64", {force = true})
end
-- add rdc, @see https://github.com/xmake-io/xmake/issues/1975
if target:values("cuda.rdc") ~= false then
target:add("cuflags", "-rdc=true")
end
-- add links
target:add("syslinks", "cudadevrt")
local cudart = false
for _, link in ipairs(table.join(target:get("links") or {},
target:get("syslinks"))) do
if link == "cudart" or link == "cudart_static" then
cudart = true
break
end
end
if not cudart then target:add("syslinks", "cudart_static") end
if target:is_plat("linux") then
target:add("syslinks", "rt", "pthread", "dl")
end
target:add("linkdirs", cuda.linkdirs)
target:add("rpathdirs", cuda.linkdirs)
-- add includedirs
target:add("includedirs", cuda.includedirs)
end)
after_build(function(target, opt)
import("core.base.option")
import("core.tool.linker")
import("core.project.depend")
import("utils.progress")
-- load linker instance
local linkinst = linker.load("gpucode", "cu", {target = target})
-- init culdflags
local culdflags = {"-dlink"}
-- add shared flag
if target:is_shared() then table.insert(culdflags, "-shared") end
-- get link flags
local linkflags = linkinst:linkflags({
target = target,
configs = {force = {culdflags = culdflags}}
})
-- get target file
local targetfile = target:objectfile(
path.join("rules", "cuda", "devlink",
target:basename() .. "_gpucode.cu"))
-- get object files
local objectfiles = nil
for _, sourcebatch in pairs(target:sourcebatches()) do
if sourcebatch.sourcekind == "cu" then
objectfiles = sourcebatch.objectfiles
end
end
if not objectfiles then return end
-- insert gpucode.o to the object files
table.insert(target:objectfiles(), targetfile)
-- need build this target?
local depfiles = objectfiles
for _, dep in ipairs(target:orderdeps()) do
if dep:kind() == "static" then
if depfiles == objectfiles then
depfiles = table.copy(objectfiles)
end
table.insert(depfiles, dep:targetfile())
end
end
local dryrun = option.get("dry-run")
local depvalues = {linkinst:program(), linkflags}
depend.on_changed(function()
-- is verbose?
local verbose = option.get("verbose")
-- trace progress info
progress.show(opt.progress,
"${color.build.target}devlinking.$(mode) %s",
path.filename(targetfile))
-- trace verbose info
if verbose then
-- show the full link command with raw arguments, it will expand @xxx.args for msvc/link on windows
print(linkinst:linkcmd(objectfiles, targetfile,
{linkflags = linkflags, rawargs = true}))
end
-- link it
if not dryrun then
assert(linkinst:link(objectfiles, targetfile,
{linkflags = linkflags}))
end
end, {
dependfile = target:dependfile(targetfile),
lastmtime = os.mtime(targetfile),
changed = target:is_rebuilt(),
values = depvalues,
files = depfiles,
dryrun = dryrun
})
end)
end)
target("zgpu.cuda_util.cuda_test_kernel", function()
set_kind("object")
add_files("cuda_test_kernel.cu")
add_deps("zgpu.cuda_util.cuda_base_memory")
set_optimize("faster")
add_rules("cuda_devlink")
end)
devlink 作为 rule,在 before_link 执行,估计 object kind 没 link 这步骤,就没执行了
可能给 object kind 弄一个 phony link 更好?
devlink 作为 rule,在 before_link 执行,估计 object kind 没 link 这步骤,就没执行了
可能给 object kind 弄一个 phony link 更好?
感觉还是 xmake 原生支持会更好?不过目前我暂时通过 package rule 实现。
等后面有空可以看下 能否改进,最近没啥时间。
Bot detected the issue body's language is not English, translate it automatically.
I can see if I can improve it when I have time later, I don’t have much time recently.