summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-06-17 23:49:50 +0800
committerruki <[email protected]>2026-06-17 23:49:50 +0800
commiteba488dafedd88c1f19e23132276872aac877b73 (patch)
treea577ac74585545b465b12caa03480d7665f2f5d6
parentba2df770b8430a8f8e593d34dc05de051a59a1bd (diff)
add targets arugment support
-rw-r--r--xmake/actions/build/main.lua22
-rw-r--r--xmake/actions/build/xmake.lua6
-rw-r--r--xmake/actions/clean/main.lua21
-rw-r--r--xmake/actions/clean/xmake.lua6
-rw-r--r--xmake/actions/install/install.lua16
-rw-r--r--xmake/actions/install/install_admin.lua5
-rw-r--r--xmake/actions/install/main.lua21
-rw-r--r--xmake/actions/install/xmake.lua6
-rw-r--r--xmake/actions/package/local/main.lua16
-rw-r--r--xmake/actions/package/oldpkg/main.lua18
-rw-r--r--xmake/actions/package/remote/main.lua12
-rw-r--r--xmake/actions/package/xmake.lua6
-rw-r--r--xmake/actions/uninstall/main.lua8
-rw-r--r--xmake/actions/uninstall/uninstall.lua16
-rw-r--r--xmake/actions/uninstall/uninstall_admin.lua5
-rw-r--r--xmake/actions/uninstall/xmake.lua6
-rw-r--r--xmake/modules/private/action/utils.lua25
-rw-r--r--xmake/plugins/format/main.lua12
-rw-r--r--xmake/plugins/format/xmake.lua4
-rw-r--r--xmake/rules/xcode/application/install.lua2
20 files changed, 155 insertions, 78 deletions
diff --git a/xmake/actions/build/main.lua b/xmake/actions/build/main.lua
index aa8a8c089..9b0fcc1e2 100644
--- a/xmake/actions/build/main.lua
+++ b/xmake/actions/build/main.lua
@@ -41,7 +41,7 @@ import("private.action.utils", {alias = "action_utils"})
import("private.detect.check_targetname")
-- try building it
-function _do_try_build(configfile, tool, trybuild, trybuild_detected, targetname)
+function _do_try_build(configfile, tool, trybuild, trybuild_detected, targetnames)
if configfile and tool and (trybuild or utils.confirm({default = true,
description = "${bright}" .. path.filename(configfile) .. "${clear} found, try building it or you can run `${bright}xmake f --trybuild=${clear}` to set buildsystem"})) then
if not trybuild then
@@ -59,9 +59,9 @@ function _try_build()
config.load()
-- rebuild it? do clean first
- local targetname = option.get("target")
+ local targetnames = action_utils.get_targets_and_group()
if option.get("rebuild") then
- task.run("clean", {target = targetname})
+ task.run("clean", {targets = targetnames})
end
-- get the buildsystem tool
@@ -76,14 +76,14 @@ function _try_build()
else
raise("unknown build tool: %s", trybuild)
end
- return _do_try_build(configfile, tool, trybuild, trybuild_detected, targetname)
+ return _do_try_build(configfile, tool, trybuild, trybuild_detected, targetnames)
else
for _, name in ipairs({"xrepo", "autoconf", "cmake", "meson", "scons", "bazel", "msbuild", "xcodebuild", "make", "ninja", "ndkbuild"}) do
tool = import("private.action.trybuild." .. name, {anonymous = true})
configfile = tool.detect()
if configfile then
trybuild_detected = name
- if _do_try_build(configfile, tool, trybuild, trybuild_detected, targetname) then
+ if _do_try_build(configfile, tool, trybuild, trybuild_detected, targetnames) then
return true
end
end
@@ -196,12 +196,14 @@ function main(opt)
project.lock()
-- config it first
- local targetname, group_pattern = action_utils.get_target_and_group()
+ local targetnames, group_pattern = action_utils.get_targets_and_group()
task.run("config", {}, {disable_dump = true})
- -- check target name
- if targetname then
- assert(check_targetname(targetname))
+ -- check target names
+ if targetnames then
+ for _, targetname in ipairs(targetnames) do
+ assert(check_targetname(targetname))
+ end
end
-- enter project directory
@@ -212,7 +214,7 @@ function main(opt)
-- build targets
local build_time = os.mclock()
- build_targets(targetname, {group_pattern = group_pattern})
+ build_targets(targetnames, {group_pattern = group_pattern})
build_time = os.mclock() - build_time
-- leave project directory
diff --git a/xmake/actions/build/xmake.lua b/xmake/actions/build/xmake.lua
index 832a98725..655b28207 100644
--- a/xmake/actions/build/xmake.lua
+++ b/xmake/actions/build/xmake.lua
@@ -22,7 +22,7 @@ task("build")
set_category("main")
on_run("main")
set_menu {
- usage = "xmake [task] [options] [target]"
+ usage = "xmake [task] [options] [targets]"
, description = "Build targets if no given tasks."
, shortname = 'b'
, options =
@@ -53,7 +53,9 @@ task("build")
" - xmake --files='src/main.c" .. path.envsep() .. "src/test.c'" }
, {}
- , {nil, "target", "v", nil , "The target name. It will build all default targets if this parameter is not specified."
+ , {nil, "targets", "vs", nil , "The target names. It will build all default targets if this parameter is not specified.",
+ "e.g.",
+ " xmake build target1 target2 ..."
, values = function (complete, opt) return import("private.utils.complete_helper.targets")(complete, opt) end }
}
}
diff --git a/xmake/actions/clean/main.lua b/xmake/actions/clean/main.lua
index c4abe6956..a85fca742 100644
--- a/xmake/actions/clean/main.lua
+++ b/xmake/actions/clean/main.lua
@@ -30,6 +30,7 @@ import("private.action.clean.remove_files")
import("target.action.clean", {alias = "_do_clean_target"})
import("private.service.remote_build.action", {alias = "remote_build_action"})
import("private.detect.check_targetname")
+import("private.action.utils", {alias = "action_utils"})
-- on clean target
function _on_clean_target(target)
@@ -103,11 +104,13 @@ function _clean_targets(targets)
end
end
--- clean target
-function _clean(targetname)
- if targetname then
- local target = assert(check_targetname(targetname))
- _clean_target(target)
+-- clean targets
+function _clean(targetnames)
+ if targetnames and #targetnames > 0 then
+ for _, targetname in ipairs(targetnames) do
+ local target = assert(check_targetname(targetname))
+ _clean_target(target)
+ end
else
_clean_targets(project.ordertargets())
end
@@ -163,14 +166,14 @@ function main()
-- lock the whole project
project.lock()
- -- get the target name
- local targetname = option.get("target")
+ -- get the target names
+ local targetnames = action_utils.get_targets_and_group()
-- enter project directory
local oldir = os.cd(project.directory())
- -- clean target
- _clean(targetname)
+ -- clean targets
+ _clean(targetnames)
-- unlock the whole project
project.unlock()
diff --git a/xmake/actions/clean/xmake.lua b/xmake/actions/clean/xmake.lua
index 4f66dd205..b2968e118 100644
--- a/xmake/actions/clean/xmake.lua
+++ b/xmake/actions/clean/xmake.lua
@@ -23,7 +23,7 @@ task("clean")
on_run("main")
set_menu {
- usage = "xmake clean|c [options] [target]"
+ usage = "xmake clean|c [options] [targets]"
, description = "Remove all binary and temporary files."
, shortname = 'c'
@@ -32,7 +32,9 @@ task("clean")
{'a', "all", "k", nil , "Clean all auto-generated files by xmake." }
, {}
- , {nil, "target", "v", nil , "The target name. It will clean all default targets if this parameter is not specified."
+ , {nil, "targets", "vs", nil , "The target names. It will clean all default targets if this parameter is not specified.",
+ "e.g.",
+ " xmake clean target1 target2 ..."
, values = function (complete, opt) return import("private.utils.complete_helper.targets")(complete, opt) end }
}
}
diff --git a/xmake/actions/install/install.lua b/xmake/actions/install/install.lua
index 232f4f9c0..33fc4a795 100644
--- a/xmake/actions/install/install.lua
+++ b/xmake/actions/install/install.lua
@@ -111,15 +111,21 @@ function _install_targets(targets)
end
-- install targets
-function main(targetname, group_pattern)
+--
+-- @param targetnames the target names (table), a single target name, or the magic "__all"/"__def"
+--
+function main(targetnames, group_pattern)
local targets = {}
- if targetname and not targetname:startswith("__") then
- local target = project.target(targetname)
- table.insert(targets, target)
+ if type(targetnames) == "table" then
+ for _, targetname in ipairs(targetnames) do
+ table.insert(targets, project.target(targetname))
+ end
+ elseif targetnames and not targetnames:startswith("__") then
+ table.insert(targets, project.target(targetnames))
else
for _, target in ipairs(project.ordertargets()) do
local group = target:get("group")
- if (target:is_default() and not group_pattern) or targetname == "__all" or (group_pattern and group and group:match(group_pattern)) then
+ if (target:is_default() and not group_pattern) or targetnames == "__all" or (group_pattern and group and group:match(group_pattern)) then
table.insert(targets, target)
end
end
diff --git a/xmake/actions/install/install_admin.lua b/xmake/actions/install/install_admin.lua
index 22d6da524..61f02da89 100644
--- a/xmake/actions/install/install_admin.lua
+++ b/xmake/actions/install/install_admin.lua
@@ -27,6 +27,11 @@ import("install")
function main(targetname, group_pattern, installdir, bindir, libdir, includedir)
local verbose = option.get("verbose")
+
+ -- the targetname may be a list of target names joined with the path separator
+ if targetname and targetname:find(path.envsep(), 1, true) then
+ targetname = path.splitenv(targetname)
+ end
if group_pattern and #group_pattern == 0 then
group_pattern = nil
end
diff --git a/xmake/actions/install/main.lua b/xmake/actions/install/main.lua
index e6c8258fc..80b428cab 100644
--- a/xmake/actions/install/main.lua
+++ b/xmake/actions/install/main.lua
@@ -30,12 +30,14 @@ import("install")
import("private.action.utils", {alias = "action_utils"})
-- check targets
-function _check_targets(targetname, group_pattern)
+function _check_targets(targetnames, group_pattern)
-- get targets
local targets = {}
- if targetname then
- table.insert(targets, project.target(targetname))
+ if targetnames and #targetnames > 0 then
+ for _, targetname in ipairs(targetnames) do
+ table.insert(targets, project.target(targetname))
+ end
else
-- install default or all targets
for _, target in pairs(project.targets()) do
@@ -69,14 +71,17 @@ function main()
task.run("config", {require = false}, {disable_dump = true})
-- check targets first
- local targetname, group_pattern = action_utils.get_target_and_group()
- _check_targets(targetname, group_pattern)
+ local targetnames, group_pattern = action_utils.get_targets_and_group()
+ _check_targets(targetnames, group_pattern)
+
+ -- get the install targets argument, it may be a list of target names or the magic "__all"/"__def"
+ local targets_arg = targetnames or (option.get("all") and "__all" or "__def")
-- attempt to install directly
try
{
function ()
- install(targetname or (option.get("all") and "__all" or "__def"), group_pattern)
+ install(targets_arg, group_pattern)
cprint("${color.success}install ok!")
end,
@@ -90,7 +95,7 @@ function main()
local ok = try
{
function ()
- install(targetname or (option.get("all") and "__all" or "__def"), group_pattern)
+ install(targets_arg, group_pattern)
cprint("${color.success}install ok!")
return true
end
@@ -109,7 +114,7 @@ function main()
-- install target with administrator permission
sudo.execl(path.join(os.scriptdir(), "install_admin.lua"), {
- targetname or (option.get("all") and "__all" or "__def"),
+ type(targets_arg) == "table" and table.concat(targets_arg, path.envsep()) or targets_arg,
group_pattern or "", option.get("installdir") or "",
option.get("bindir"),
option.get("libdir"),
diff --git a/xmake/actions/install/xmake.lua b/xmake/actions/install/xmake.lua
index 3ef6a22c3..679ddbc81 100644
--- a/xmake/actions/install/xmake.lua
+++ b/xmake/actions/install/xmake.lua
@@ -22,7 +22,7 @@ task("install")
set_category("action")
on_run("main")
set_menu {
- usage = "xmake install|i [options] [target]",
+ usage = "xmake install|i [options] [targets]",
description = "Package and install the target binary files.",
shortname = 'i',
options = {
@@ -47,7 +47,9 @@ task("install")
{},
{nil, "admin", "k", nil , "Try to request administrator permission to install"},
{},
- {nil, "target", "v", nil , "The target name. It will install all default targets if this parameter is not specified.",
+ {nil, "targets", "vs", nil , "The target names. It will install all default targets if this parameter is not specified.",
+ "e.g.",
+ " xmake install target1 target2 ...",
values = function (complete, opt)
return import("private.utils.complete_helper.targets")(complete, opt)
end}
diff --git a/xmake/actions/package/local/main.lua b/xmake/actions/package/local/main.lua
index 408b9ad76..48b0ce5bd 100644
--- a/xmake/actions/package/local/main.lua
+++ b/xmake/actions/package/local/main.lua
@@ -223,16 +223,18 @@ function main()
-- lock the whole project
project.lock()
- -- get the target name
- local targetname = option.get("target")
+ -- get the target names
+ local targetnames = option.get("targets")
-- build it first
- task.run("build", {target = targetname, all = option.get("all")})
+ task.run("build", {targets = targetnames, all = option.get("all")})
- -- package the given target?
- if targetname then
- local target = assert(check_targetname(targetname))
- _package_target(target)
+ -- package the given targets?
+ if targetnames and #targetnames > 0 then
+ for _, targetname in ipairs(targetnames) do
+ local target = assert(check_targetname(targetname))
+ _package_target(target)
+ end
else
-- package default or all targets
for _, target in ipairs(project.ordertargets()) do
diff --git a/xmake/actions/package/oldpkg/main.lua b/xmake/actions/package/oldpkg/main.lua
index 82d5d07f1..f9b543cc0 100644
--- a/xmake/actions/package/oldpkg/main.lua
+++ b/xmake/actions/package/oldpkg/main.lua
@@ -183,17 +183,19 @@ function main()
-- lock the whole project
project.lock()
- -- get the target name
- local targetname = option.get("target")
+ -- get the target names
+ local targetnames = option.get("targets")
-- build it first
- task.run("build", {target = targetname, all = option.get("all")})
+ task.run("build", {targets = targetnames, all = option.get("all")})
- -- package the given target?
- if targetname then
- local target = assert(check_targetname(targetname))
- _package_targets(target:orderdeps())
- _package_target(target)
+ -- package the given targets?
+ if targetnames and #targetnames > 0 then
+ for _, targetname in ipairs(targetnames) do
+ local target = assert(check_targetname(targetname))
+ _package_targets(target:orderdeps())
+ _package_target(target)
+ end
else
-- package default or all targets
for _, target in ipairs(project.ordertargets()) do
diff --git a/xmake/actions/package/remote/main.lua b/xmake/actions/package/remote/main.lua
index 45746eb69..27e7afc89 100644
--- a/xmake/actions/package/remote/main.lua
+++ b/xmake/actions/package/remote/main.lua
@@ -151,11 +151,13 @@ function main()
-- load config
config.load()
- -- package the given target?
- local targetname = option.get("target")
- if targetname then
- local target = assert(check_targetname(targetname))
- _package_target(target)
+ -- package the given targets?
+ local targetnames = option.get("targets")
+ if targetnames and #targetnames > 0 then
+ for _, targetname in ipairs(targetnames) do
+ local target = assert(check_targetname(targetname))
+ _package_target(target)
+ end
else
-- package default or all targets
for _, target in ipairs(project.ordertargets()) do
diff --git a/xmake/actions/package/xmake.lua b/xmake/actions/package/xmake.lua
index 283edc815..d64a1e454 100644
--- a/xmake/actions/package/xmake.lua
+++ b/xmake/actions/package/xmake.lua
@@ -22,7 +22,7 @@ task("package")
set_category("action")
on_run("main")
set_menu {
- usage = "xmake package|p [options] [target]",
+ usage = "xmake package|p [options] [targets]",
description = "Package target.",
shortname = 'p',
options = {
@@ -37,7 +37,9 @@ task("package")
{nil, "version", "kv", nil, "Set the version of remote package."},
{nil, "shasum", "kv", nil, "Set the sha256 or commit of remote package."},
{},
- {nil, "target", "v", nil, "The target name. It will package all default targets if this parameter is not specified.",
+ {nil, "targets", "vs", nil, "The target names. It will package all default targets if this parameter is not specified.",
+ "e.g.",
+ " xmake package target1 target2 ...",
values = function (complete, opt)
return import("private.utils.complete_helper.targets")(complete, opt)
end }
diff --git a/xmake/actions/uninstall/main.lua b/xmake/actions/uninstall/main.lua
index 4fb411892..840f12450 100644
--- a/xmake/actions/uninstall/main.lua
+++ b/xmake/actions/uninstall/main.lua
@@ -33,11 +33,11 @@ function main()
task.run("config", {require = false}, {disable_dump = true})
-- attempt to uninstall directly, TODO group_pattern
- local targetname, group_pattern = action_utils.get_target_and_group()
+ local targetnames, group_pattern = action_utils.get_targets_and_group()
try
{
function ()
- uninstall(targetname)
+ uninstall(targetnames)
cprint("${color.success}uninstall ok!")
end,
@@ -51,7 +51,7 @@ function main()
local ok = try
{
function ()
- uninstall(targetname)
+ uninstall(targetnames)
cprint("${color.success}uninstall ok!")
return true
end
@@ -70,7 +70,7 @@ function main()
-- uninstall target with administrator permission
sudo.execl(path.join(os.scriptdir(), "uninstall_admin.lua"), {
- targetname or "__all",
+ targetnames and table.concat(targetnames, path.envsep()) or "__all",
option.get("installdir") or "",
option.get("bindir"),
option.get("libdir"),
diff --git a/xmake/actions/uninstall/uninstall.lua b/xmake/actions/uninstall/uninstall.lua
index 9a95da9dd..9ebc32d20 100644
--- a/xmake/actions/uninstall/uninstall.lua
+++ b/xmake/actions/uninstall/uninstall.lua
@@ -106,15 +106,21 @@ function _uninstall_targets(targets)
end
-- uninstall
-function main(targetname)
+--
+-- @param targetnames the target names (table), a single target name, or the magic "__all"/"__def"
+--
+function main(targetnames, group_pattern)
local targets = {}
- if targetname and not targetname:startswith("__") then
- local target = project.target(targetname)
- table.insert(targets, target)
+ if type(targetnames) == "table" then
+ for _, targetname in ipairs(targetnames) do
+ table.insert(targets, project.target(targetname))
+ end
+ elseif targetnames and not targetnames:startswith("__") then
+ table.insert(targets, project.target(targetnames))
else
for _, target in ipairs(project.ordertargets()) do
local group = target:get("group")
- if (target:is_default() and not group_pattern) or targetname == "__all" or (group_pattern and group and group:match(group_pattern)) then
+ if (target:is_default() and not group_pattern) or targetnames == "__all" or (group_pattern and group and group:match(group_pattern)) then
table.insert(targets, target)
end
end
diff --git a/xmake/actions/uninstall/uninstall_admin.lua b/xmake/actions/uninstall/uninstall_admin.lua
index b8d654c3d..9c6bd4a53 100644
--- a/xmake/actions/uninstall/uninstall_admin.lua
+++ b/xmake/actions/uninstall/uninstall_admin.lua
@@ -27,6 +27,11 @@ import("uninstall")
function main(targetname, installdir, bindir, libdir, includedir)
local verbose = option.get("verbose")
+
+ -- the targetname may be a list of target names joined with the path separator
+ if targetname and targetname:find(path.envsep(), 1, true) then
+ targetname = path.splitenv(targetname)
+ end
if installdir and #installdir == 0 then
installdir = nil
end
diff --git a/xmake/actions/uninstall/xmake.lua b/xmake/actions/uninstall/xmake.lua
index 72ba9c3f2..a31b7736b 100644
--- a/xmake/actions/uninstall/xmake.lua
+++ b/xmake/actions/uninstall/xmake.lua
@@ -22,7 +22,7 @@ task("uninstall")
set_category("action")
on_run("main")
set_menu {
- usage = "xmake uninstall|u [options] [target]",
+ usage = "xmake uninstall|u [options] [targets]",
description = "Uninstall the project binary files.",
shortname = 'u',
options = {
@@ -41,7 +41,9 @@ task("uninstall")
" xmake uninstall --group=benchmark/*" },
{nil, "admin", "k", nil , "Try to request administrator permission to uninstall"},
{ },
- {nil, "target", "v", nil , "The target name. It will uninstall all default targets if this parameter is not specified.",
+ {nil, "targets", "vs", nil , "The target names. It will uninstall all default targets if this parameter is not specified.",
+ "e.g.",
+ " xmake uninstall target1 target2 ...",
values = function (complete, opt)
return import("private.utils.complete_helper.targets")(complete, opt)
end}
diff --git a/xmake/modules/private/action/utils.lua b/xmake/modules/private/action/utils.lua
index 9b83b59ab..c31735c54 100644
--- a/xmake/modules/private/action/utils.lua
+++ b/xmake/modules/private/action/utils.lua
@@ -32,3 +32,28 @@ function get_target_and_group()
end
return targetname, group_pattern
end
+
+-- get target names and group pattern from option
+--
+-- it supports building multiple targets, e.g. `xmake build target1 target2 ...`
+-- and is compatible with the legacy single `target` option passed programmatically.
+--
+function get_targets_and_group()
+ local targetnames
+ local group_pattern = option.get("group")
+ if group_pattern then
+ group_pattern = "^" .. path.pattern(group_pattern) .. "$"
+ else
+ targetnames = option.get("targets")
+ if not targetnames then
+ local targetname = option.get("target")
+ if targetname then
+ targetnames = {targetname}
+ end
+ end
+ if targetnames then
+ targetnames = table.wrap(targetnames)
+ end
+ end
+ return targetnames, group_pattern
+end
diff --git a/xmake/plugins/format/main.lua b/xmake/plugins/format/main.lua
index 7d5e1de66..f8be7c428 100644
--- a/xmake/plugins/format/main.lua
+++ b/xmake/plugins/format/main.lua
@@ -94,10 +94,12 @@ function _get_file_patterns(sourcefiles)
end
-- get all the targets that match the group or targetname
-function _get_targets(targetname, group_pattern)
+function _get_targets(targetnames, group_pattern)
local targets = {}
- if targetname then
- table.insert(targets, project.target(targetname))
+ if targetnames and #targetnames > 0 then
+ for _, targetname in ipairs(targetnames) do
+ table.insert(targets, project.target(targetname))
+ end
else
for _, target in pairs(project.targets()) do
local group = target:get("group")
@@ -178,8 +180,8 @@ function main()
-- collect sourcefiles
local sourcefiles = {}
- local targetname, group_pattern = action_utils.get_target_and_group()
- local targets = _get_targets(targetname, group_pattern)
+ local targetnames, group_pattern = action_utils.get_targets_and_group()
+ local targets = _get_targets(targetnames, group_pattern)
if option.get("files") then
local filepatterns = _get_file_patterns(option.get("files"))
for _, target in ipairs(targets) do
diff --git a/xmake/plugins/format/xmake.lua b/xmake/plugins/format/xmake.lua
index d9e34572b..5de1b8120 100644
--- a/xmake/plugins/format/xmake.lua
+++ b/xmake/plugins/format/xmake.lua
@@ -45,7 +45,9 @@ task("format")
" - xmake format --files='src/**.c|excluded_file.c'",
" - xmake format --files='src/main.c" .. path.envsep() .. "src/test.c'" },
{},
- {nil, "target", "v", nil, "The target name. It will format all default targets if this parameter is not specified."
+ {nil, "targets", "vs", nil, "The target names. It will format all default targets if this parameter is not specified.",
+ "e.g.",
+ " xmake format target1 target2 ..."
, values = function (complete, opt) return import("private.utils.complete_helper.targets")(complete, opt) end }
}
}
diff --git a/xmake/rules/xcode/application/install.lua b/xmake/rules/xcode/application/install.lua
index 1f1578fe1..4d5053240 100644
--- a/xmake/rules/xcode/application/install.lua
+++ b/xmake/rules/xcode/application/install.lua
@@ -32,7 +32,7 @@ function _install_for_ios(target)
-- get *.ipa file
local ipafile = path.join(path.directory(appdir), path.basename(appdir) .. ".ipa")
if not os.isfile(ipafile) or os.mtime(target:targetfile()) > os.mtime(ipafile) then
- task.run("package", {target = target:name()})
+ task.run("package", {targets = {target:name()}})
end
assert(os.isfile(ipafile), "please run `xmake package` first!")