在2.2.1版本之后,xmake不仅原生内置支持多种语言文件的构建,而且还可以通过自定义构建规则,让用户自己来实现复杂的未知文件构建。

我们可以通过预先设置规则支持的文件后缀,来扩展其他文件的构建支持:

  1. -- 定义一个markdown文件的构建规则
  2. rule("markdown")
  3. set_extensions(".md", ".markdown")
  4. on_build_file(function (target, sourcefile, opt)
  5. os.cp(sourcefile, path.join(target:targetdir(), path.basename(sourcefile) .. ".html"))
  6. end)
  7. target("test")
  8. set_kind("binary")
  9. -- 使test目标支持markdown文件的构建规则
  10. add_rules("markdown")
  11. -- 添加markdown文件的构建
  12. add_files("src/*.md")
  13. add_files("src/*.markdown")

我们也可以指定某些零散的其他文件作为markdown规则来处理:

  1. target("test")
  2. -- ...
  3. add_files("src/test/*.md.in", {rule = "markdown"})

一个target可以叠加应用多个rules去更加定制化实现自己的构建行为,甚至支持不同的构建环境。

通过add_files("*.md", {rule = "markdown"})方式指定的规则,优先级高于add_rules("markdown")设置的规则。

接口 描述 支持版本
rule 定义规则 >= 2.1.9
add_imports 为所有自定义脚本预先导入扩展模块 >= 2.1.9
set_extensions 设置规则支持的文件扩展类型 >= 2.1.9
on_load 自定义加载脚本 >= 2.2.1
on_link 自定义链接脚本 >= 2.2.7
on_build 自定义编译脚本 >= 2.1.9
on_clean 自定义清理脚本 >= 2.1.9
on_package 自定义打包脚本 >= 2.1.9
on_install 自定义安装脚本 >= 2.1.9
on_uninstall 自定义卸载脚本 >= 2.1.9
on_build_file 自定义编译脚本, 实现单文件构建 >= 2.2.1
on_build_files 自定义编译脚本, 实现多文件构建 >= 2.2.1
before_load 自定义加载前的脚本 >= 2.2.1
before_link 自定义链接前的脚本 >= 2.2.7
before_build 自定义编译前的脚本 >= 2.2.1
before_clean 自定义清理前的脚本 >= 2.2.1
before_package 自定义打包前的脚本 >= 2.2.1
before_install 自定义安装前的脚本 >= 2.2.1
before_uninstall 自定义卸载前的脚本 >= 2.2.1
before_build_file 自定义编译前的脚本, 实现单文件构建 >= 2.2.1
before_build_files 自定义编译前的脚本, 实现多文件构建 >= 2.2.1
after_load 自定义加载后的脚本 >= 2.2.1
after_link 自定义链接后的脚本 >= 2.2.7
after_build 自定义编译后的脚本 >= 2.2.1
after_clean 自定义清理后的脚本 >= 2.2.1
after_package 自定义打包后的脚本 >= 2.2.1
after_install 自定义安装后的脚本 >= 2.2.1
after_uninstall 自定义卸载后的脚本 >= 2.2.1
after_build_file 自定义编译后的脚本, 实现单文件构建 >= 2.2.1
after_build_files 自定义编译后的脚本, 实现多文件构建 >= 2.2.1
rule_end 结束定义规则 >= 2.1.9

内建规则

自从2.2.1版本后,xmake提供了一些内置规则去简化日常xmake.lua描述,以及一些常用构建环境的支持。

规则 描述 支持版本
mode.debug 调试模式编译规则 >= 2.2.1
mode.release 发布模式编译规则 >= 2.2.1
mode.check 检测模式编译规则 >= 2.2.1
mode.profile 性能分析模式编译规则 >= 2.2.1
mode.coverage 覆盖分析编译模式规则 >= 2.2.1
qt.static Qt静态库编译规则 >= 2.2.1
qt.shared Qt动态库编译规则 >= 2.2.1
qt.console Qt控制台编译规则 >= 2.2.1
qt.application Qt应用程序编译规则 >= 2.2.1
wdk.umdf.driver WDK环境umdf驱动编译规则 >= 2.2.1
wdk.umdf.binary WDK环境umdf驱动应用编译规则 >= 2.2.1
wdk.kmdf.driver WDK环境kmdf驱动编译规则 >= 2.2.1
wdk.kmdf.binary WDK环境kmdf驱动应用编译规则 >= 2.2.1
wdk.wdm.driver WDK环境wdm驱动编译规则 >= 2.2.1
wdk.wdm.binary WDK环境wdm驱动应用编译规则 >= 2.2.1

mode.debug

为当前工程xmake.lua添加debug编译模式的配置规则,例如:

  1. add_rules("mode.debug")

