定义和设置选项开关,每个`option`对应一个选项,可用于自定义编译配置选项、开关设置。
除了`target`以外的所有域接口,例如`option`,`task`等的接口,默认不能放置在外面的全局作用域中的(除非部分跟target共用的接口除外)。 如果要设置值影响所有`option`,`task`等选项,可以通过匿名全局域来设置。
例如: ```lua -- 进入option的匿名全局域,里面的设置会同时影响test和test2选项 option() add_defines("DEBUG") option("test") -- ... -- 尽量保持缩进,因为这个之后的所有设置,都是针对test选项的 option("test2") -- ... ````option`域是可以重复进入来实现分离设置的,如果要显示离开当前选项的作用域设置,可以手动调用[option_end](#option_end)接口。
| 接口 | 描述 | 支持版本 | | ----------------------------------------------------- | -------------------------------------------- | -------- | | [option](#option) | 定义选项 | >= 2.0.1 | | [option_end](#option_end) | 结束定义选项 | >= 2.1.1 | | [add_deps](#optionadd_deps) | 添加选项依赖 | >= 2.1.5 | | [before_check](#optionbefore_check) | 选项检测之前执行此脚本 | >= 2.1.5 | | [on_check](#optionon_check) | 自定义选项检测脚本 | >= 2.1.5 | | [after_check](#optionafter_check) | 选项检测之后执行此脚本 | >= 2.1.5 | | [set_values](#optionset_values) | 设置选项值列表 | >= 2.1.9 | | [set_default](#optionset_default) | 设置默认值 | >= 2.0.1 | | [set_showmenu](#optionset_showmenu) | 设置是否启用菜单显示 | >= 1.0.1 | | [set_category](#optionset_category) | 设置选项分类,仅用于菜单显示 | >= 1.0.1 | | [set_description](#optionset_description) | 设置菜单显示描述 | >= 1.0.1 | | [add_links](#optionadd_links) | 添加链接库检测 | >= 1.0.1 | | [add_linkdirs](#optionadd_linkdirs) | 添加链接库检测需要的搜索目录 | >= 1.0.1 | | [add_rpathdirs](#optionadd_rpathdirs) | 添加运行时候动态链接库搜索目录 | >= 2.1.3 | | [add_cincludes](#optionadd_cincludes) | 添加c头文件检测 | >= 1.0.1 | | [add_cxxincludes](#optionadd_cxxincludes) | 添加c++头文件检测 | >= 1.0.1 | | [add_ctypes](#optionadd_ctypes) | 添加c类型检测 | >= 1.0.1 | | [add_cxxtypes](#optionadd_cxxtypes) | 添加c++类型检测 | >= 1.0.1 | | [add_csnippet](#optionadd_csnippet) | 添加c代码片段检测 | >= 2.1.5 | | [add_cxxsnippet](#optionadd_cxxsnippet) | 添加c++代码片段检测 | >= 2.1.5 | | [set_warnings](#targetset_warnings) | 设置警告级别 | >= 1.0.1 | | [set_optimize](#targetset_optimize) | 设置优化级别 | >= 1.0.1 | | [set_languages](#targetset_languages) | 设置代码语言标准 | >= 1.0.1 | | [add_includedirs](#targetadd_includedirs) | 添加头文件搜索目录 | >= 1.0.1 | | [add_defines](#targetadd_defines) | 添加宏定义 | >= 1.0.1 | | [add_undefines](#targetadd_undefines) | 取消宏定义 | >= 1.0.1 | | [add_defines_h](#targetadd_defines_h) | 添加宏定义到头文件 | >= 1.0.1 | | [add_undefines_h](#targetadd_undefines_h) | 取消宏定义到头文件 | >= 1.0.1 | | [add_cflags](#targetadd_cflags) | 添加c编译选项 | >= 1.0.1 | | [add_cxflags](#targetadd_cxflags) | 添加c/c++编译选项 | >= 1.0.1 | | [add_cxxflags](#targetadd_cxxflags) | 添加c++编译选项 | >= 1.0.1 | | [add_mflags](#targetadd_mflags) | 添加objc编译选项 | >= 2.0.1 | | [add_mxflags](#targetadd_mxflags) | 添加objc/objc++编译选项 | >= 2.0.1 | | [add_mxxflags](#targetadd_mxxflags) | 添加objc++编译选项 | >= 2.0.1 | | [add_scflags](#targetadd_scflags) | 添加swift编译选项 | >= 2.1.1 | | [add_asflags](#targetadd_asflags) | 添加汇编编译选项 | >= 2.1.1 | | [add_gcflags](#targetadd_gcflags) | 添加go编译选项 | >= 2.1.1 | | [add_dcflags](#targetadd_dcflags) | 添加dlang编译选项 | >= 2.1.1 | | [add_rcflags](#targetadd_rcflags) | 添加rust编译选项 | >= 2.1.1 | | [add_cuflags](#targetadd_cuflags) | 添加cuda编译选项 | >= 2.2.1 | | [add_culdflags](#targetadd_culdflags) | 添加cuda设备链接选项 | >= 2.2.7 | | [add_ldflags](#targetadd_ldflags) | 添加链接选项 | >= 2.1.1 | | [add_arflags](#targetadd_arflags) | 添加静态库归档选项 | >= 2.1.1 | | [add_shflags](#targetadd_shflags) | 添加动态库链接选项 | >= 2.0.1 | | [add_cfuncs](#targetadd_cfuncs) | 添加c库函数检测 | >= 1.0.1 | | [add_cxxfuncs](#targetadd_cxxfuncs) | 添加c++库函数接口 | >= 1.0.1 | | [add_languages](#targetadd_languages) | 添加语言标准 | >= 2.0.1 | | [add_vectorexts](#targetadd_vectorexts) | 添加向量扩展指令 | >= 2.0.1 | | [add_frameworks](#targetadd_frameworks) | 添加链接框架 | >= 2.1.1 | | [add_frameworkdirs](#targetadd_frameworkdirs) | 添加链接框架 | >= 2.1.5 | ### option #### 定义选项 定义和设置选项开关,可用于自定义编译配置选项、开关设置。 例如,定义一个是否启用test的选项: ```lua option("test") set_default(false) set_showmenu(true) add_defines("TEST") ``` 然后关联到指定的target中去: ```lua target("demo") add_options("test") ``` 这样,一个选项就算定义好了,如果这个选项被启用,那么编译这个target的时候,就会自动加上`-DTEST`的宏定义。 ```lua # 手动启用这个选项 $ xmake f --test=y $ xmake ``` ### option_end #### 结束定义选项 这是一个可选api,显示离开选项作用域,用法和[target_end](#target_end)类似。 ### option:add_deps #### 添加选项依赖 通过设置依赖,可以调整选项的检测顺序,一般用于[on_check](#optionon_check)等检测脚本的调用时机。 ```lua option("small") set_default(true) on_check(function (option) -- ... end) option("test") add_deps("small") set_default(true) on_check(function (option) if option:dep("small"):enabled() then option:enable(false) end end) ``` 当依赖的small选项检测完成后,通过判断small选项的状态,来控制test的选项状态。 ### option:before_check #### 选项检测之前执行此脚本 例如:在检测之前,通过[find_package](#detect-find_package)来查找包,将`links`, `includedirs`和`linkdirs`等信息添加到option中去, 然后开始选项检测,通过后就会自动链接到target上。 ```lua option("zlib") before_check(function (option) import("lib.detect.find_package") option:add(find_package("zlib")) end) ``` ### option:on_check #### 自定义选项检测脚本 此脚本会覆盖内置的选项检测逻辑。 ```lua option("test") add_deps("small") set_default(true) on_check(function (option) if option:dep("small"):enabled() then option:enable(false) end end) ``` 如果test依赖的选项通过,则禁用test选项。 ### option:after_check #### 选项检测之后执行此脚本 在选项检测完成后,执行此脚本做一些后期处理,也可以在此时重新禁用选项: ```lua option("test") add_deps("small") add_links("pthread") after_check(function (option) option:enable(false) end) ``` ### option:set_values #### 设置选项值列表 仅用于`xmake f --menu`的图形菜单配置时,提供选项值列表供用户快速选择使用,例如: ```lua option("test") set_default("b") set_showmenu(true) set_values("a", "b", "c") ``` 效果图如下:
### option:set_default
#### 设置选项默认值
在没有通过`xmake f --option=[y|n}`等命令修改选项值的时候,这个选项本身也是有个默认值的,可以通过这个接口来设置:
```lua
option("test")
-- 默认禁用这个选项
set_default(false)
```
选项的值不仅支持boolean类型,也可以是字符串类型,例如:
```lua
option("test")
set_default("value")
```
| 值类型 | 描述 | 配置 |
| ------ | -------------------------------------- | -----------------------------------------------|
| boolean | 一般用作参数开关,值范围:`true/false` | `xmake f --optionname=[y/n/yes/no/true/false]` |
| string | 可以是任意字符串,一般用于模式判断 | `xmake f --optionname=value` |
如果是`boolean`值的选项,可以通过[is_option](#is_option)来进行判断,选项是否被启用。
如果是`string`类型的选项,可以在内建变量中直接使用,例如:
```lua
-- 定义一个路径配置选项,默认使用临时目录
option("rootdir")
set_default("$(tmpdir)")
set_showmenu(true)
target("test")
-- 添加指定选项目录中的源文件
add_files("$(rootdir)/*.c")
```
其中,`$(rootdir)` 就是自定义的选项内建变量,通过手动配置,可以动态修改它的值:
```bash
$ xmake f --rootdir=~/projectdir/src
$ xmake
```
给这个`rootdir`选项指定一个其他的源码目录路径,然后编译。
选项的检测行为:
| default值 | 检测行为 |
| ---------- | --------------------------------------------------------------------------------------------- |
| 没有设置 | 优先手动配置修改,默认禁用,否则自动检测,可根据手动传入的值类型,自动切换boolean和string类型 |
| false | 开关选项,不自动检测,默认禁用,可手动配置修改 |
| true | 开关选项,不自动检测,默认启用,可手动配置修改 |
| string类型 | 无开关状态,不自动检测,可手动配置修改,一般用于配置变量传递 |
### option:set_showmenu
#### 设置是否启用菜单显示
如果设置为`true`,那么在`xmake f --help`里面就会出现这个选项,也就能通过`xmake f --optionname=xxx`进行配置,否则只能在`xmake.lua`内部使用,无法手动配置修改。
```lua
option("test")
set_showmenu(true)
```
设置为启用菜单后,执行`xmake f --help`可以看到,帮助菜单里面多了一项:
```
Options:
...
--test=TEST
```
### option:set_category
#### 设置选项分类,仅用于菜单显示
这个是个可选配置,仅用于在帮助菜单中,进行分类显示选项,同一类别的选项,会在同一个分组里面显示,这样菜单看起来更加的美观。
例如:
```lua
option("test1")
set_showmenu(true)
set_category("test")
option("test2")
set_showmenu(true)
set_category("test")
option("demo1")
set_showmenu(true)
set_category("demo")
option("demo2")
set_showmenu(true)
set_category("demo")
```
这里四个选项分别归类于两个分组:`test`和`demo`,那么显示的布局类似这样:
```bash
Options:
...
--test1=TEST1
--test2=TEST2
--demo1=DEMO1
--demo2=DEMO2
```
这个接口,仅仅是为了调整显示布局,更加美观而已,没其他用途。
在2.1.9版本中,可以通过category设置分级路径名`set_category("root/submenu/submenu2")`,来配置`xmake f --menu`的图形菜单界面,例如:
```lua
-- 'boolean' option
option("test1")
set_default(true)
set_showmenu(true)
set_category("root menu/test1")
-- 'choice' option with values: "a", "b", "c"
option("test2")
set_default("a")
set_values("a", "b", "c")
set_showmenu(true)
set_category("root menu/test2")
-- 'string' option
option("test3")
set_default("xx")
set_showmenu(true)
set_category("root menu/test3/test3")
-- 'number' option
option("test4")
set_default(6)
set_showmenu(true)
set_category("root menu/test4")
```
上述配置最后显示的菜单界面路径结构:
- root menu
- test1
- test2
- test3
- test3
- test4
效果图如下:
### option:set_description
#### 设置菜单显示描述
设置选项菜单显示时,右边的描述信息,用于帮助用户更加清楚的知道这个选项的用途,例如:
```lua
option("test")
set_default(false)
set_showmenu(true)
set_description("Enable or disable test")
```
生成的菜单内容如下:
```
Options:
...
--test=TEST Enable or disable test (default: false)
```
这个接口也支持多行显示,输出更加详细的描述信息,例如:
```lua
option("mode")
set_default("debug")
set_showmenu(true)
set_description("Set build mode",
" - debug",
" - release",
" - profile")
```
生成的菜单内容如下:
```
Options:
...
--mode=MODE Set build mode (default: debug)
- debug
- release
- profile
```
看到这个菜单,用户就能清楚地知道,定义的这个`mode`选项的具体用处,以及如何使用了:
```bash
$ xmake f --mode=release
```
### option:add_links
#### 添加链接库检测
如果指定的链接库检测通过,此选项将被启用,并且对应关联的target会自动加上此链接,例如:
```lua
option("pthread")
set_default(false)
add_links("pthread")
add_linkdirs("/usr/local/lib")
target("test")
add_options("pthread")
```
如果检测通过,`test`目标编译的时候就会自动加上:`-L/usr/local/lib -lpthread` 编译选项
### option:add_linkdirs
#### 添加链接库检测时候需要的搜索目录
这个是可选的,一般系统库不需要加这个,也能检测通过,如果确实没找到,可以自己追加搜索目录,提高检测通过率。具体使用见:[add_links](#optionadd_links)
### option:add_rpathdirs
#### 添加程序运行时动态库的加载搜索目录
在选项通过检测后,会自动添加到对应的target上去,具体使用见:[target.add_rpathdirs](#targetadd_rpathdirs)。
### option:add_cincludes
#### 添加c头文件检测
如果c头文件检测通过,此选项将被启用,例如:
```lua
option("pthread")
set_default(false)
add_cincludes("pthread.h")
add_defines("ENABLE_PTHREAD")
target("test")
add_options("pthread")
```
此选项检测是否存在`pthread.h`的头文件,如果检测通过那么`test`目标程序将会加上`ENABLE_PTHREAD`的宏定义。
如果想要更加灵活的检测,可以通过[lib.detect.has_cincludes](#detect-has_cincludes)在[option.on_check](#optionon_check)中去实现。
### option:add_cxxincludes
#### 添加c++头文件检测
与[add_cincludes](#optionadd_cincludes)类似,只是检测的头文件类型是c++头文件。
### option:add_ctypes
#### 添加c类型检测
如果c类型检测通过,此选项将被启用,例如:
```lua
option("wchar")
set_default(false)
add_cincludes("wchar_t")
add_defines("HAVE_WCHAR")
target("test")
add_options("wchar")
```
此选项检测是否存在`wchar_t`的类型,如果检测通过那么`test`目标程序将会加上`HAVE_WCHAR`的宏定义。
如果想要更加灵活的检测,可以通过[lib.detect.has_ctypes](#detect-has_ctypes)在[option.on_check](#optionon_check)中去实现。
### option:add_cxxtypes
#### 添加c++类型检测
与[add_ctypes](#optionadd_ctypes)类似,只是检测的类型是c++类型。
### option:add_csnippet
#### 添加c代码片段检测
如果现有的[add_ctypes](#optionadd_ctypes), [add_cfuncs](#optionadd_cfuncs)等不能满足当前的检测需求,
可以用这个接口实现更加定制化检测一些编译器特性检测,具体见: [add_cxxsnippet](#optionadd_cxxsnippet)。
### option:add_cxxsnippet
#### 添加c++代码片段检测
可以用这个接口实现更加定制化检测一些编译器特性检测,尤其是c++的各种特性的检测支持,例如:
```lua
option("constexpr")
add_cxxsnippet("constexpr", "constexpr int f(int x) { int sum=0; for (int i=0; i<=x; ++i) sum += i; return sum; } constexpr int x = f(5); static_assert(x == 15);")
```
第一个参数设置代码片段的名字作为标示,检测输出信息时候会有显示。
上述代码,实现对c++的constexpr特性的检测,如果检测通过,则启用constexpr选项,当然这里只是个例子。
对于编译器特性的检测,有更加方便高效的检测模块,提供更强大的检测支持,具体见:[compiler.has_features](#compiler-has_features)和[detect.check_cxsnippets](#detect-check_cxsnippets)
如果想要更加灵活的检测,可以通过[lib.detect.check_cxsnippets](#detect-check_cxsnippets)在[option.on_check](#optionon_check)中去实现。