Using Custom Build Rules in xmake
After version 2.1.9, xmake not only natively supports building multiple language files, but also allows users to implement complex unknown file builds through custom build rules.
For specific usage instructions, please refer to the relevant documentation: Rule Usage Manual
General Rules
We can extend build support for other files by pre-setting the file extensions supported by rules:
-- Define a build rule for markdown files
rule("markdown")
set_extensions(".md", ".markdown")
on_build(function (target, sourcefile)
os.cp(sourcefile, path.join(target:targetdir(), path.basename(sourcefile) .. ".html"))
end)
target("test")
set_kind("binary")
-- Make test target support markdown file build rules
add_rules("markdown")
-- Add markdown file builds
add_files("src/*.md")
add_files("src/*.markdown")We can also specify some scattered other files to be processed as markdown rules:
target("test")
-- ...
add_files("src/test/*.md.in", {rule = "markdown"})Note: Rules specified through add_files("*.md", {rule = "markdown"}) have higher priority than rules set by add_rules("markdown").
Dependent Builds
We can also implement cascading builds of rules. For example, after building the man rule, continue to call the markdown rule to implement cascading builds:
rule("man")
add_imports("core.project.rule")
on_build(function (target, sourcefile)
rule.build("markdown", target, sourcefile)
end)Among them, add_imports is used to pre-import extension modules, which can be directly used in multiple custom scripts. For specific instructions, see: add_imports Documentation
Multi-file Builds
For some files, you need to support multi-file builds to generate a single object mode, which can be implemented through on_build_all:
rule("man")
on_build_all(function (target, sourcefiles)
-- build some source files
for _, sourcefile in ipairs(sourcefiles) do
-- ...
end
end)
target("test")
-- ...
add_files("src/test/*.doc.in", {rule = "man"})Clean and Install
We can use on_clean, on_install to implement custom rule cleanup and installation logic, processing one source file at a time, for example:
rule("markdown")
on_build(function (target, sourcefile)
os.cp(sourcefile, path.join(target:targetdir(), path.basename(sourcefile) .. ".html"))
end)
on_clean(function (target, sourcefile)
os.rm(path.join(target:targetdir(), path.basename(sourcefile) .. ".html"))
end)
on_install(function (target, sourcefile)
import("core.base.option")
os.cp(path.join(target:targetdir(), path.basename(sourcefile) .. ".html"), option.get("outputdir"))
end)Finally, here's a complete example for reference: Rule Usage Example