note/专业积累/工具/xmake/xmake API.md
2023-07-05 09:34:06 +08:00

581 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# API
[链接](https://www.bookstack.cn/read/xmake/manual-project_target.md)
`api("param1","param2",...,dict_prop)`
`on_script("dir.file") || on_script(function(...) end) `
## [命名规范](https://www.bookstack.cn/read/xmake/manual-specification.md)
接口的命名,是有按照预定义的一些规范来命名的,这样更加方便理解和易于使用,目前命名按照如下一些规则:
| 接口规则 | 描述 |
| ----------------------- | ------------------------------------------------------------ |
| `is_`, `has_`前缀的接口 | 表示为条件判断 |
| `set_`前缀的接口 | 表示为覆盖设置 |
| `add_`前缀的接口 | 表示为追加设置 |
| `s`后缀的接口 | 表示支持多值传入,例如:`add_files("*.c", "test.cpp")` |
| `on_`前缀的接口 | 表示为覆盖内置脚本 |
| `before_`前缀的接口 | 表示为在内置脚本运行前,执行此脚本 |
| `after_`前缀的接口 | 表示为在内置脚本运行后,执行此脚本 |
| `scope("name")`的接口 | 表示为定义一个描述域,例如:`target("xxx")`, `option("xxx")` |
| 描述域/描述设置 | 建议缩进表示 |
## [条件判断](https://www.bookstack.cn/read/xmake/manual-conditions.md)
条件判断的api一般用于必须要处理特定平台的编译逻辑的场合。。通常跟lua的if语句配合使用。
| 接口 | 描述 | 支持版本 |
| ------------------------------------------------------------ | ---------------------------- | ----------------------- |
| [is_os](https://www.bookstack.cn/read/xmake/manual-conditions.md#is_os) | 判断当前构建目标的操作系统 | >= 2.0.1 |
| [is_arch](https://www.bookstack.cn/read/xmake/manual-conditions.md#is_arch) | 判断当前编译架构 | >= 2.0.1 |
| [is_plat](https://www.bookstack.cn/read/xmake/manual-conditions.md#is_plat) | 判断当前编译平台 | >= 2.0.1 |
| [is_host](https://www.bookstack.cn/read/xmake/manual-conditions.md#is_host) | 判断当前主机环境操作系统 | >= 2.1.4 |
| [is_mode](https://www.bookstack.cn/read/xmake/manual-conditions.md#is_mode) | 判断当前编译模式 | >= 2.0.1 |
| [is_kind](https://www.bookstack.cn/read/xmake/manual-conditions.md#is_kind) | 判断当前编译类型 | >= 2.0.1 |
| [is_option](https://www.bookstack.cn/read/xmake/manual-conditions.md#is_option) | 判断选项是否启用 | >= 2.0.1 < 2.2.2 已废弃 |
| [is_config](https://www.bookstack.cn/read/xmake/manual-conditions.md#is_config) | 判断指定配置是否为给定的值 | >= 2.2.2 |
| [has_config](https://www.bookstack.cn/read/xmake/manual-conditions.md#has_config) | 判断配置是否启用或者存在 | >= 2.2.2 |
| [has_package](https://www.bookstack.cn/read/xmake/manual-conditions.md#has_package) | 判断依赖包是否被启用或者存在 | >= 2.2.3 |
## 特殊字符
### 正则表达式
```lua
-- 递归添加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")
```
### [内置变量](https://www.bookstack.cn/read/xmake/manual-builtin_variables.md)
```lua
target("test")
-- 添加工程源码目录下的源文件
add_files("$(projectdir)/src/*.c")
-- 添加构建目录下的头文件搜索路径
add_includedirs("$(buildir)/inc")
```
| 接口 | 描述 | 支持版本 |
| ------------------------------------------------------------ | --------------------------- | -------- |
| [$(os)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varos) | 获取当前编译平台的操作系统 | >= 2.0.1 |
| [$(host)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varhost) | 获取本机操作系统 | >= 2.0.1 |
| [$(tmpdir)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#vartmpdir) | 获取临时目录 | >= 2.0.1 |
| [$(curdir)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varcurdir) | 获取当前目录 | >= 2.0.1 |
| [$(buildir)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varbuildir) | 获取构建输出目录 | >= 2.0.1 |
| [$(scriptdir)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varscriptdir) | 获取工程描述脚本目录 | >= 2.1.1 |
| [$(globaldir)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varglobaldir) | 获取全局配置目录 | >= 2.0.1 |
| [$(configdir)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varconfigdir) | 获取本地工程配置目录 | >= 2.0.1 |
| [$(programdir)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varprogramdir) | xmake安装脚本目录 | >= 2.1.5 |
| [$(projectdir)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varprojectdir) | 获取工程根目录 | >= 2.0.1 |
| [$(shell)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varshell) | 执行外部shell命令 | >= 2.0.1 |
| [$(env)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varenv) | 获取外部环境变量 | >= 2.1.5 |
| [$(reg)](https://xmake.io/mirror/zh-cn/manual/builtin_variables.html#varreg) | 获取windows注册表配置项的值 | >= 2.1.5 |
## 模块接口
### [内置模块](https://www.bookstack.cn/read/xmake/manual-builtin_modules.md)
### [扩展模块](https://www.bookstack.cn/read/xmake/manual-extension_modules.md)
### 常用接口
- import
- includes
## 测试
```lua
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](https://www.bookstack.cn/read/xmake/guide-configuration.md)
相当于命令行配置,优先级最高
### 类型
本地配置会覆盖全局配置
- 全局配置
- 所有项目生效
- 本地配置
- 本地项目生效
### 作用
- 设置编译选项
- 设置环境变量
- 设置项目配置
## xmake.lua
```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
```lua
--定制化处理target的链接过程
target("test")
on_link(function (target)
print("link it")
end)
```
#### on_build
```lua
--[[
覆盖target目标默认的构建行为实现自定义的编译过程
一般情况下并不需要这么做除非确实需要做一些xmake默认没有提供的编译操作
如果第一个参数为字符串,那么就是指定这个脚本需要在哪个平台|架构下,才会被执行
]]
target("test")
on_build("iphoneos|arm*", function (target)
print("build for iphoneos and arm")
end)
```
#### on_build_file
```lua
--通过此接口可以用来hook指定target内置的构建过程自己重新实现每个源文件编译过程
target("test")
set_kind("binary")
add_files("src/*.c")
on_build_file(function (target, sourcefile, opt)
end)
```
#### on_build_files
```lua
--通过此接口可以用来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
```lua
--覆盖target目标的xmake [c|clean}的清理操作,实现自定义清理过程。
target("test")
-- 设置自定义清理脚本
on_clean(function (target)
-- 仅删掉目标文件
os.rm(target:targetfile())
end)
```
#### on_package
```lua
--覆盖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
```lua
--覆盖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
```lua
--覆盖target目标的xmake [u|uninstall}的卸载操作,实现自定义卸载过程
target("test")
on_uninstall(function (target)
...
end)
```
#### on_run
```lua
--覆盖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
```lua
--定制化处理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](https://www.bookstack.cn/read/xmake/manual-project_target.md)
- 项目属性配置
- 项目间存在继承关系
## 项目配置
```lua
-- 批量导入配置文件
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")
```
## 第三方库
```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")
```
## 编译配置
```lua
-- 启用调试符号
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
```lua
-- 源码地址
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
```shell
#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](https://www.bookstack.cn/read/xmake/manual-plugin_task.md#taskset_category)分类不同而已
| 接口 | 描述 | 支持版本 |
| ------------------------------------------------------------ | ------------------ | -------- |
| [task](https://www.bookstack.cn/read/xmake/manual-plugin_task.md#task) | 定义插件或者任务 | >= 2.0.1 |
| [task_end](https://www.bookstack.cn/read/xmake/manual-plugin_task.md#task_end) | 结束定义插件或任务 | >= 2.1.1 |
| [set_menu](https://www.bookstack.cn/read/xmake/manual-plugin_task.md#taskset_menu) | 设置任务菜单 | >= 2.0.1 |
| [set_category](https://www.bookstack.cn/read/xmake/manual-plugin_task.md#taskset_category) | 设置任务类别 | >= 2.0.1 |
| [on_run](https://www.bookstack.cn/read/xmake/manual-plugin_task.md#taskon_run) | 设置任务运行脚本 | >= 2.0.1 |