19 KiB
API
api("param1","param2",...,dict_prop)
on_script("dir.file") || on_script(function(...) end)
命名规范
接口的命名,是有按照预定义的一些规范来命名的,这样更加方便理解和易于使用,目前命名按照如下一些规则:
| 接口规则 | 描述 |
|---|---|
is_, has_前缀的接口 |
表示为条件判断 |
set_前缀的接口 |
表示为覆盖设置 |
add_前缀的接口 |
表示为追加设置 |
s后缀的接口 |
表示支持多值传入,例如:add_files("*.c", "test.cpp") |
on_前缀的接口 |
表示为覆盖内置脚本 |
before_前缀的接口 |
表示为在内置脚本运行前,执行此脚本 |
after_前缀的接口 |
表示为在内置脚本运行后,执行此脚本 |
scope("name")的接口 |
表示为定义一个描述域,例如:target("xxx"), option("xxx") |
| 描述域/描述设置 | 建议缩进表示 |
条件判断
条件判断的api,一般用于必须要处理特定平台的编译逻辑的场合。。通常跟lua的if语句配合使用。
| 接口 | 描述 | 支持版本 |
|---|---|---|
| is_os | 判断当前构建目标的操作系统 | >= 2.0.1 |
| is_arch | 判断当前编译架构 | >= 2.0.1 |
| is_plat | 判断当前编译平台 | >= 2.0.1 |
| is_host | 判断当前主机环境操作系统 | >= 2.1.4 |
| is_mode | 判断当前编译模式 | >= 2.0.1 |
| is_kind | 判断当前编译类型 | >= 2.0.1 |
| is_option | 判断选项是否启用 | >= 2.0.1 < 2.2.2 已废弃 |
| is_config | 判断指定配置是否为给定的值 | >= 2.2.2 |
| has_config | 判断配置是否启用或者存在 | >= 2.2.2 |
| has_package | 判断依赖包是否被启用或者存在 | >= 2.2.3 |
特殊字符
正则表达式
-- 递归添加src下的所有c文件,但是不包括src/impl/下的所有c文件
add_files("src/**.c|impl/*.c")
-- 添加src下的所有cpp文件,但是不包括src/test.cpp、src/hello.cpp以及src下所有带xx_前缀的cpp文件
add_files("src/*.cpp|test.cpp|hello.cpp|xx_*.cpp")
-- 批量导入配置文件
includes("test/**/xmake.lua")
内置变量
target("test")
-- 添加工程源码目录下的源文件
add_files("$(projectdir)/src/*.c")
-- 添加构建目录下的头文件搜索路径
add_includedirs("$(buildir)/inc")
| 接口 | 描述 | 支持版本 |
|---|---|---|
| $(os) | 获取当前编译平台的操作系统 | >= 2.0.1 |
| $(host) | 获取本机操作系统 | >= 2.0.1 |
| $(tmpdir) | 获取临时目录 | >= 2.0.1 |
| $(curdir) | 获取当前目录 | >= 2.0.1 |
| $(buildir) | 获取构建输出目录 | >= 2.0.1 |
| $(scriptdir) | 获取工程描述脚本目录 | >= 2.1.1 |
| $(globaldir) | 获取全局配置目录 | >= 2.0.1 |
| $(configdir) | 获取本地工程配置目录 | >= 2.0.1 |
| $(programdir) | xmake安装脚本目录 | >= 2.1.5 |
| $(projectdir) | 获取工程根目录 | >= 2.0.1 |
| $(shell) | 执行外部shell命令 | >= 2.0.1 |
| $(env) | 获取外部环境变量 | >= 2.1.5 |
| $(reg) | 获取windows注册表配置项的值 | >= 2.1.5 |
模块接口
内置模块
扩展模块
常用接口
- import
- includes
测试
on_test(function (package)
assert(package:has_cxxfuncs("func1", {includes = "xxx.h", configs = {defines = "c++14", cxflags = "-Dxxx"}}))
end)
on_test(function (package)
assert(package:check_cxxsnippets({test = [[
#include <boost/algorithm/string.hpp>
#include <string>
#include <vector>
#include <assert.h>
using namespace boost::algorithm;
using namespace std;
static void test() {
string str("a,b");
vector<string> strVec;
split(strVec, str, is_any_of(","));
assert(strVec.size()==2);
assert(strVec[0]=="a");
assert(strVec[1]=="b");
}
]]}, {configs = {languages = "c++14"}}))
end)
项目配置
config.lua
相当于命令行配置,优先级最高
类型
本地配置会覆盖全局配置
- 全局配置
- 所有项目生效
- 本地配置
- 本地项目生效
作用
- 设置编译选项
- 设置环境变量
- 设置项目配置
xmake.lua
-- 全局根作用域,影响所有target,包括includes() 中的子工程target设置
add_defines("DEBUG")
option("test")
set_default(false)
-- 显示结束作用域
option_end()
-- 隐式结束上一个作用域
target("demo")
set_kind("binary")
add_files("src/*.c")
target_end()
配置域
set_xxx/add_xxx的配置集,用于静态的生成lua对象的属性集
配置域通过includes 导入子配置
配置文件在不同阶段会被多次解析 会被执行多遍!
- 配置里可以加入简单的逻辑判断
- 沙盒环境,被禁止执行复杂操作(屏蔽接口)
描述域
命令行中的属性优先级最高,会影响到所有设置
进入另一个target/option域设置,会自动离开上个target/option域,但是有时候为了比较一些作用域污染情况,我们可以显示离开某个域
- 命令行
- 配置域
- 全局域
- 范围域
脚本域
导入后就可以直接使用里面的所有公有接口,私有接口用_前缀标示,表明不会被导出,不会被外部调用到。
其中 main 为入口函数,可选,如果设置,模块 foo 可以直接被调用
- 在指定时机中执行复杂操作,只执行一遍
- 脚本域中开放所有接口,可执行任何操作
on_link
--定制化处理target的链接过程
target("test")
on_link(function (target)
print("link it")
end)
on_build
--[[
覆盖target目标默认的构建行为,实现自定义的编译过程,
一般情况下,并不需要这么做,除非确实需要做一些xmake默认没有提供的编译操作
如果第一个参数为字符串,那么就是指定这个脚本需要在哪个平台|架构下,才会被执行
]]
target("test")
on_build("iphoneos|arm*", function (target)
print("build for iphoneos and arm")
end)
on_build_file
--通过此接口,可以用来hook指定target内置的构建过程,自己重新实现每个源文件编译过程
target("test")
set_kind("binary")
add_files("src/*.c")
on_build_file(function (target, sourcefile, opt)
end)
on_build_files
--通过此接口,可以用来hook指定target内置的构建过程,替换一批同类型源文件编译过程:
target("test")
set_kind("binary")
add_files("src/*.c")
on_build_files(function (target, sourcebatch, opt)
end)
其中sourcebatch描述了这批同类型源文件:
sourcebatch.sourcekind: 获取这批源文件的类型,比如:cc, as, ..sourcebatch.sourcefiles(): 获取源文件列表sourcebatch.objectfiles(): 获取对象文件列表sourcebatch.dependfiles(): 获取对应依赖文件列表,存有源文件中编译依赖信息,例如:xxx.d
on_clean
--覆盖target目标的xmake [c|clean}的清理操作,实现自定义清理过程。
target("test")
-- 设置自定义清理脚本
on_clean(function (target)
-- 仅删掉目标文件
os.rm(target:targetfile())
end)
on_package
--覆盖target目标的xmake [p|package}的打包操作,实现自定义打包过程,如果你想对指定target打包成自己想要的格式,可以通过这个接口自定义它
target("demo")
set_kind("shared")
add_files("jni/*.c")
on_package(function (target)
os.exec("./gradlew app:assembleDebug")
end)
on_install
--覆盖target目标的xmake [i|install}的安装操作,实现自定义安装过程
target("test")
-- 设置自定义安装脚本,自动安装apk文件
on_install(function (target)
-- 使用adb安装打包生成的apk文件
os.run("adb install -r ./bin/Demo-debug.apk")
end)
on_uninstall
--覆盖target目标的xmake [u|uninstall}的卸载操作,实现自定义卸载过程
target("test")
on_uninstall(function (target)
...
end)
on_run
--覆盖target目标的xmake [r|run}的运行操作,实现自定义运行过程。
target("test")
-- 设置自定义运行脚本,自动运行安装好的app程序,并且自动获取设备输出信息
on_run(function (target)
os.run("adb shell am start -n com.demo/com.demo.DemoTest")
os.run("adb logcat")
end)
on_link
--定制化处理target的链接过程
target("test")
on_link(function (target)
print("link it")
end)
扩展事件
- before_xxx
- after_xxx
target:on_xxx的所有接口都覆盖内部默认实现,通常我们并不需要完全复写,只是额外挂接自己的一些逻辑,那么可以使用target:before_xxx和target:after_xxx系列脚本就行了。
所有的on_xxx都有对应的before_和after_xx版本,参数也完全一致
文件拆分
文件间存在树形继承关系,当前文件目录为工作空间
配置域
配置域通过includes 导入子配置
- 拆分属性配置到多个文件
- 支持批量导入
脚本域
不仅可以使用大部分lua的api,还可以使用很多xmake提供的扩展模块
所有扩展模块,通过import来导入
Target
- 项目属性配置
- 项目间存在继承关系
项目配置
-- 批量导入配置文件
includes("test/**/xmake.lua")
target("test")
-- 静态库 | 动态库 | 可执行程序
-- static | shared | binary
set_kind("binary")
-- 源文件
add_files("src/*.cpp")
-- 删除指定文件
del_files("src/test.c")
-- 头文件
add_headerfiles("src/*.h")
-- 头文件目录
add_includedirs("/usr/local/include")
-- 库目录
add_linkdirs("/usr/local/lib")
-- 链接 非系统库
add_links("pthread")
-- 链接 系统库
add_syslinks("pthread")
-- 项目依赖,会自动添加目录与库
add_deps("lua")
-- 就继承了 lua 的所有导出设置:linkdirs, links, includedirs以及defines
-- {inherit = false} 可禁止配置继承
-- 添加第三方库依赖
add_requires("lua")
-- 链接第三方库
add_packages("lua")
第三方库
-- 远程第三方仓库集
add_repositories("my-repo git@github.com:myrepo/xmake-repo.git")
-- 本地第三方仓库集
add_repositories("my-repo myrepo")
-- 定义第三方库
package("libjpeg")
set_urls("http://www.ijg.org/files/jpegsrc.$(version).tar.gz")
add_versions("v9c", "650250979303a649e21f87b5ccd02672af1ea6954b911342ea491f351ceb7122")
on_install("windows", function (package)
os.mv("jconfig.vc", "jconfig.h")
os.vrun("nmake -f makefile.vc")
os.cp("*.h", package:installdir("include"))
os.cp("libjpeg.lib", package:installdir("lib"))
end)
on_install("macosx", "linux", function (package)
import("package.tools.autoconf").install(package)
end)
package_end()
--语义版本支持,例如:”>= 1.1.0 < 1.2”, “~1.6”, “1.2.x”, “1.*”
add_requires("lua 5.4.*", "libpng ~1.16", "brew::zlib", {alias = "zlib"})
add_requires("vcpkg::zlib", "vcpkg::pcre2")
编译配置
-- 启用调试符号
set_symbols("debug")
-- 隐藏符号
set_symbols("hidden")
-- 添加扩展指令集
add_vectorexts("sse2", "sse3", "ssse3", "mmx")
-- 仅添加C代码相关编译flags
add_cflags("-g", "-O2", "-DDEBUG")
-- 添加C/C++代码相关编译flags
add_cxflags("-g", "-O2", "-DDEBUG")
-- 仅添加C++代码相关编译flags
add_cxxflags("-g", "-O2", "-DDEBUG", {force = true})
-- force 强制检测 flag 是否添加成功
-- 设置语言标准
set_languages("c99", "c++11")
-- 编译优化选项
set_optimize("fastest")
set_toolchain("cxx", "clang")
set_toolchain("ld", "clang++")
-- 设置 xmake f 参数默认值,优先级最高
set_config("cflags", "-DTEST")
set_config("sdk", "/home/xxx/tooksdk")
set_config("cc", "gcc")
set_config("ld", "g++")
Lua对象接口
| Target 接口 | |
|---|---|
| target:name() | 获取目标名 |
| target:targetfile() | 获取目标文件路径 |
| target:targetkind() | 获取目标构建类型 |
| target:get("defines") | 获取目标宏定义 |
| target:get("xxx") | 获取set_/add_ 信息 |
| target:add("link","pthread") | 添加目标设置 |
| target:set("link","pthread","z") | 覆写目标设置 |
| target:deps() | 获取目标所有依赖 |
| target:dep("depname") | 获取指定依赖 |
| target:opts(") | 获取所有关联选项 |
| target:opt("optname") | 获取指定关联选项 |
| target:pkgs() | 获取所有关联依赖包 |
| target:pkg("pkgname") | 获取指定关联依赖包 |
| target:sourcebatches() | 获取所有源文件列表 |
Rule
- 属性与事件组成特定实体
- 方便继承到其他域中
- 项目间存在组合关系
Package
第三方库配置
- 语义版本支持,例如:”>= 1.1.0 < 1.2”, “~1.6”, “1.2.x”, “1.*”
第三方库的配置和项目配置不一样
kind 决定 package 如何用于 项目
- 程序依赖
- 库依赖
- 源码依赖
接口
-
类型
-
set_kind
-
-
版本
-
set_urls
-
add_urls
-
add_versions
-
add_patches
-
-
参数
-
add_configs
-
-- 源码地址
set_urls("https://ffmpeg.org/releases/ffmpeg-$(version).tar.bz2", {alias = "home"})
add_urls("https://github.com/FFmpeg/FFmpeg/archive/n$(version).zip", {alias = "github"})
add_urls("https://gitlab.gnome.org/GNOME/libxml2.git")
-- 源码包 与 哈希码
add_versions("home:4.0.2", "346c51735f42c37e0712e0b3d2f6476c86ac15863e4445d9e823fe396420d056")
add_versions("github:4.0.2", "4df1ef0bf73b7148caea1270539ef7bd06607e0ea8aa2fbf1bb34062a097f026")
-- 版本补丁
add_patches("1.15", "https://raw.githubusercontent.com/Homebrew/patches/9be2793af/libiconv/patch-utf8mac.diff",
"e8128732f22f63b5c656659786d2cf76f1450008f36bcf541285268c66cabeab")
-- 配置自定义参数 与 参数描述
add_configs("bitwidth", {description = "Set the code unit width.", default = "8", values = {"8", "16", "32"}})
package("luasocket")
-- 设置类型 binary 不可省略
set_kind("library")
set_homepage("https://cmake.org")
set_description("A cross-platform family of tool designed to build, test and package software")
Option
xmake 命令后加入可选配置
Task
#task project
#option : k m
#kind vsxmake2022
#mode "debug;release"
xmake project -k vsxmake2022 -m "debug;release"
xmake project --help
xmake可以实现自定义任务或者插件,其两者的核心就是task任务,其两者实际上是一样的,xmake的插件都是用task实现的。
本质上都是任务,只是set_category分类不同而已。
| 接口 | 描述 | 支持版本 |
|---|---|---|
| task | 定义插件或者任务 | >= 2.0.1 |
| task_end | 结束定义插件或任务 | >= 2.1.1 |
| set_menu | 设置任务菜单 | >= 2.0.1 |
| set_category | 设置任务类别 | >= 2.0.1 |
| on_run | 设置任务运行脚本 | >= 2.0.1 |