diff options
| author | ruki <[email protected]> | 2023-04-22 00:31:06 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2023-04-22 00:31:06 +0800 |
| commit | e3ce80f3ff6b7bfa5be75eb434b4ce6ccc18554c (patch) | |
| tree | 4d25bd85e4cd20f3f18fc5380a2f2d0390e5a0fc | |
| parent | 3f3b0728c72a2562c9265d9fd162c410e03725e5 (diff) | |
add rule groups
| -rw-r--r-- | xmake/actions/build/kinds/object.lua | 142 | ||||
| -rw-r--r-- | xmake/modules/private/utils/rule_groups.lua | 153 |
2 files changed, 161 insertions, 134 deletions
diff --git a/xmake/actions/build/kinds/object.lua b/xmake/actions/build/kinds/object.lua index 05fdc939c..2782b73df 100644 --- a/xmake/actions/build/kinds/object.lua +++ b/xmake/actions/build/kinds/object.lua @@ -25,96 +25,14 @@ import("core.project.config") import("core.project.project") import("private.async.runjobs") import("private.utils.batchcmds") - --- get rule --- @note we need 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) 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 - --- has scripts for the custom rule -function _has_scripts_for_rule(ruleinst, suffix) - - -- add batch jobs for xx_build_files - local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") - local script = ruleinst:script(scriptname) - if script then - return true - end - - -- add batch jobs for xx_build_file - scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - return true - end - - -- add batch jobs for xx_buildcmd_files - scriptname = "buildcmd_files" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - return true - end - - -- add batch jobs for xx_buildcmd_file - scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "") - script = ruleinst:script(scriptname) - if script then - return true - end -end - --- has scripts for target -function _has_scripts_for_target(target, suffix) - local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") - local script = target:script(scriptname) - if script then - return true - else - scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") - script = target:script(scriptname) - if script then - return true - end - end -end - --- has scripts for group -function _has_scripts_for_group(group, suffix) - for _, item in pairs(group) do - if item.target and _has_scripts_for_target(item.target, suffix) then - return true - end - if item.rule and _has_scripts_for_rule(item.rule, suffix) then - return true - end - end -end +import("private.utils.rule_groups") -- add batch jobs for the custom rule function _add_batchjobs_for_rule(batchjobs, rootjob, target, sourcebatch, suffix) -- get rule local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!") - local ruleinst = _get_rule(target, rulename) + local ruleinst = rule_groups.get_rule(target, rulename) -- add batch jobs for xx_build_files local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") @@ -186,7 +104,7 @@ function _add_batchjobs_for_target(batchjobs, rootjob, target, sourcebatch, suff -- local rulename = sourcebatch.rulename if rulename then - local ruleinst = _get_rule(target, rulename) + local ruleinst = rule_groups.get_rule(target, rulename) if not ruleinst:script("build_file") and not ruleinst:script("build_files") then return @@ -228,67 +146,23 @@ function _add_batchjobs_for_group(batchjobs, rootjob, target, group, suffix) _add_batchjobs_for_target(batchjobs, rootjob, target, sourcebatch, suffix) end -- override on_xxx script in target? we need ignore rule scripts - if item.rule and (suffix or not _has_scripts_for_target(target, suffix)) then + if item.rule and (suffix or not rule_groups.has_scripts_for_target(target, suffix)) then _add_batchjobs_for_rule(batchjobs, rootjob, target, sourcebatch, suffix) end end 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 - -- add batch jobs for building source files function add_batchjobs_for_sourcefiles(batchjobs, rootjob, target, sourcebatches) -- build sourcebatch groups first - local groups = _build_sourcebatch_groups(target, sourcebatches) + local groups = rule_groups.build_sourcebatch_groups(target, sourcebatches) -- add batch jobs for build_after local groups_root local groups_leaf = rootjob for idx, group in ipairs(groups) do - if _has_scripts_for_group(group, "after") then + if rule_groups.has_scripts_for_group(group, "after") then batchjobs:group_enter(target:name() .. "/after_build_files" .. idx) _add_batchjobs_for_group(batchjobs, groups_leaf, target, group, "after") groups_leaf = batchjobs:group_leave() or groups_leaf @@ -298,7 +172,7 @@ function add_batchjobs_for_sourcefiles(batchjobs, rootjob, target, sourcebatches -- add batch jobs for build for idx, group in ipairs(groups) do - if _has_scripts_for_group(group) then + if rule_groups.has_scripts_for_group(group) then batchjobs:group_enter(target:name() .. "/build_files" .. idx) _add_batchjobs_for_group(batchjobs, groups_leaf, target, group) groups_leaf = batchjobs:group_leave() or groups_leaf @@ -308,7 +182,7 @@ function add_batchjobs_for_sourcefiles(batchjobs, rootjob, target, sourcebatches -- add batch jobs for build_before for idx, group in ipairs(groups) do - if _has_scripts_for_group(group, "before") then + if rule_groups.has_scripts_for_group(group, "before") then batchjobs:group_enter(target:name() .. "/before_build_files" .. idx) _add_batchjobs_for_group(batchjobs, groups_leaf, target, group, "before") groups_leaf = batchjobs:group_leave() or groups_leaf diff --git a/xmake/modules/private/utils/rule_groups.lua b/xmake/modules/private/utils/rule_groups.lua new file mode 100644 index 000000000..65ecea104 --- /dev/null +++ b/xmake/modules/private/utils/rule_groups.lua @@ -0,0 +1,153 @@ +--!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 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) 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 + +-- has scripts for the custom rule +function has_scripts_for_rule(ruleinst, suffix) + + -- add batch jobs for xx_build_files + local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") + local script = ruleinst:script(scriptname) + if script then + return true + end + + -- add batch jobs for xx_build_file + scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") + script = ruleinst:script(scriptname) + if script then + return true + end + + -- add batch jobs for xx_buildcmd_files + scriptname = "buildcmd_files" .. (suffix and ("_" .. suffix) or "") + script = ruleinst:script(scriptname) + if script then + return true + end + + -- add batch jobs for xx_buildcmd_file + scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "") + script = ruleinst:script(scriptname) + if script then + return true + end +end + +-- has scripts for target +function has_scripts_for_target(target, suffix) + local scriptname = "build_files" .. (suffix and ("_" .. suffix) or "") + local script = target:script(scriptname) + if script then + return true + else + scriptname = "build_file" .. (suffix and ("_" .. suffix) or "") + script = target:script(scriptname) + if script then + return true + end + end +end + +-- has scripts for group +function has_scripts_for_group(group, suffix) + for _, item in pairs(group) do + if item.target and has_scripts_for_target(item.target, suffix) then + return true + end + if item.rule and has_scripts_for_rule(item.rule, suffix) then + return true + end + end +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 + |