相当于:

  1. -- the debug mode
  2. if is_mode("debug") then
  3. -- enable the debug symbols
  4. set_symbols("debug")
  5. -- disable optimization
  6. set_optimize("none")
  7. end

我们可以通过:xmake f -m debug来切换到此编译模式。

mode.release

为当前工程xmake.lua添加release编译模式的配置规则,例如:

  1. add_rules("mode.release")

相当于:

  1. -- the release mode
  2. if is_mode("release") then
  3. -- set the symbols visibility: hidden
  4. set_symbols("hidden")
  5. -- enable fastest optimization
  6. set_optimize("fastest")
  7. -- strip all symbols
  8. set_strip("all")
  9. end

我们可以通过:xmake f -m release来切换到此编译模式。

mode.check

为当前工程xmake.lua添加check编译模式的配置规则,一般用于内存检测,例如:

  1. add_rules("mode.check")

相当于:

  1. -- the check mode
  2. if is_mode("check") then
  3. -- enable the debug symbols
  4. set_symbols("debug")
  5. -- disable optimization
  6. set_optimize("none")
  7. -- attempt to enable some checkers for pc
  8. add_cxflags("-fsanitize=address", "-ftrapv")
  9. add_mxflags("-fsanitize=address", "-ftrapv")
  10. add_ldflags("-fsanitize=address")
  11. end

我们可以通过:xmake f -m check来切换到此编译模式。

mode.profile

为当前工程xmake.lua添加profile编译模式的配置规则,一般用于性能分析,例如:

  1. add_rules("mode.profile")

相当于:

  1. -- the profile mode
  2. if is_mode("profile") then
  3. -- enable the debug symbols
  4. set_symbols("debug")
  5. -- enable gprof
  6. add_cxflags("-pg")
  7. add_ldflags("-pg")
  8. end

我们可以通过:xmake f -m profile来切换到此编译模式。

mode.coverage

为当前工程xmake.lua添加coverage编译模式的配置规则,一般用于覆盖分析,例如:

  1. add_rules("mode.coverage")

相当于:

  1. -- the coverage mode
  2. if is_mode("coverage") then
  3. add_cxflags("--coverage")
  4. add_mxflags("--coverage")
  5. add_ldflags("--coverage")
  6. end

我们可以通过:xmake f -m coverage来切换到此编译模式。

qt.static

用于编译生成Qt环境的静态库程序:

  1. target("qt_static_library")
  2. add_rules("qt.static")
  3. add_files("src/*.cpp")
  4. add_frameworks("QtNetwork", "QtGui")

qt.shared

用于编译生成Qt环境的动态库程序:

  1. target("qt_shared_library")
  2. add_rules("qt.shared")
  3. add_files("src/*.cpp")
  4. add_frameworks("QtNetwork", "QtGui")

qt.console

用于编译生成Qt环境的控制台程序:

  1. target("qt_console")
  2. add_rules("qt.console")
  3. add_files("src/*.cpp")

qt.application

用于编译生成Qt环境的ui应用程序。

Quick(qml)应用程序:

  1. target("qt_quickapp")
  2. add_rules("qt.application")
  3. add_files("src/*.cpp")
  4. add_files("src/qml.qrc")
  5. add_frameworks("QtQuick")

Qt Widgets(ui/moc)应用程序:

  1. -- add target
  2. target("qt_widgetapp")
  3. add_rules("qt.application")
  4. add_files("src/*.cpp")
  5. add_files("src/mainwindow.ui")
  6. add_files("src/mainwindow.h") -- 添加带有 Q_OBJECT meta头文件
  7. add_frameworks("QtWidgets")

更多Qt相关描述见:#160

wdk.env.kmdf

应用WDK下kmdf的编译环境设置,需要配合:wdk.[driver|binary|static|shared]等规则来使用。

wdk.env.umdf

应用WDK下umdf的编译环境设置,需要配合:wdk.[driver|binary|static|shared]等规则来使用。

wdk.env.wdm

应用WDK下wdm的编译环境设置,需要配合:wdk.[driver|binary|static|shared]等规则来使用。

wdk.driver

编译生成windows下基于WDK环境的驱动程序,目前仅支持WDK10环境。

注:需要配合:wdk.env.[umdf|kmdf|wdm]等环境规则使用。

  1. -- add target
  2. target("echo")
  3. -- add rules
  4. add_rules("wdk.driver", "wdk.env.kmdf")
  5. -- add files
  6. add_files("driver/*.c")
  7. add_files("driver/*.inx")
  8. -- add includedirs
  9. add_includedirs("exe")

wdk.binary

编译生成windows下基于WDK环境的可执行程序,目前仅支持WDK10环境。

