summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2023-04-22 00:36:27 +0800
committerruki <[email protected]>2023-04-22 00:36:27 +0800
commit1e31f3a9da25e2f2b287dc1b4462e71d53fabf80 (patch)
treefbb316f2561526f32b00879b5f19ef382c47365f
parente3ce80f3ff6b7bfa5be75eb434b4ce6ccc18554c (diff)
improve cmakelists for rule order
-rw-r--r--xmake/actions/build/kinds/object.lua67
-rw-r--r--xmake/modules/private/utils/rule_groups.lua59
-rw-r--r--xmake/plugins/project/cmake/cmakelists.lua46
3 files changed, 102 insertions, 70 deletions
diff --git a/xmake/actions/build/kinds/object.lua b/xmake/actions/build/kinds/object.lua
index 2782b73df..df24db2cb 100644
--- a/xmake/actions/build/kinds/object.lua
+++ b/xmake/actions/build/kinds/object.lua
@@ -27,6 +27,65 @@ import("private.async.runjobs")
import("private.utils.batchcmds")
import("private.utils.rule_groups")
+-- 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
+
-- add batch jobs for the custom rule
function _add_batchjobs_for_rule(batchjobs, rootjob, target, sourcebatch, suffix)
@@ -146,7 +205,7 @@ 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 rule_groups.has_scripts_for_target(target, suffix)) then
+ if item.rule and (suffix or not _has_scripts_for_target(target, suffix)) then
_add_batchjobs_for_rule(batchjobs, rootjob, target, sourcebatch, suffix)
end
end
@@ -162,7 +221,7 @@ function add_batchjobs_for_sourcefiles(batchjobs, rootjob, target, sourcebatches
local groups_root
local groups_leaf = rootjob
for idx, group in ipairs(groups) do
- if rule_groups.has_scripts_for_group(group, "after") then
+ if _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
@@ -172,7 +231,7 @@ function add_batchjobs_for_sourcefiles(batchjobs, rootjob, target, sourcebatches
-- add batch jobs for build
for idx, group in ipairs(groups) do
- if rule_groups.has_scripts_for_group(group) then
+ if _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
@@ -182,7 +241,7 @@ function add_batchjobs_for_sourcefiles(batchjobs, rootjob, target, sourcebatches
-- add batch jobs for build_before
for idx, group in ipairs(groups) do
- if rule_groups.has_scripts_for_group(group, "before") then
+ if _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
index 65ecea104..f8f8181ec 100644
--- a/xmake/modules/private/utils/rule_groups.lua
+++ b/xmake/modules/private/utils/rule_groups.lua
@@ -48,65 +48,6 @@ function _get_rule_max_depth(target, ruleinst, depth)
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]
diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua
index f2c683e13..00e8c077b 100644
--- a/xmake/plugins/project/cmake/cmakelists.lua
+++ b/xmake/plugins/project/cmake/cmakelists.lua
@@ -28,6 +28,7 @@ import("core.base.hashset")
import("core.project.rule")
import("lib.detect.find_tool")
import("private.utils.batchcmds")
+import("private.utils.rule_groups")
-- get minimal cmake version
function _get_cmake_minver()
@@ -895,6 +896,9 @@ end
-- add target custom commands for batchcmds
function _add_target_custom_commands_for_batchcmds(cmakelists, target, outputdir, suffix, cmds)
+ if #cmds == 0 then
+ return
+ end
if suffix == "before" then
-- ADD_CUSTOM_COMMAND and PRE_BUILD did not work as I expected,
-- so we need use add_dependencies and fake target to support it.
@@ -978,26 +982,54 @@ function _add_target_custom_commands_for_objectrules(cmakelists, target, sourceb
end
end
end
+function _add_batchjobs_for_group(batchjobs, rootjob, target, group, suffix)
+ for _, item in pairs(group) do
+ local sourcebatch = item.sourcebatch
+ if item.target then
+ _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 rule_groups.has_scripts_for_target(target, suffix)) then
+ _add_batchjobs_for_rule(batchjobs, rootjob, target, sourcebatch, suffix)
+ end
+ end
+end
+
-- add target custom commands
function _add_target_custom_commands(cmakelists, target, outputdir)
+ -- build sourcebatch groups first
+ local groups = rule_groups.build_sourcebatch_groups(target, target:sourcebatches())
+
-- add before commands
local cmds_before = {}
_add_target_custom_commands_for_target(cmakelists, target, cmds_before, "before")
- for _, sourcebatch in table.orderpairs(target:sourcebatches()) do
- if not _sourcebatch_is_built(sourcebatch) then
- _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, cmds_before, "before")
- _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, cmds_before)
+ for idx, group in irpairs(groups) do
+ for _, item in pairs(group) do
+ -- buildcmd scripts are always in rule, so we need ignore target item (item.target).
+ local sourcebatch = item.sourcebatch
+ if item.rule then
+ if not _sourcebatch_is_built(sourcebatch) then
+ _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, cmds_before, "before")
+ _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, cmds_before)
+ end
+ end
end
end
_add_target_custom_commands_for_batchcmds(cmakelists, target, outputdir, "before", cmds_before)
-- add after commands
local cmds_after = {}
- for _, sourcebatch in table.orderpairs(target:sourcebatches()) do
- if not _sourcebatch_is_built(sourcebatch) then
- _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, cmds_after, "after")
+ for idx, group in irpairs(groups) do
+ for _, item in pairs(group) do
+ -- buildcmd scripts are always in rule, so we need ignore target item (item.target).
+ local sourcebatch = item.sourcebatch
+ if item.rule then
+ if not _sourcebatch_is_built(sourcebatch) then
+ _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, cmds_after, "after")
+ end
+ end
end
end
_add_target_custom_commands_for_target(cmakelists, target, cmds_after, "after")