summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-03-27 00:48:17 +0800
committerruki <[email protected]>2025-04-08 15:31:55 +0800
commit78db72c72e2f2d1c699c7c7010e6bd84cdbf9644 (patch)
tree9c29c804b6c9dea5128175dc3e76afde5ce07526
parent4fee5fe56d3eedb3871ee237b083bb3bcbf6ec5c (diff)
add stage jobs for target
-rw-r--r--xmake/actions/build/target_utils.lua43
-rw-r--r--xmake/modules/async/jobgraph.lua77
2 files changed, 77 insertions, 43 deletions
diff --git a/xmake/actions/build/target_utils.lua b/xmake/actions/build/target_utils.lua
index 74c57a2c9..aa6f06aa9 100644
--- a/xmake/actions/build/target_utils.lua
+++ b/xmake/actions/build/target_utils.lua
@@ -27,17 +27,30 @@ import("async.runjobs", {alias = "async_runjobs"})
import("async.jobgraph", {alias = "async_jobgraph"})
import("private.utils.batchcmds")
--- add jobs for the given target
-function _add_jobs_for_target(jobgraph, target, opt)
+-- add stage jobs for the given target
+-- stage: before, after or ""
+function _add_stage_jobs_for_target(jobgraph, target, stage, opt)
opt = opt or {}
- if not target:is_enabled() then
- return
+ local job_kind = opt.job_kind
+
+ -- the stage group, e.g. foo/after_prepare, bar/before_build
+ local group_name = string.format("%s/%s_%s", target:fullname(), stage, job_kind)
+
+ -- call target script first, e.g. before/after_prepare, before/after_build
+ local progress = opt.progress
+ local script_name = job_kind .. "_" .. stage
+ local script = target:script(script_name)
+ if script then
+ local jobname = target:fullname() .. "/" .. script_name
+ jobgraph:add(jobname, function (index, total, opt)
+ -- TODO bind target envs
+ script(target, {progress = progress})
+ end, {groups = group_name})
end
- -- add after_xxx jobs for target
- local job_kind = opt.job_kind
- local job_after = target:fullname() .. "/after_" .. job_kind
+
-- TODO we should remove root job, use group instead of it
+ --[[
jobgraph:add(job_after, function (index, total, opt)
local progress = opt.progress
local script_aftername = job_kind .. "_after"
@@ -59,7 +72,21 @@ function _add_jobs_for_target(jobgraph, target, opt)
end
end
end
- end)
+ end)]]
+end
+
+-- add jobs for the given target
+function _add_jobs_for_target(jobgraph, target, opt)
+ opt = opt or {}
+ if not target:is_enabled() then
+ return
+ end
+
+ -- add group jobs for target, e.g. after_xxx -> (depend on) on_xxx -> before_xxx
+ local group = _add_stage_jobs_for_target(jobgraph, target, "", opt)
+ local group_before = _add_stage_jobs_for_target(jobgraph, target, "before", opt)
+ local group_after = _add_stage_jobs_for_target(jobgraph, target, "after", opt)
+ jobgraph:add_deps(group_after, group, group_before)
end
-- add jobs for the given target and deps
diff --git a/xmake/modules/async/jobgraph.lua b/xmake/modules/async/jobgraph.lua
index d737c7348..3440f606b 100644
--- a/xmake/modules/async/jobgraph.lua
+++ b/xmake/modules/async/jobgraph.lua
@@ -105,54 +105,61 @@ function jobgraph:remove(name)
end
-- add job deps, e.g. add_deps(a, b, c, ...): a -> b -> c, ...
+--
+-- and it supports nil, e.g add_deps("foo", nil, "bar", ...)
+--
function jobgraph:add_deps(...)
local prev
local prev_is_group
local dag = self._dag
local jobs = self._jobs
local groups = self._groups
- for _, name in ipairs(table.pack(...)) do
- local curr_is_group = false
- local curr = jobs[name]
- if not curr then
- curr = groups[name]
- curr_is_group = true
- end
- assert(curr, "job(%s) not found in jobgraph(%s)", name, self)
- if prev then
- if prev_is_group and curr_is_group then
- -- we use a fake job as a node to bridge the two groups.
- local fakejob = {}
- for _, job in ipairs(prev) do
- if not dag:has_edge(job, fakejob) then
- dag:add_edge(job, fakejob)
+ local deps = table.pack(...)
+ for i = 1, deps.n do
+ local name = deps[i]
+ if name then
+ local curr_is_group = false
+ local curr = jobs[name]
+ if not curr then
+ curr = groups[name]
+ curr_is_group = true
+ end
+ assert(curr, "job(%s) not found in jobgraph(%s)", name, self)
+ if prev then
+ if prev_is_group and curr_is_group then
+ -- we use a fake job as a node to bridge the two groups.
+ local fakejob = {}
+ for _, job in ipairs(prev) do
+ if not dag:has_edge(job, fakejob) then
+ dag:add_edge(job, fakejob)
+ end
end
- end
- for _, job in ipairs(curr) do
- if not dag:has_edge(fakejob, job) then
- dag:add_edge(fakejob, job)
+ for _, job in ipairs(curr) do
+ if not dag:has_edge(fakejob, job) then
+ dag:add_edge(fakejob, job)
+ end
end
- end
- elseif curr_is_group then
- for _, job in ipairs(curr) do
- if not dag:has_edge(prev, job) then
- dag:add_edge(prev, job)
+ elseif curr_is_group then
+ for _, job in ipairs(curr) do
+ if not dag:has_edge(prev, job) then
+ dag:add_edge(prev, job)
+ end
end
- end
- elseif prev_is_group then
- for _, job in ipairs(prev) do
- if not dag:has_edge(job, curr) then
- dag:add_edge(job, curr)
+ elseif prev_is_group then
+ for _, job in ipairs(prev) do
+ if not dag:has_edge(job, curr) then
+ dag:add_edge(job, curr)
+ end
+ end
+ else
+ if not dag:has_edge(prev, curr) then
+ dag:add_edge(prev, curr)
end
- end
- else
- if not dag:has_edge(prev, curr) then
- dag:add_edge(prev, curr)
end
end
+ prev = curr
+ prev_is_group = curr_is_group
end
- prev = curr
- prev_is_group = curr_is_group
end
end