From abd58c9c0e5043d73b127de9cd387e416bd5090f Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 8 Apr 2025 00:44:33 +0800 Subject: prepare targets for more generators --- xmake/plugins/project/utils/target_cmds.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'xmake/plugins/project/utils/target_cmds.lua') diff --git a/xmake/plugins/project/utils/target_cmds.lua b/xmake/plugins/project/utils/target_cmds.lua index 332e4858d..debc6fdc5 100644 --- a/xmake/plugins/project/utils/target_cmds.lua +++ b/xmake/plugins/project/utils/target_cmds.lua @@ -25,6 +25,7 @@ import("core.base.hashset") import("core.project.rule") import("private.utils.batchcmds") import("private.utils.rule_groups") +import("private.action.build.target", {alias = "target_buildutils"}) -- this sourcebatch is built? function _sourcebatch_is_built(sourcebatch) @@ -115,3 +116,9 @@ function get_target_buildcmd_sourcegroups(target, cmds, sourcegroups, opt) end end +-- prepare targets +function prepare_targets() + local targets_root = target_buildutils.get_root_targets() + target_buildutils.run_targetjobs(targets_root, {job_kind = "prepare"}) +end + -- cgit v1.3.1 From 77d90d253447ea6992f4f0a81d8df219e23b499c Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 9 Apr 2025 23:42:30 +0800 Subject: improve target_cmds --- .../modules/private/action/build/build_binary.lua | 6 +- .../private/action/build/build_moduleonly.lua | 4 +- .../modules/private/action/build/build_object.lua | 4 +- .../modules/private/action/build/build_shared.lua | 4 +- .../modules/private/action/build/build_static.lua | 4 +- .../modules/private/action/build/link_objects.lua | 8 +- .../modules/private/action/build/prepare_files.lua | 4 +- xmake/modules/private/action/build/target.lua | 118 +++++++++++++++------ xmake/plugins/project/cmake/cmakelists.lua | 13 +-- xmake/plugins/project/utils/target_cmds.lua | 47 ++++++++ 10 files changed, 156 insertions(+), 56 deletions(-) (limited to 'xmake/plugins/project/utils/target_cmds.lua') diff --git a/xmake/modules/private/action/build/build_binary.lua b/xmake/modules/private/action/build/build_binary.lua index 72263e6c8..3863b8550 100644 --- a/xmake/modules/private/action/build/build_binary.lua +++ b/xmake/modules/private/action/build/build_binary.lua @@ -22,16 +22,16 @@ import("build_object") import("private.action.build.target", {alias = "target_buildutils"}) -function main(jobgraph, target) +function main(jobgraph, target, opt) local objects_group = target:fullname() .. "/objects" local jobsize = jobgraph:size() jobgraph:group(objects_group, function () - build_object(jobgraph, target) + build_object(jobgraph, target, opt) end) if jobgraph:size() > jobsize then local link_group = target:fullname() .. "/link" jobgraph:group(link_group, function () - target_buildutils.add_linkjobs(jobgraph, target) + target_buildutils.add_linkjobs(jobgraph, target, opt) end) jobgraph:add_orders(objects_group, link_group) end diff --git a/xmake/modules/private/action/build/build_moduleonly.lua b/xmake/modules/private/action/build/build_moduleonly.lua index e3cc87c27..32c07375e 100644 --- a/xmake/modules/private/action/build/build_moduleonly.lua +++ b/xmake/modules/private/action/build/build_moduleonly.lua @@ -21,6 +21,6 @@ -- imports import("build_object") -function main(jobgraph, target) - build_object(jobgraph, target) +function main(jobgraph, target, opt) + build_object(jobgraph, target, opt) end diff --git a/xmake/modules/private/action/build/build_object.lua b/xmake/modules/private/action/build/build_object.lua index 2a6baa59a..08f82092b 100644 --- a/xmake/modules/private/action/build/build_object.lua +++ b/xmake/modules/private/action/build/build_object.lua @@ -21,6 +21,6 @@ -- imports import("private.action.build.target", {alias = "target_buildutils"}) -function main(jobgraph, target) - target_buildutils.add_filejobs(jobgraph, target, {job_kind = "build"}) +function main(jobgraph, target, opt) + target_buildutils.add_filejobs(jobgraph, target, opt) end diff --git a/xmake/modules/private/action/build/build_shared.lua b/xmake/modules/private/action/build/build_shared.lua index 077489710..9223093b4 100644 --- a/xmake/modules/private/action/build/build_shared.lua +++ b/xmake/modules/private/action/build/build_shared.lua @@ -21,6 +21,6 @@ -- imports import("build_binary") -function main(jobgraph, target) - build_binary(jobgraph, target) +function main(jobgraph, target, opt) + build_binary(jobgraph, target, opt) end diff --git a/xmake/modules/private/action/build/build_static.lua b/xmake/modules/private/action/build/build_static.lua index 8b9b2ffaf..6d47394ed 100644 --- a/xmake/modules/private/action/build/build_static.lua +++ b/xmake/modules/private/action/build/build_static.lua @@ -21,6 +21,6 @@ -- imports import("build_binary") -function main(jobgraph, target) - build_binary(jobgraph, target) +function main(jobgraph, target, opt) + build_binary(jobgraph, target, opt) end diff --git a/xmake/modules/private/action/build/link_objects.lua b/xmake/modules/private/action/build/link_objects.lua index 25214d27e..396896d00 100644 --- a/xmake/modules/private/action/build/link_objects.lua +++ b/xmake/modules/private/action/build/link_objects.lua @@ -60,9 +60,13 @@ function _do_link_target(target, opt) values = depvalues, files = depfiles, dryrun = dryrun}) end -function main(jobgraph, target) +function main(jobgraph, target, opt) + opt = opt or {} + local buildcmds = opt.buildcmds local linkjob = target:fullname() .. "/link_objects" jobgraph:add(linkjob, function (index, total, opt) - _do_link_target(target, opt) + if not buildcmds then + _do_link_target(target, opt) + end end) end diff --git a/xmake/modules/private/action/build/prepare_files.lua b/xmake/modules/private/action/build/prepare_files.lua index d8ca351ca..9f0f47ef0 100644 --- a/xmake/modules/private/action/build/prepare_files.lua +++ b/xmake/modules/private/action/build/prepare_files.lua @@ -22,6 +22,6 @@ import("core.base.option") import("private.action.build.target", {alias = "target_buildutils"}) -function main(jobgraph, target) - target_buildutils.add_filejobs(jobgraph, target, {job_kind = "prepare"}) +function main(jobgraph, target, opt) + target_buildutils.add_filejobs(jobgraph, target, opt) end diff --git a/xmake/modules/private/action/build/target.lua b/xmake/modules/private/action/build/target.lua index beb6f9cb2..68f6bda53 100644 --- a/xmake/modules/private/action/build/target.lua +++ b/xmake/modules/private/action/build/target.lua @@ -119,14 +119,16 @@ function _add_targetjobs_orders(jobgraph, target, dep, opt) end -- add target jobs for the builtin script -function add_targetjobs_for_builtin_script(jobgraph, target, job_kind) +function add_targetjobs_for_builtin_script(jobgraph, target, opt) + opt = opt or {} + local job_kind = opt.job_kind if target:is_static() or target:is_binary() or target:is_shared() or target:is_object() or target:is_moduleonly() then if job_kind == "prepare" then - import("private.action.build.prepare_files", {anonymous = true})(jobgraph, target) + import("private.action.build.prepare_files", {anonymous = true})(jobgraph, target, opt) elseif job_kind == "link" then - import("private.action.build.link_objects", {anonymous = true})(jobgraph, target) + import("private.action.build.link_objects", {anonymous = true})(jobgraph, target, opt) else - import("private.action.build.build_" .. target:kind(), {anonymous = true})(jobgraph, target) + import("private.action.build.build_" .. target:kind(), {anonymous = true})(jobgraph, target, opt) end end end @@ -135,6 +137,7 @@ end function add_targetjobs_for_script(jobgraph, target, instance, opt) opt = opt or {} local has_script = false + local buildcmds = opt.buildcmds local job_prefix = target:fullname() if target == instance then job_prefix = job_prefix .. "/target" @@ -143,7 +146,7 @@ function add_targetjobs_for_script(jobgraph, target, instance, opt) end -- call script - if not has_script then + if not has_script and not buildcmds then local script_name = opt.script_name local script = instance:script(script_name) if script then @@ -185,9 +188,14 @@ function add_targetjobs_for_script(jobgraph, target, instance, opt) if scriptcmd then local jobname = string.format("%s/%s", job_prefix, scriptcmd_name) jobgraph:add(jobname, function (index, total, opt) - local batchcmds_ = batchcmds.new({target = target}) - scriptcmd(target, batchcmds_, {progress = opt.progress}) - batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) + if buildcmds then + -- only generate cmds and do not run them, use cases: e.g. project generator + scriptcmd(target, buildcmds, {progress = opt.progress}) + else + local batchcmds_ = batchcmds.new({target = target}) + scriptcmd(target, batchcmds_, {progress = opt.progress}) + batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) + end end) has_script = true end @@ -220,7 +228,8 @@ function add_targetjobs_with_stage(jobgraph, target, stage, opt) local has_script = false local script_opt = { script_name = script_name, - scriptcmd_name = scriptcmd_name + scriptcmd_name = scriptcmd_name, + buildcmds = opt.buildcmds } for _, instance in ipairs(instances) do -- we need to use this group to sort rule scripts with add_orders @@ -238,7 +247,7 @@ function add_targetjobs_with_stage(jobgraph, target, stage, opt) -- call builtin script, e.g. on_prepare, on_build, ... if not has_script and stage == "" then - add_targetjobs_for_builtin_script(jobgraph, target, job_kind) + add_targetjobs_for_builtin_script(jobgraph, target, opt) end end) @@ -265,10 +274,15 @@ function add_targetjobs(jobgraph, target, opt) _g.pkgenvs = pkgenvs end + local buildcmds = opt.buildcmds local job_kind = opt.job_kind local job_begin = string.format("%s/begin_%s", target:fullname(), job_kind) local job_end = string.format("%s/end_%s", target:fullname(), job_kind) jobgraph:add(job_begin, function (index, total, opt) + if buildcmds then + return + end + -- enter package environments -- https://github.com/xmake-io/xmake/issues/4033 -- @@ -293,6 +307,10 @@ function add_targetjobs(jobgraph, target, opt) end) jobgraph:add(job_end, function (index, total, opt) + if buildcmds then + return + end + -- restore environments if target:pkgenvs() then pkgenvs.oldenvs = pkgenvs.oldenvs or os.getenvs() @@ -307,9 +325,17 @@ function add_targetjobs(jobgraph, target, opt) end) -- add jobs with target stage, e.g. begin -> before_xxx -> on_xxx -> after_xxx - local group = add_targetjobs_with_stage(jobgraph, target, "", opt) - local group_before = add_targetjobs_with_stage(jobgraph, target, "before", opt) - local group_after = add_targetjobs_with_stage(jobgraph, target, "after", opt) + local with_stages = opt.with_stages + local group, group_before, group_after + if not with_stages or with_stages:has("on") then + group = add_targetjobs_with_stage(jobgraph, target, "", opt) + end + if not with_stages or with_stages:has("before") then + group_before = add_targetjobs_with_stage(jobgraph, target, "before", opt) + end + if not with_stages or with_stages:has("after") then + group_after = add_targetjobs_with_stage(jobgraph, target, "after", opt) + end jobgraph:add_orders(job_begin, group_before, group, group_after, job_end) end @@ -341,6 +367,7 @@ end function add_filejobs_for_script(jobgraph, target, instance, sourcebatch, opt) opt = opt or {} local has_script = false + local buildcmds = opt.buildcmds local job_prefix = target:fullname() local file_group = sourcebatch.rulename if target == instance then @@ -350,7 +377,7 @@ function add_filejobs_for_script(jobgraph, target, instance, sourcebatch, opt) end -- call script files - if not has_script then + if not has_script and not buildcmds then local script_files_name = opt.script_files_name local script_files = instance:script(script_files_name) if script_files then @@ -383,7 +410,7 @@ function add_filejobs_for_script(jobgraph, target, instance, sourcebatch, opt) end -- call script file - if not has_script then + if not has_script and not buildcmds then local script_file_name = opt.script_file_name local script_file = instance:script(script_file_name) if script_file then @@ -434,9 +461,14 @@ function add_filejobs_for_script(jobgraph, target, instance, sourcebatch, opt) local distcc = instance:extraconf(scriptcmd_files_name, "distcc") local jobname = string.format("%s/%s", job_prefix, scriptcmd_files_name) jobgraph:add(jobname, function (index, total, opt) - local batchcmds_ = batchcmds.new({target = target}) - scriptcmd_files(target, batchcmds_, sourcebatch, {progress = opt.progress, distcc = distcc}) - batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) + -- only generate cmds and do not run them, use cases: e.g. project generator + if buildcmds then + scriptcmd_files(target, buildcmds, sourcebatch, {progress = opt.progress}) + else + local batchcmds_ = batchcmds.new({target = target}) + scriptcmd_files(target, batchcmds_, sourcebatch, {progress = opt.progress, distcc = distcc}) + batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) + end end) has_script = true end @@ -455,12 +487,20 @@ function add_filejobs_for_script(jobgraph, target, instance, sourcebatch, opt) local distcc = instance:extraconf(scriptcmd_file_name, "distcc") local jobname = string.format("%s/%s", job_prefix, scriptcmd_file_name) jobgraph:add(jobname, function (index, total, opt) - local batchcmds_ = batchcmds.new({target = target}) - local sourcekind = sourcebatch.sourcekind - for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - scriptcmd_file(target, batchcmds_, sourcefile, {progress = opt.progress, sourcekind = sourcekind, distcc = distcc}) + -- only generate cmds and do not run them, use cases: e.g. project generator + if buildcmds then + local sourcekind = sourcebatch.sourcekind + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + scriptcmd_file(target, buildcmds, sourcefile, {sourcekind = sourcekind}) + end + else + local batchcmds_ = batchcmds.new({target = target}) + local sourcekind = sourcebatch.sourcekind + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + scriptcmd_file(target, batchcmds_, sourcefile, {progress = opt.progress, sourcekind = sourcekind, distcc = distcc}) + end + batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) end - batchcmds_:runcmds({changed = target:is_rebuilt(), dryrun = option.get("dry-run")}) end) has_script = true end @@ -473,6 +513,7 @@ end -- function add_filejobs_with_stage(jobgraph, target, sourcebatches, stage, opt) opt = opt or {} + local buildcmds = opt.buildcmds local job_kind = opt.job_kind local job_kind_file = job_kind .. "_file" local job_kind_files = job_kind .. "_files" @@ -523,7 +564,8 @@ function add_filejobs_with_stage(jobgraph, target, sourcebatches, stage, opt) script_file_name = script_file_name, script_files_name = script_files_name, scriptcmd_file_name = scriptcmd_file_name, - scriptcmd_files_name = scriptcmd_files_name + scriptcmd_files_name = scriptcmd_files_name, + buildcmds = buildcmds } local has_target_script = false for _, instance in ipairs(instances) do @@ -575,9 +617,17 @@ function add_filejobs(jobgraph, target, opt) end -- add file jobs with target stage, e.g. before_xxx_files -> on_xxx_files -> after_xxx_files - local group = add_filejobs_with_stage(jobgraph, target, sourcebatches, "", opt) - local group_before = add_filejobs_with_stage(jobgraph, target, sourcebatches, "before", opt) - local group_after = add_filejobs_with_stage(jobgraph, target, sourcebatches, "after", opt) + local with_stages = opt.with_stages + local group, group_before, group_after + if not with_stages or with_stages:has("on") then + group = add_filejobs_with_stage(jobgraph, target, sourcebatches, "", opt) + end + if not with_stages or with_stages:has("before") then + group_before = add_filejobs_with_stage(jobgraph, target, sourcebatches, "before", opt) + end + if not with_stages or with_stages:has("after") then + group_after = add_filejobs_with_stage(jobgraph, target, sourcebatches, "after", opt) + end jobgraph:add_orders(group_before, group, group_after) end @@ -608,9 +658,17 @@ end function add_linkjobs(jobgraph, target, opt) opt = opt or {} opt.job_kind = "link" - local group = add_targetjobs_with_stage(jobgraph, target, "", opt) - local group_before = add_targetjobs_with_stage(jobgraph, target, "before", opt) - local group_after = add_targetjobs_with_stage(jobgraph, target, "after", opt) + local with_stages = opt.with_stages + local group, group_before, group_after + if not with_stages or with_stages:has("on") then + group = add_targetjobs_with_stage(jobgraph, target, "", opt) + end + if not with_stages or with_stages:has("before") then + group_before = add_targetjobs_with_stage(jobgraph, target, "before", opt) + end + if not with_stages or with_stages:has("after") then + group_after = add_targetjobs_with_stage(jobgraph, target, "after", opt) + end jobgraph:add_orders(group_before, group, group_after) end diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua index f826cc453..9d2fc453a 100644 --- a/xmake/plugins/project/cmake/cmakelists.lua +++ b/xmake/plugins/project/cmake/cmakelists.lua @@ -29,7 +29,6 @@ import("core.project.rule") import("core.platform.platform") import("lib.detect.find_tool") import("private.utils.batchcmds") -import("private.utils.rule_groups") import("private.utils.target", {alias = "target_utils"}) import("plugins.project.utils.target_cmds", {rootdir = os.programdir()}) import("rules.c++.modules.modules_support.compiler_support", {alias = "module_compiler_support", rootdir = os.programdir()}) @@ -1201,9 +1200,6 @@ end -- add target custom commands function _add_target_custom_commands(cmakelists, target, outputdir) - -- build sourcebatch groups first - local sourcegroups = rule_groups.build_sourcebatch_groups(target, target:sourcebatches()) - -- ignore c++ modules rules local ignored_rules if _can_native_support_for_cxxmodules() then @@ -1212,17 +1208,12 @@ function _add_target_custom_commands(cmakelists, target, outputdir) -- add before commands -- we use irpairs(groups), because the last group that should be given the highest priority. - local cmds_before = {} - target_cmds.get_target_buildcmd(target, cmds_before, {suffix = "before", ignored_rules = ignored_rules}) - target_cmds.get_target_buildcmd_sourcegroups(target, cmds_before, sourcegroups, {suffix = "before", ignored_rules = ignored_rules}) -- rule.on_buildcmd_files should also be executed before building the target, as cmake PRE_BUILD does not work. - target_cmds.get_target_buildcmd_sourcegroups(target, cmds_before, sourcegroups, {ignored_rules = ignored_rules}) + local cmds_before = target_cmds.get_target_buildcmds(target, {ignored_rules = ignored_rules, stages = {"before", "on"}}) _add_target_custom_commands_for_batchcmds(cmakelists, target, outputdir, "before", cmds_before) -- add after commands - local cmds_after = {} - target_cmds.get_target_buildcmd_sourcegroups(target, cmds_after, sourcegroups, {suffix = "after", ignored_rules = ignored_rules}) - target_cmds.get_target_buildcmd(target, cmds_after, {suffix = "after", ignored_rules = ignored_rules}) + local cmds_after = target_cmds.get_target_buildcmds(target, {ignored_rules = ignored_rules, stages = {"after"}}) _add_target_custom_commands_for_batchcmds(cmakelists, target, outputdir, "after", cmds_after) end diff --git a/xmake/plugins/project/utils/target_cmds.lua b/xmake/plugins/project/utils/target_cmds.lua index debc6fdc5..c25a2c3e3 100644 --- a/xmake/plugins/project/utils/target_cmds.lua +++ b/xmake/plugins/project/utils/target_cmds.lua @@ -122,3 +122,50 @@ function prepare_targets() target_buildutils.run_targetjobs(targets_root, {job_kind = "prepare"}) end +-- get target buildcmds +function get_target_buildcmds(target, opt) + opt = opt or {} + local progress_wrapper = {} + progress_wrapper.current = function () + return count + end + progress_wrapper.total = function () + return total + end + progress_wrapper.percent = function () + if total and total > 0 then + return math.floor((count * 100) / total) + else + return 0 + end + end + debug.setmetatable(progress_wrapper, { + __tostring = function () + -- we do not output any progress info for the project generators + return "" + end + }) + local buildcmds = batchcmds.new({target = target}) + local jobgraph = target_buildutils.get_targetjobs({target}, { + job_kind = "build", + buildcmds = buildcmds, + with_stages = hashset.from(opt.stages or {}), + ignored_rules = hashset.from(opt.ignored_rules or {}), + progress = progress_wrapper}) + if jobgraph and not jobgraph:empty() then + local jobqueue = jobgraph:build() + while true do + local job = jobqueue:getfree() + if job then + if job.run then + job.run() + end + jobqueue:remove(job) + else + break + end + end + end + return buildcmds:cmds() +end + -- cgit v1.3.1 From 4109abcddf430a8fad253566b23db6f8c73b5366 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 9 Apr 2025 23:44:19 +0800 Subject: ignore rules and stages --- xmake/modules/private/action/build/target.lua | 38 ++++++++++++++++----------- xmake/plugins/project/utils/target_cmds.lua | 8 +++--- 2 files changed, 28 insertions(+), 18 deletions(-) (limited to 'xmake/plugins/project/utils/target_cmds.lua') diff --git a/xmake/modules/private/action/build/target.lua b/xmake/modules/private/action/build/target.lua index 68f6bda53..477dd3023 100644 --- a/xmake/modules/private/action/build/target.lua +++ b/xmake/modules/private/action/build/target.lua @@ -208,6 +208,7 @@ end function add_targetjobs_with_stage(jobgraph, target, stage, opt) opt = opt or {} local job_kind = opt.job_kind + local ignored_rules = opt.ignored_rules -- the group name, e.g. foo/after_prepare, bar/before_build local group_name = string.format("%s/%s_%s", target:fullname(), stage ~= "" and stage or "on", job_kind) @@ -220,8 +221,11 @@ function add_targetjobs_with_stage(jobgraph, target, stage, opt) -- call target and rules script local instances = {target} - for _, r in ipairs(target:orderules()) do - table.insert(instances, r) + for _, ruleinst in ipairs(target:orderules()) do + -- we only ignore some builtin rules, so we need not to use fullname. + if not ignored_rules or not ignored_rules:has(ruleinst:name()) then + table.insert(instances, ruleinst) + end end local jobsize = jobgraph:size() jobgraph:group(group_name, function () @@ -491,7 +495,7 @@ function add_filejobs_for_script(jobgraph, target, instance, sourcebatch, opt) if buildcmds then local sourcekind = sourcebatch.sourcekind for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - scriptcmd_file(target, buildcmds, sourcefile, {sourcekind = sourcekind}) + scriptcmd_file(target, buildcmds, sourcefile, {progress = opt.progress, sourcekind = sourcekind}) end else local batchcmds_ = batchcmds.new({target = target}) @@ -514,6 +518,7 @@ end function add_filejobs_with_stage(jobgraph, target, sourcebatches, stage, opt) opt = opt or {} local buildcmds = opt.buildcmds + local ignored_rules = opt.ignored_rules local job_kind = opt.job_kind local job_kind_file = job_kind .. "_file" local job_kind_files = job_kind .. "_files" @@ -538,20 +543,23 @@ function add_filejobs_with_stage(jobgraph, target, sourcebatches, stage, opt) for _, sourcebatch in pairs(sourcebatches) do local rulename = sourcebatch.rulename if rulename then + -- we only ignore some builtin rules, so we need not to use fullname. local ruleinst = rule_utils.get_rule(target, rulename) - sourcebatches_map[ruleinst] = sourcebatch - -- avoid duplicate scripts being called twice in the target, - -- we just build sourcebatch with on_build_files scripts - -- - -- for example, c++.build and c++.build.modules.builder rules have same sourcefiles, - -- but we just build it for c++.build - -- - -- @see https://github.com/xmake-io/xmake/issues/3171 - -- - if ruleinst:script("build_file") or ruleinst:script("build_files") then - table.insert(sourcebatches_for_target, sourcebatch) + if not ignored_rules or not ignored_rules:has(ruleinst:name()) then + sourcebatches_map[ruleinst] = sourcebatch + -- avoid duplicate scripts being called twice in the target, + -- we just build sourcebatch with on_build_files scripts + -- + -- for example, c++.build and c++.build.modules.builder rules have same sourcefiles, + -- but we just build it for c++.build + -- + -- @see https://github.com/xmake-io/xmake/issues/3171 + -- + if ruleinst:script("build_file") or ruleinst:script("build_files") then + table.insert(sourcebatches_for_target, sourcebatch) + end + table.insert(instances, ruleinst) end - table.insert(instances, ruleinst) else table.insert(sourcebatches_for_target, sourcebatch) end diff --git a/xmake/plugins/project/utils/target_cmds.lua b/xmake/plugins/project/utils/target_cmds.lua index c25a2c3e3..835117d50 100644 --- a/xmake/plugins/project/utils/target_cmds.lua +++ b/xmake/plugins/project/utils/target_cmds.lua @@ -150,17 +150,19 @@ function get_target_buildcmds(target, opt) job_kind = "build", buildcmds = buildcmds, with_stages = hashset.from(opt.stages or {}), - ignored_rules = hashset.from(opt.ignored_rules or {}), - progress = progress_wrapper}) + ignored_rules = hashset.from(opt.ignored_rules or {})}) if jobgraph and not jobgraph:empty() then + local total = jobgraph:size() + local index = 0 local jobqueue = jobgraph:build() while true do local job = jobqueue:getfree() if job then if job.run then - job.run() + job.run(index, total, {progress = progress_wrapper}) end jobqueue:remove(job) + index = index + 1 else break end -- cgit v1.3.1 From 699e40f3e45469b3597f5fa24ad6bb2c922b8a4b Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 9 Apr 2025 23:48:29 +0800 Subject: move rule_group to deprecated --- xmake/actions/build/deprecated/kinds/object.lua | 2 +- .../actions/build/deprecated/kinds/rule_groups.lua | 95 ++++++++++++++++++++++ xmake/modules/private/utils/rule_groups.lua | 95 ---------------------- xmake/plugins/project/clang/compile_commands.lua | 14 +--- xmake/plugins/project/utils/target_cmds.lua | 90 -------------------- xmake/plugins/project/vstudio/impl/vs201x.lua | 17 ++-- 6 files changed, 103 insertions(+), 210 deletions(-) create mode 100644 xmake/actions/build/deprecated/kinds/rule_groups.lua delete mode 100644 xmake/modules/private/utils/rule_groups.lua (limited to 'xmake/plugins/project/utils/target_cmds.lua') diff --git a/xmake/actions/build/deprecated/kinds/object.lua b/xmake/actions/build/deprecated/kinds/object.lua index b5359f79e..c4ed8721a 100644 --- a/xmake/actions/build/deprecated/kinds/object.lua +++ b/xmake/actions/build/deprecated/kinds/object.lua @@ -25,7 +25,7 @@ import("core.project.config") import("core.project.project") import("async.runjobs") import("private.utils.batchcmds") -import("private.utils.rule_groups") +import("rule_groups") -- has scripts for the custom rule function _has_scripts_for_rule(ruleinst, suffix) diff --git a/xmake/actions/build/deprecated/kinds/rule_groups.lua b/xmake/actions/build/deprecated/kinds/rule_groups.lua new file mode 100644 index 000000000..d64a75d62 --- /dev/null +++ b/xmake/actions/build/deprecated/kinds/rule_groups.lua @@ -0,0 +1,95 @@ +--!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 rule_groups.lua +-- + +-- imports +import("core.base.option") +import("core.project.rule") +import("core.project.config") +import("core.project.project") + +-- get rule +-- @note we need to get rule from target first, because we maybe will inject and replace builtin rule in target +function get_rule(target, rulename) + local ruleinst = assert(target:rule(rulename) or project.rule(rulename, {namespace = target:namespace()}) or + rule.rule(rulename), "unknown rule: %s", rulename) + return ruleinst +end + +-- get max depth of rule +function _get_rule_max_depth(target, ruleinst, depth) + local max_depth = depth + for _, depname in ipairs(ruleinst:get("deps")) do + local dep = get_rule(target, depname) + local dep_depth = depth + if ruleinst:extraconf("deps", depname, "order") then + dep_depth = dep_depth + 1 + end + local cur_depth = _get_rule_max_depth(target, dep, dep_depth) + if cur_depth > max_depth then + max_depth = cur_depth + end + end + return max_depth +end + +-- build sourcebatch groups for target +function _build_sourcebatch_groups_for_target(groups, target, sourcebatches) + local group = groups[1] + for _, sourcebatch in pairs(sourcebatches) do + local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!") + local item = group[rulename] or {} + item.target = target + item.sourcebatch = sourcebatch + group[rulename] = item + end +end + +-- build sourcebatch groups for rules +function _build_sourcebatch_groups_for_rules(groups, target, sourcebatches) + for _, sourcebatch in pairs(sourcebatches) do + local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!") + local ruleinst = get_rule(target, rulename) + local depth = _get_rule_max_depth(target, ruleinst, 1) + local group = groups[depth] + if group == nil then + group = {} + groups[depth] = group + end + local item = group[rulename] or {} + item.rule = ruleinst + item.sourcebatch = sourcebatch + group[rulename] = item + end +end + +-- build sourcebatch groups by rule dependencies order, e.g. `add_deps("qt.ui", {order = true})` +-- +-- @see https://github.com/xmake-io/xmake/issues/2814 +-- +function build_sourcebatch_groups(target, sourcebatches) + local groups = {{}} + _build_sourcebatch_groups_for_target(groups, target, sourcebatches) + _build_sourcebatch_groups_for_rules(groups, target, sourcebatches) + if #groups > 0 then + groups = table.reverse(groups) + end + return groups +end + diff --git a/xmake/modules/private/utils/rule_groups.lua b/xmake/modules/private/utils/rule_groups.lua deleted file mode 100644 index d64a75d62..000000000 --- a/xmake/modules/private/utils/rule_groups.lua +++ /dev/null @@ -1,95 +0,0 @@ ---!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 rule_groups.lua --- - --- imports -import("core.base.option") -import("core.project.rule") -import("core.project.config") -import("core.project.project") - --- get rule --- @note we need to get rule from target first, because we maybe will inject and replace builtin rule in target -function get_rule(target, rulename) - local ruleinst = assert(target:rule(rulename) or project.rule(rulename, {namespace = target:namespace()}) or - rule.rule(rulename), "unknown rule: %s", rulename) - return ruleinst -end - --- get max depth of rule -function _get_rule_max_depth(target, ruleinst, depth) - local max_depth = depth - for _, depname in ipairs(ruleinst:get("deps")) do - local dep = get_rule(target, depname) - local dep_depth = depth - if ruleinst:extraconf("deps", depname, "order") then - dep_depth = dep_depth + 1 - end - local cur_depth = _get_rule_max_depth(target, dep, dep_depth) - if cur_depth > max_depth then - max_depth = cur_depth - end - end - return max_depth -end - --- build sourcebatch groups for target -function _build_sourcebatch_groups_for_target(groups, target, sourcebatches) - local group = groups[1] - for _, sourcebatch in pairs(sourcebatches) do - local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!") - local item = group[rulename] or {} - item.target = target - item.sourcebatch = sourcebatch - group[rulename] = item - end -end - --- build sourcebatch groups for rules -function _build_sourcebatch_groups_for_rules(groups, target, sourcebatches) - for _, sourcebatch in pairs(sourcebatches) do - local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!") - local ruleinst = get_rule(target, rulename) - local depth = _get_rule_max_depth(target, ruleinst, 1) - local group = groups[depth] - if group == nil then - group = {} - groups[depth] = group - end - local item = group[rulename] or {} - item.rule = ruleinst - item.sourcebatch = sourcebatch - group[rulename] = item - end -end - --- build sourcebatch groups by rule dependencies order, e.g. `add_deps("qt.ui", {order = true})` --- --- @see https://github.com/xmake-io/xmake/issues/2814 --- -function build_sourcebatch_groups(target, sourcebatches) - local groups = {{}} - _build_sourcebatch_groups_for_target(groups, target, sourcebatches) - _build_sourcebatch_groups_for_rules(groups, target, sourcebatches) - if #groups > 0 then - groups = table.reverse(groups) - end - return groups -end - diff --git a/xmake/plugins/project/clang/compile_commands.lua b/xmake/plugins/project/clang/compile_commands.lua index c36cb8ade..4cf6eb1ab 100644 --- a/xmake/plugins/project/clang/compile_commands.lua +++ b/xmake/plugins/project/clang/compile_commands.lua @@ -27,7 +27,6 @@ import("core.project.project") import("core.language.language") import("private.utils.batchcmds") import("private.utils.executable_path") -import("private.utils.rule_groups") import("plugins.project.utils.target_cmds", {rootdir = os.programdir()}) import("actions.test.main", {rootdir = os.programdir(), alias = "test_action"}) @@ -242,25 +241,16 @@ end -- add target commands function _add_target_commands(jsonfile, target) - -- build sourcebatch groups first - local sourcegroups = rule_groups.build_sourcebatch_groups(target, target:sourcebatches()) - -- add before commands -- we use irpairs(groups), because the last group that should be given the highest priority. - local cmds_before = {} - target_cmds.get_target_buildcmd(target, cmds_before, {suffix = "before"}) - target_cmds.get_target_buildcmd_sourcegroups(target, cmds_before, sourcegroups, {suffix = "before"}) - -- rule.on_buildcmd_files should also be executed before building the target, as cmake PRE_BUILD does not work. - target_cmds.get_target_buildcmd_sourcegroups(target, cmds_before, sourcegroups) + local cmds_before = target_cmds.get_target_buildcmds(target, {stages = {"before", "on"}}) _add_target_custom_commands(jsonfile, target, "before", cmds_before) -- add target source commands _add_target_source_commands(jsonfile, target) -- add after commands - local cmds_after = {} - target_cmds.get_target_buildcmd_sourcegroups(target, cmds_after, sourcegroups, {suffix = "after"}) - target_cmds.get_target_buildcmd(target, cmds_after, {suffix = "after"}) + local cmds_after = target_cmds.get_target_buildcmds(target, {stages = {"after"}}) _add_target_custom_commands(jsonfile, target, "after", cmds_after) end diff --git a/xmake/plugins/project/utils/target_cmds.lua b/xmake/plugins/project/utils/target_cmds.lua index 835117d50..b18acb943 100644 --- a/xmake/plugins/project/utils/target_cmds.lua +++ b/xmake/plugins/project/utils/target_cmds.lua @@ -24,98 +24,8 @@ import("core.project.config") import("core.base.hashset") import("core.project.rule") import("private.utils.batchcmds") -import("private.utils.rule_groups") import("private.action.build.target", {alias = "target_buildutils"}) --- this sourcebatch is built? -function _sourcebatch_is_built(sourcebatch) - -- we can only use rulename to filter them because sourcekind may be bound to multiple rules - local rulename = sourcebatch.rulename - if rulename == "c.build" or rulename == "c++.build" - or rulename == "asm.build" or rulename == "cuda.build" - or rulename == "objc.build" or rulename == "objc++.build" - or rulename == "win.sdk.resource" then - return true - end -end - --- get target buildcmd commands -function get_target_buildcmd(target, cmds, opt) - opt = opt or {} - local suffix = opt.suffix - local ignored_rules = hashset.from(opt.ignored_rules or {}) - for _, ruleinst in ipairs(target:orderules()) do - if not ignored_rules:has(ruleinst:name()) then - local scriptname = "buildcmd" .. (suffix and ("_" .. suffix) or "") - local script = ruleinst:script(scriptname) - if script then - local batchcmds_ = batchcmds.new({target = target}) - script(target, batchcmds_, {}) - if not batchcmds_:empty() then - table.join2(cmds, batchcmds_:cmds()) - end - end - end - end -end - --- get target buildcmd_files commands -function get_target_buildcmd_files(target, cmds, sourcebatch, opt) - opt = opt or {} - - -- get rule - local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!") - local ruleinst = assert(target:rule(rulename) or project.rule(rulename, {namespace = target:namespace()}) or - rule.rule(rulename), "unknown rule: %s", rulename) - local ignored_rules = hashset.from(opt.ignored_rules or {}) - if ignored_rules:has(ruleinst:name()) then - return - end - - -- generate commands for xx_buildcmd_files - local suffix = opt.suffix - local scriptname = "buildcmd_files" .. (suffix and ("_" .. suffix) or "") - local script = ruleinst:script(scriptname) - if script then - local batchcmds_ = batchcmds.new({target = target}) - script(target, batchcmds_, sourcebatch, {}) - if not batchcmds_:empty() then - table.join2(cmds, batchcmds_:cmds()) - end - end - - -- generate commands for xx_buildcmd_file - if not script then - scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - local sourcekind = sourcebatch.sourcekind - for _, sourcefile in ipairs(sourcebatch.sourcefiles) do - local batchcmds_ = batchcmds.new({target = target}) - script(target, batchcmds_, sourcefile, {}) - if not batchcmds_:empty() then - table.join2(cmds, batchcmds_:cmds()) - end - end - end - end -end - --- get target buildcmd commands of source group -function get_target_buildcmd_sourcegroups(target, cmds, sourcegroups, opt) - for idx, group in irpairs(sourcegroups) do - for _, item in pairs(group) do - -- buildcmd scripts are always in rule, so we need to ignore target item (item.target). - local sourcebatch = item.sourcebatch - if item.rule then - if not _sourcebatch_is_built(sourcebatch) then - get_target_buildcmd_files(target, cmds, sourcebatch, opt) - end - end - end - end -end - -- prepare targets function prepare_targets() local targets_root = target_buildutils.get_root_targets() diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua index 0a23a1847..e3b9ddc95 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x.lua @@ -39,7 +39,6 @@ import("private.action.require.install", {alias = "install_requires"}) import("private.action.run.runenvs") import("actions.config.configfiles", {alias = "generate_configfiles", rootdir = os.programdir()}) import("private.utils.batchcmds") -import("private.utils.rule_groups") import("plugins.project.utils.target_cmds", {rootdir = os.programdir()}) function _translate_path(dir, vcxprojdir) @@ -132,24 +131,18 @@ function _make_custom_commands(target, vcxprojdir) return _translate_path(p, vcxprojdir) end) - -- build sourcebatch groups first - local sourcegroups = rule_groups.build_sourcebatch_groups(target, target:sourcebatches()) - -- ignore c++ modules rules local ignored_rules = _get_cxxmodules_rules() -- add before commands -- we use irpairs(groups), because the last group that should be given the highest priority. - local cmds_before = {} - target_cmds.get_target_buildcmd(target, cmds_before, {suffix = "before", ignored_rules = ignored_rules}) - target_cmds.get_target_buildcmd_sourcegroups(target, cmds_before, sourcegroups, {suffix = "before", ignored_rules = ignored_rules}) - -- rule.on_buildcmd_files should also be executed before building the target, as cmake PRE_BUILD does not work. - target_cmds.get_target_buildcmd_sourcegroups(target, cmds_before, sourcegroups, {ignored_rules = ignored_rules}) + -- rule.on_buildcmd_files should also be executed before building the target + local cmds_before = target_cmds.get_target_buildcmds(target, {ignored_rules = ignored_rules, stages = {"before", "on"}}) + _add_target_custom_commands_for_batchcmds(cmakelists, target, outputdir, "before", cmds_before) -- add after commands - local cmds_after = {} - target_cmds.get_target_buildcmd_sourcegroups(target, cmds_after, sourcegroups, {suffix = "after", ignored_rules = ignored_rules}) - target_cmds.get_target_buildcmd(target, cmds_after, {suffix = "after", ignored_rules = ignored_rules}) + local cmds_after = target_cmds.get_target_buildcmds(target, {ignored_rules = ignored_rules, stages = {"after"}}) + _add_target_custom_commands_for_batchcmds(cmakelists, target, outputdir, "after", cmds_after) local commands = {} for _, cmd in ipairs(cmds_before) do -- cgit v1.3.1