Xmake supports custom tasks and plugins, both implemented using the task system. Tasks can be used for automating build processes, code generation, file processing, and various other project requirements.
set_category("plugin")set_menu() to allow tasks to be called directly from the command linetask("taskname")
on_run(function ()
-- task execution logic
print("Task executing...")
end)
task("hello")
on_run(function ()
print("hello xmake!")
end)
This task can only be called via task.run() in xmake.lua:
target("test")
after_build(function (target)
import("core.project.task")
task.run("hello")
end)
Use set_menu() to allow tasks to be called directly from the command line:
task("echo")
on_run(function ()
import("core.base.option")
-- get parameter content and display
local contents = option.get("contents") or {}
local color = option.get("color") or "black"
cprint("${%s}%s", color, table.concat(contents, " "))
end)
set_menu {
usage = "xmake echo [options]",
description = "Display specified information",
options = {
{'c', "color", "kv", "black", "Set output color"},
{nil, "contents", "vs", nil, "Content to display"}
}
}
Now you can call it from the command line:
$ xmake echo -c red hello xmake!
task("myplugin")
set_category("plugin") -- categorize as plugin
on_run(function ()
print("This is a plugin")
end)
Category descriptions:
task("example")
on_run(function ()
import("core.base.option")
-- get different types of parameters
local verbose = option.get("verbose") -- boolean
local color = option.get("color") -- key-value
local files = option.get("files") -- multiple values
local args = {...} -- variable arguments
end)
set_menu {
options = {
{'v', "verbose", "k", nil, "Enable verbose output"}, -- boolean option
{'c', "color", "kv", "red", "Set color"}, -- key-value option
{'f', "files", "vs", nil, "File list"}, -- multiple values option
{nil, "args", "vs", nil, "Other arguments"} -- variable arguments
}
}
target("test")
set_kind("binary")
add_files("src/*.cpp")
after_build(function (target)
import("core.project.task")
-- run code generation task after build
task.run("generate-code")
-- run test task
task.run("run-tests")
end)
-- code generation task
task("generate-code")
on_run(function ()
print("Generating code...")
-- execute code generation logic
os.exec("protoc --cpp_out=src proto/*.proto")
end)
-- test task
task("run-tests")
on_run(function ()
print("Running tests...")
os.exec("xmake run test")
end)
task("process-assets")
on_run(function ()
import("core.base.option")
local input_dir = option.get("input") or "assets"
local output_dir = option.get("output") or "build/assets"
-- process resource files
os.mkdir(output_dir)
os.cp(path.join(input_dir, "*.png"), output_dir)
os.cp(path.join(input_dir, "*.json"), output_dir)
print("Resource file processing completed")
end)
set_menu {
usage = "xmake process-assets [options]",
description = "Process project resource files",
options = {
{'i', "input", "kv", "assets", "Input directory"},
{'o', "output", "kv", "build/assets", "Output directory"}
}
}
task("format")
on_run(function ()
import("core.base.option")
import("lib.detect.find_tool")
local tool = find_tool("clang-format")
if not tool then
raise("clang-format not found!")
end
local files = option.get("files") or {"src/**/*.cpp", "src/**/*.h"}
for _, pattern in ipairs(files) do
local filelist = os.files(pattern)
for _, file in ipairs(filelist) do
os.execv(tool.program, {"-i", file})
print("Formatting file:", file)
end
end
end)
set_menu {
usage = "xmake format [options]",
description = "Format code files",
options = {
{'f', "files", "vs", nil, "File patterns to format"}
}
}
task("clean-all")
on_run(function ()
local patterns = {
"build/**",
"*.log",
"*.tmp",
"*.o",
"*.a",
"*.so",
"*.dylib",
"*.exe"
}
for _, pattern in ipairs(patterns) do
os.tryrm(pattern)
end
print("Project cleanup completed")
end)
set_menu {
usage = "xmake clean-all",
description = "Clean all build files and temporary files"
}
$ xmake taskname [options] [args...]
import("core.project.task")
-- call task
task.run("taskname")
-- pass parameters
task.run("taskname", {option1 = "value1"}, "arg1", "arg2")
target("test")
before_build(function (target)
task.run("prepare")
end)
after_build(function (target)
task.run("post-process")
end)
pcall to wrap task logicprogress.show() to display execution progress