注:需要配合:wdk.env.[umdf|kmdf|wdm]等环境规则使用。

  1. -- add target
  2. target("app")
  3. -- add rules
  4. add_rules("wdk.binary", "wdk.env.umdf")
  5. -- add files
  6. add_files("exe/*.cpp")

wdk.static

编译生成windows下基于WDK环境的静态库程序,目前仅支持WDK10环境。

注:需要配合:wdk.env.[umdf|kmdf|wdm]等环境规则使用。

  1. target("nonpnp")
  2. -- add rules
  3. add_rules("wdk.static", "wdk.env.kmdf")
  4. -- add flags for rule: wdk.tracewpp
  5. add_values("wdk.tracewpp.flags", "-func:TraceEvents(LEVEL,FLAGS,MSG,...)", "-func:Hexdump((LEVEL,FLAGS,MSG,...))")
  6. -- add files
  7. add_files("driver/*.c", {rule = "wdk.tracewpp"})

wdk.shared

编译生成windows下基于WDK环境的动态库程序,目前仅支持WDK10环境。

注:需要配合:wdk.env.[umdf|kmdf|wdm]等环境规则使用。

  1. target("nonpnp")
  2. -- add rules
  3. add_rules("wdk.shared", "wdk.env.wdm")
  4. -- add flags for rule: wdk.tracewpp
  5. add_values("wdk.tracewpp.flags", "-func:TraceEvents(LEVEL,FLAGS,MSG,...)", "-func:Hexdump((LEVEL,FLAGS,MSG,...))")
  6. -- add files
  7. add_files("driver/*.c", {rule = "wdk.tracewpp"})

wdk.tracewpp

用于启用tracewpp预处理源文件:

  1. target("nonpnp")
  2. -- add rules
  3. add_rules("wdk.driver", "wdk.env.kmdf")
  4. -- add flags for rule: wdk.tracewpp
  5. add_values("wdk.tracewpp.flags", "-func:TraceEvents(LEVEL,FLAGS,MSG,...)", "-func:Hexdump((LEVEL,FLAGS,MSG,...))")
  6. -- add files
  7. add_files("driver/*.c", {rule = "wdk.tracewpp"})
  8. add_files("driver/*.rc")

更多WDK规则描述见:#159

win.sdk.application

编译生成winsdk应用程序。

  1. -- add rules
  2. add_rules("mode.debug", "mode.release")
  3. -- define target
  4. target("usbview")
  5. -- windows application
  6. add_rules("win.sdk.application")
  7. -- add files
  8. add_files("*.c", "*.rc")
  9. add_files("xmlhelper.cpp", {rule = "win.sdk.dotnet"})

wdk.sdk.dotnet

用于指定某些c++源文件作为c++.net来编译。

  1. add_files("xmlhelper.cpp", {rule = "win.sdk.dotnet"})

rule

定义规则

  1. rule("markdown")
  2. set_extensions(".md", ".markdown")
  3. on_build_file(function (target, sourcefile, opt)
  4. os.cp(sourcefile, path.join(target:targetdir(), path.basename(sourcefile) .. ".html"))
  5. end)

rule:add_imports

为所有自定义脚本预先导入扩展模块

使用方式和说明请见:target:add_imports,用法相同。

rule:set_extensions

设置规则支持的文件扩展类型

通过设置支持的扩展文件类型,将规则应用于带这些后缀的文件上,例如:

  1. -- 定义一个markdown文件的构建规则
  2. rule("markdown")
  3. set_extensions(".md", ".markdown")
  4. on_build_file(function (target, sourcefile, opt)
  5. os.cp(sourcefile, path.join(target:targetdir(), path.basename(sourcefile) .. ".html"))
  6. end)
  7. target("test")
  8. set_kind("binary")
  9. -- 使test目标支持markdown文件的构建规则
  10. add_rules("markdown")
  11. -- 添加markdown文件的构建
  12. add_files("src/*.md")
  13. add_files("src/*.markdown")

rule:on_load

自定义加载脚本

用于实现自定规则的加载脚本,当加载target的时候,会被执行,可在里面自定义设置一些target配置,例如:

  1. rule("test")
  2. on_load(function (target)
  3. target:add("defines", "-DTEST")
  4. end)

自定义链接脚本

用于实现自定规则的链接脚本,会覆盖被应用的target的默认链接行为,例如:

  1. rule("test")
  2. on_link(function (target)
  3. end)

rule:on_build

自定义编译脚本

用于实现自定规则的构建脚本,会覆盖被应用的target的默认构建行为,例如:

  1. rule("markdown")
  2. on_build(function (target)
  3. end)

rule:on_clean

自定义清理脚本

用于实现自定规则的清理脚本会,覆盖被应用的target的默认清理行为,例如:

  1. rule("markdown")
  2. on_clean(function (target)
  3. -- remove sourcefile.html
  4. end)

