summaryrefslogtreecommitdiff
path: root/xmake/rules/cuda/devlink/devlink.lua
diff options
context:
space:
mode:
authorruki <[email protected]>2023-08-11 23:46:43 +0800
committerruki <[email protected]>2023-08-11 23:46:43 +0800
commit8951d5ba9a3ec367c2d995f9d2187752b5567953 (patch)
treeac328ed6eb8975c29446a9c09498000d1561c96d /xmake/rules/cuda/devlink/devlink.lua
parent898698717c518de2ca6f3354e0dd29bfb436187e (diff)
improve devlink
Diffstat (limited to 'xmake/rules/cuda/devlink/devlink.lua')
-rw-r--r--xmake/rules/cuda/devlink/devlink.lua111
1 files changed, 111 insertions, 0 deletions
diff --git a/xmake/rules/cuda/devlink/devlink.lua b/xmake/rules/cuda/devlink/devlink.lua
new file mode 100644
index 000000000..9b76c9775
--- /dev/null
+++ b/xmake/rules/cuda/devlink/devlink.lua
@@ -0,0 +1,111 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file devlink.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.theme.theme")
+import("core.project.config")
+import("core.project.depend")
+import("core.tool.linker")
+import("core.platform.platform")
+import("utils.progress")
+
+-- @see https://devblogs.nvidia.com/separate-compilation-linking-cuda-device-code/
+function main(target, opt)
+
+ -- disable devlink?
+ --
+ -- @note cuda.build.devlink value will be deprecated
+ --
+ local devlink = target:policy("build.cuda.devlink") or target:values("cuda.build.devlink")
+ if devlink == false then
+ return
+ end
+
+ -- only for binary/shared by default
+ -- https://github.com/xmake-io/xmake/issues/1976
+ if not (devlink == true or target:is_binary() or target:is_shared()) then
+ return
+ end
+
+ -- 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), values = depvalues, files = depfiles, always_changed = dryrun})
+end