diff options
| author | ruki <[email protected]> | 2025-03-27 00:48:17 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2025-04-08 15:31:55 +0800 |
| commit | 78db72c72e2f2d1c699c7c7010e6bd84cdbf9644 (patch) | |
| tree | 9c29c804b6c9dea5128175dc3e76afde5ce07526 | |
| parent | 4fee5fe56d3eedb3871ee237b083bb3bcbf6ec5c (diff) | |
add stage jobs for target
| -rw-r--r-- | xmake/actions/build/target_utils.lua | 43 | ||||
| -rw-r--r-- | xmake/modules/async/jobgraph.lua | 77 |
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 |