rule:on_package

自定义打包脚本

用于实现自定规则的打包脚本,覆盖被应用的target的默认打包行为, 例如:

  1. rule("markdown")
  2. on_package(function (target)
  3. -- package sourcefile.html
  4. end)

rule:on_install

自定义安装脚本

用于实现自定规则的安装脚本,覆盖被应用的target的默认安装行为, 例如:

  1. rule("markdown")
  2. on_install(function (target)
  3. end)

rule:on_uninstall

自定义卸载脚本

用于实现自定规则的卸载脚本,覆盖被应用的target的默认卸载行为, 例如:

  1. rule("markdown")
  2. on_uninstall(function (target)
  3. end)

rule:on_build_file

自定义编译脚本,一次处理一个源文件

  1. rule("markdown")
  2. on_build_file(function (target, sourcefile, opt)
  3. print("%%%d: %s", opt.progress, sourcefile)
  4. end)

其中第三个参数opt是可选参数,用于获取一些编译过程中的信息状态,例如:opt.progress 为当期的编译进度。

rule:on_build_files

自定义编译脚本,一次处理多个源文件

大部分的自定义构建规则,每次都是处理单独一个文件,输出一个目标文件,例如:a.c => a.o

但是,有些情况下,我们需要同时输入多个源文件一起构建生成一个目标文件,例如:a.c b.c d.c => x.o

对于这种情况,我们可以通过自定义这个脚本来实现:

  1. rule("markdown")
  2. on_build_files(function (target, sourcebatch, opt)
  3. -- build some source files
  4. for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
  5. -- ...
  6. end
  7. end)

rule:before_load

自定义加载前脚本

用于实现自定义target加载前的执行脚本,例如:

  1. rule("test")
  2. before_load(function (target)
  3. target:add("defines", "-DTEST")
  4. end)

自定义链接前脚本

用于实现自定义target链接前的执行脚本,例如:

  1. rule("test")
  2. before_link(function (target)
  3. end)

rule:before_build

自定义编译前脚本

用于实现自定义target构建前的执行脚本,例如:

  1. rule("markdown")
  2. before_build(function (target)
  3. end)

rule:before_clean

自定义清理前脚本

用于实现自定义target清理前的执行脚本,例如:

  1. rule("markdown")
  2. before_clean(function (target)
  3. end)

rule:before_package

自定义打包前脚本

用于实现自定义target打包前的执行脚本, 例如:

  1. rule("markdown")
  2. before_package(function (target)
  3. end)

rule:before_install

自定义安装前脚本

用于实现自定义target安装前的执行脚本,例如:

  1. rule("markdown")
  2. before_install(function (target)
  3. end)

rule:before_uninstall

自定义卸载前脚本

用于实现自定义target卸载前的执行脚本,例如:

  1. rule("markdown")
  2. before_uninstall(function (target)
  3. end)

rule:before_build_file

自定义编译前脚本,一次处理一个源文件

rule:on_build_file用法类似,不过这个接口被调用的时机是在编译某个源文件之前,一般用于对某些源文件进行编译前的预处理。

rule:before_build_files

自定义编译前脚本,一次处理多个源文件

rule:on_build_files用法类似,不过这个接口被调用的时机是在编译某些源文件之前,一般用于对某些源文件进行编译前的预处理。

rule:after_load

自定义加载后脚本

用于实现自定义target加载后的执行脚本,用法跟rule:before_load类似。

自定义链接后脚本

用于实现自定义target链接后的执行脚本,用法跟rule:before_link类似。

rule:after_build

自定义编译后脚本

用于实现自定义target构建后的执行脚本,用法跟rule:before_build类似。

rule:after_clean

自定义清理后脚本

用于实现自定义target清理后的执行脚本,用法跟rule:before_clean类似。

rule:after_package

自定义打包后脚本

用于实现自定义target打包后的执行脚本, 用法跟rule:before_package类似。

rule:after_install

自定义安装后脚本

用于实现自定义target安装后的执行脚本,用法跟rule:before_install类似。

rule:after_uninstall

自定义卸载后脚本

用于实现自定义target卸载后的执行脚本,用法跟rule:before_uninstall类似。

rule:after_build_file

自定义编译后脚本,一次处理一个源文件

rule:on_build_file用法类似,不过这个接口被调用的时机是在编译某个源文件之后,一般用于对某些编译后对象文件进行后期处理。

rule:after_build_files

自定义编译后脚本,一次处理多个源文件

rule:on_build_files用法类似,不过这个接口被调用的时机是在编译某些源文件之后,一般用于对某些编译后对象文件进行后期处理。

rule_end

结束定义规则

这个是可选的,如果想要手动结束rule的定义,可以调用它:

  1. rule("test")
  2. -- ..
  3. rule_end()