diff options
| author | ruki <[email protected]> | 2017-07-26 17:00:20 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2017-07-26 17:00:20 +0800 |
| commit | 20866bd9ff8d8cf6a4bbc165d6702e3c2b5a9ca8 (patch) | |
| tree | 32e5c51a35520ffcddcb9d900ba76e59fa7d71c3 /docs | |
| parent | 41b7a4be4010495f6c6876534e9a78121021bb80 (diff) | |
update docs
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/manual.md | 2052 | ||||
| -rw-r--r-- | docs/zh/manual.md | 176 |
2 files changed, 1954 insertions, 274 deletions
diff --git a/docs/manual.md b/docs/manual.md index fecdc8982..4ef2b90df 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -461,74 +461,76 @@ target("test2") </p> -| 接口 | 描述 | 支持版本 | -| ------------------------------------------- | ------------------------------------ | -------- | -| [target](#target) | 定义工程目标 | >= 1.0.1 | -| [target_end](#target_end) | 结束定义工程目标 | >= 2.1.1 | -| [set_kind](#targetset_kind) | 设置目标编译类型 | >= 1.0.1 | -| [set_strip](#targetset_strip) | 设置是否strip信息 | >= 1.0.1 | -| [set_default](#targetset_default) | 设置是否为默认构建安装目标 | >= 2.1.3 | -| [set_options](#targetset_options) | 设置关联选项 | >= 1.0.1 | -| [set_symbols](#targetset_symbols) | 设置符号信息 | >= 1.0.1 | -| [set_basename](#targetset_basename) | 设置目标文件名 | >= 2.1.2 | -| [set_warnings](#targetset_warnings) | 设置警告级别 | >= 1.0.1 | -| [set_optimize](#targetset_optimize) | 设置优化级别 | >= 1.0.1 | -| [set_languages](#targetset_languages) | 设置代码语言标准 | >= 1.0.1 | -| [set_headerdir](#targetset_headerdir) | 设置头文件安装目录 | >= 1.0.1 | -| [set_targetdir](#targetset_targetdir) | 设置生成目标文件目录 | >= 1.0.1 | -| [set_objectdir](#targetset_objectdir) | 设置对象文件生成目录 | >= 1.0.1 | -| [on_build](#targeton_build) | 自定义编译脚本 | >= 2.0.1 | -| [on_clean](#targeton_clean) | 自定义清理脚本 | >= 2.0.1 | -| [on_package](#targeton_package) | 自定义打包脚本 | >= 2.0.1 | -| [on_install](#targeton_install) | 自定义安装脚本 | >= 2.0.1 | -| [on_uninstall](#targeton_uninstall) | 自定义卸载脚本 | >= 2.0.1 | -| [on_run](#targeton_run) | 自定义运行脚本 | >= 2.0.1 | -| [before_build](#targetbefore_build) | 在构建之前执行一些自定义脚本 | >= 2.0.1 | -| [before_clean](#targetbefore_clean) | 在清除之前执行一些自定义脚本 | >= 2.0.1 | -| [before_package](#targetbefore_package) | 在打包之前执行一些自定义脚本 | >= 2.0.1 | -| [before_install](#targetbefore_install) | 在安装之前执行一些自定义脚本 | >= 2.0.1 | -| [before_uninstall](#targetbefore_uninstall) | 在卸载之前执行一些自定义脚本 | >= 2.0.1 | -| [before_run](#targetbefore_run) | 在运行之前执行一些自定义脚本 | >= 2.0.1 | -| [after_build](#targetafter_build) | 在构建之后执行一些自定义脚本 | >= 2.0.1 | -| [after_clean](#targetafter_clean) | 在清除之后执行一些自定义脚本 | >= 2.0.1 | -| [after_package](#targetafter_package) | 在打包之后执行一些自定义脚本 | >= 2.0.1 | -| [after_install](#targetafter_install) | 在安装之后执行一些自定义脚本 | >= 2.0.1 | -| [after_uninstall](#targetafter_uninstall) | 在卸载之后执行一些自定义脚本 | >= 2.0.1 | -| [after_run](#targetafter_run) | 在运行之后执行一些自定义脚本 | >= 2.0.1 | -| [set_config_h](#targetset_config_h) | 设置自动生成的配置头文件路径 | >= 1.0.1 | -| [set_config_h_prefix](#targetset_config_h) | 设置自动生成的头文件中宏定义命名前缀 | >= 1.0.1 | -| [add_deps](#targetadd_deps) | 添加子工程目标依赖 | >= 1.0.1 | -| [add_links](#targetadd_links) | 添加链接库名 | >= 1.0.1 | -| [add_files](#targetadd_files) | 添加源代码文件 | >= 1.0.1 | -| [add_headers](#targetadd_headers) | 添加安装的头文件 | >= 1.0.1 | -| [add_linkdirs](#targetadd_linkdirs) | 添加链接库搜索目录 | >= 1.0.1 | -| [add_rpathdirs](#targetadd_rpathdirs) | 添加运行时候动态链接库搜索目录 | >= 2.1.3 | -| [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编译选项 | >= 1.0.1 | -| [add_mxflags](#targetadd_mxflags) | 添加objc/objc++编译选项 | >= 1.0.1 | -| [add_mxxflags](#targetadd_mxxflags) | 添加objc++编译选项 | >= 1.0.1 | -| [add_scflags](#targetadd_scflags) | 添加swift编译选项 | >= 2.0.1 | -| [add_asflags](#targetadd_asflags) | 添加汇编编译选项 | >= 2.0.1 | -| [add_gcflags](#targetadd_gcflags) | 添加go编译选项 | >= 2.1.1 | -| [add_ldflags](#targetadd_ldflags) | 添加链接选项 | >= 1.0.1 | -| [add_arflags](#targetadd_arflags) | 添加静态库归档选项 | >= 1.0.1 | -| [add_shflags](#targetadd_shflags) | 添加动态库链接选项 | >= 1.0.1 | -| [add_cfunc](#targetadd_cfunc) | 添加单个c库函数检测 | >= 2.0.1 | -| [add_cxxfunc](#targetadd_cxxfunc) | 添加单个c++库函数检测 | >= 2.0.1 | -| [add_cfuncs](#targetadd_cfuncs) | 添加c库函数检测 | >= 2.0.1 | -| [add_cxxfuncs](#targetadd_cxxfuncs) | 添加c++库函数接口 | >= 2.0.1 | -| [add_packages](#targetadd_packages) | 添加包依赖 | >= 2.0.1 | -| [add_options](#targetadd_options) | 添加关联选项 | >= 2.0.1 | -| [add_languages](#targetadd_languages) | 添加语言标准 | >= 1.0.1 | -| [add_vectorexts](#targetadd_vectorexts) | 添加向量扩展指令 | >= 1.0.1 | -| [add_frameworks](#targetadd_frameworks) | 添加链接框架 | >= 2.1.1 | +| 接口 | 描述 | 支持版本 | +| --------------------------------------------- | ------------------------------------ | -------- | +| [target](#target) | 定义工程目标 | >= 1.0.1 | +| [target_end](#target_end) | 结束定义工程目标 | >= 2.1.1 | +| [set_kind](#targetset_kind) | 设置目标编译类型 | >= 1.0.1 | +| [set_strip](#targetset_strip) | 设置是否strip信息 | >= 1.0.1 | +| [set_default](#targetset_default) | 设置是否为默认构建安装目标 | >= 2.1.3 | +| [set_options](#targetset_options) | 设置关联选项 | >= 1.0.1 | +| [set_symbols](#targetset_symbols) | 设置符号信息 | >= 1.0.1 | +| [set_basename](#targetset_basename) | 设置目标文件名 | >= 2.1.2 | +| [set_warnings](#targetset_warnings) | 设置警告级别 | >= 1.0.1 | +| [set_optimize](#targetset_optimize) | 设置优化级别 | >= 1.0.1 | +| [set_languages](#targetset_languages) | 设置代码语言标准 | >= 1.0.1 | +| [set_headerdir](#targetset_headerdir) | 设置头文件安装目录 | >= 1.0.1 | +| [set_targetdir](#targetset_targetdir) | 设置生成目标文件目录 | >= 1.0.1 | +| [set_objectdir](#targetset_objectdir) | 设置对象文件生成目录 | >= 1.0.1 | +| [on_load](#targeton_load) | 自定义目标加载脚本 | >= 2.1.5 | +| [on_build](#targeton_build) | 自定义编译脚本 | >= 2.0.1 | +| [on_clean](#targeton_clean) | 自定义清理脚本 | >= 2.0.1 | +| [on_package](#targeton_package) | 自定义打包脚本 | >= 2.0.1 | +| [on_install](#targeton_install) | 自定义安装脚本 | >= 2.0.1 | +| [on_uninstall](#targeton_uninstall) | 自定义卸载脚本 | >= 2.0.1 | +| [on_run](#targeton_run) | 自定义运行脚本 | >= 2.0.1 | +| [before_build](#targetbefore_build) | 在构建之前执行一些自定义脚本 | >= 2.0.1 | +| [before_clean](#targetbefore_clean) | 在清除之前执行一些自定义脚本 | >= 2.0.1 | +| [before_package](#targetbefore_package) | 在打包之前执行一些自定义脚本 | >= 2.0.1 | +| [before_install](#targetbefore_install) | 在安装之前执行一些自定义脚本 | >= 2.0.1 | +| [before_uninstall](#targetbefore_uninstall) | 在卸载之前执行一些自定义脚本 | >= 2.0.1 | +| [before_run](#targetbefore_run) | 在运行之前执行一些自定义脚本 | >= 2.0.1 | +| [after_build](#targetafter_build) | 在构建之后执行一些自定义脚本 | >= 2.0.1 | +| [after_clean](#targetafter_clean) | 在清除之后执行一些自定义脚本 | >= 2.0.1 | +| [after_package](#targetafter_package) | 在打包之后执行一些自定义脚本 | >= 2.0.1 | +| [after_install](#targetafter_install) | 在安装之后执行一些自定义脚本 | >= 2.0.1 | +| [after_uninstall](#targetafter_uninstall) | 在卸载之后执行一些自定义脚本 | >= 2.0.1 | +| [after_run](#targetafter_run) | 在运行之后执行一些自定义脚本 | >= 2.0.1 | +| [set_config_h](#targetset_config_h) | 设置自动生成的配置头文件路径 | >= 1.0.1 | +| [set_config_h_prefix](#targetset_config_h) | 设置自动生成的头文件中宏定义命名前缀 | >= 1.0.1 | +| [add_deps](#targetadd_deps) | 添加子工程目标依赖 | >= 1.0.1 | +| [add_links](#targetadd_links) | 添加链接库名 | >= 1.0.1 | +| [add_files](#targetadd_files) | 添加源代码文件 | >= 1.0.1 | +| [add_headers](#targetadd_headers) | 添加安装的头文件 | >= 1.0.1 | +| [add_linkdirs](#targetadd_linkdirs) | 添加链接库搜索目录 | >= 1.0.1 | +| [add_rpathdirs](#targetadd_rpathdirs) | 添加运行时候动态链接库搜索目录 | >= 2.1.3 | +| [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编译选项 | >= 1.0.1 | +| [add_mxflags](#targetadd_mxflags) | 添加objc/objc++编译选项 | >= 1.0.1 | +| [add_mxxflags](#targetadd_mxxflags) | 添加objc++编译选项 | >= 1.0.1 | +| [add_scflags](#targetadd_scflags) | 添加swift编译选项 | >= 2.0.1 | +| [add_asflags](#targetadd_asflags) | 添加汇编编译选项 | >= 2.0.1 | +| [add_gcflags](#targetadd_gcflags) | 添加go编译选项 | >= 2.1.1 | +| [add_ldflags](#targetadd_ldflags) | 添加链接选项 | >= 1.0.1 | +| [add_arflags](#targetadd_arflags) | 添加静态库归档选项 | >= 1.0.1 | +| [add_shflags](#targetadd_shflags) | 添加动态库链接选项 | >= 1.0.1 | +| [add_cfunc](#targetadd_cfunc) | 添加单个c库函数检测 | >= 2.0.1 | +| [add_cxxfunc](#targetadd_cxxfunc) | 添加单个c++库函数检测 | >= 2.0.1 | +| [add_cfuncs](#targetadd_cfuncs) | 添加c库函数检测 | >= 2.0.1 | +| [add_cxxfuncs](#targetadd_cxxfuncs) | 添加c++库函数接口 | >= 2.0.1 | +| [add_packages](#targetadd_packages) | 添加包依赖 | >= 2.0.1 | +| [add_options](#targetadd_options) | 添加关联选项 | >= 2.0.1 | +| [add_languages](#targetadd_languages) | 添加语言标准 | >= 1.0.1 | +| [add_vectorexts](#targetadd_vectorexts) | 添加向量扩展指令 | >= 1.0.1 | +| [add_frameworks](#targetadd_frameworks) | 添加链接框架 | >= 2.1.1 | +| [add_frameworkdirs](#targetadd_frameworkdirs) | 添加链接框架的搜索目录 | >= 2.1.5 | ##### target @@ -692,6 +694,7 @@ $ xmake install targetname $ xmake build [-a|--all] $ xmake install [-a|--all] ``` + ##### target:set_options ###### 设置关联选项 @@ -906,6 +909,23 @@ target("test") set_objectdir("$(buildir)/.objs") ``` +##### target:on_load + +###### 自定义目标加载脚本 + +在target初始化加载的时候,将会执行此脚本,在里面可以做一些动态的目标配置,实现更灵活的目标描述定义,例如: + +```lua +target("test") + on_load(function (target) + target:add("defines", "DEBUG", "TEST=\"hello\"") + target:add("linkdirs", "/usr/lib", "/usr/local/lib") + target:add({includedirs = "/usr/include", "links" = "pthread"}) + end) +``` + +可以在`on_load`里面,通过`target:set`, `target:add` 来动态添加各种target属性。 + ##### target:on_build ###### 自定义编译脚本 @@ -923,7 +943,27 @@ target("test") end) ``` -<p class="warning"> +注:2.1.5版本之后,所有target的自定义脚本都可以针对不同平台和架构,分别处理,例如: + +```lua +target("test") + on_build("iphoneos|arm*", function (target) + print("build for iphoneos and arm") + end) +``` + +其中如果第一个参数为字符串,那么就是指定这个脚本需要在哪个`平台|架构`下,才会被执行,并且支持模式匹配,例如`arm*`匹配所有arm架构。 + +当然也可以只设置平台,不设置架构,这样就是匹配指定平台下,执行脚本: + +```lua +target("test") + on_build("windows", function (target) + print("build for windows") + end) +``` + +<p class="tip"> 一旦对这个target目标设置了自己的build过程,那么xmake默认的构建过程将不再被执行。 </p> @@ -946,13 +986,18 @@ target("test") 一些target接口描述如下: -| target接口 | 描述 | -| --------------------- | ---------------------------------------------------------------- | -| target:name() | 获取目标名 | -| target:targetfile() | 获取目标文件路径 | -| target:get("kind") | 获取目标的构建类型 | -| target:get("defines") | 获取目标的宏定义 | -| target:get("xxx") | 其他通过 `set_/add_`接口设置的target信息,都可以通过此接口来获取 | +| target接口 | 描述 | +| ----------------------------------- | ---------------------------------------------------------------- | +| target:name() | 获取目标名 | +| target:targetfile() | 获取目标文件路径 | +| target:get("kind") | 获取目标的构建类型 | +| target:get("defines") | 获取目标的宏定义 | +| target:get("xxx") | 其他通过 `set_/add_`接口设置的target信息,都可以通过此接口来获取 | +| target:add("links", "pthread") | 添加目标设置 | +| target:set("links", "pthread", "z") | 覆写目标设置 | +| target:deps() | 获取目标的所有依赖目标 | +| target:dep("depname") | 获取指定的依赖目标 | +| target:sourcebatches() | 获取目标的所有源文件列表 | ##### target:on_package @@ -1047,9 +1092,9 @@ target("test") ```lua target("test") - before_build(function (target)) + before_build(function (target) print("") - end + end) ``` ##### target:before_clean @@ -1060,9 +1105,9 @@ target("test") ```lua target("test") - before_clean(function (target)) + before_clean(function (target) print("") - end + end) ``` ##### target:before_package @@ -1073,9 +1118,9 @@ target("test") ```lua target("test") - before_package(function (target)) + before_package(function (target) print("") - end + end) ``` ##### target:before_install @@ -1086,9 +1131,9 @@ target("test") ```lua target("test") - before_install(function (target)) + before_install(function (target) print("") - end + end) ``` ##### target:before_uninstall @@ -1099,9 +1144,9 @@ target("test") ```lua target("test") - before_uninstall(function (target)) + before_uninstall(function (target) print("") - end + end) ``` ##### target:before_run @@ -1112,9 +1157,9 @@ target("test") ```lua target("test") - before_run(function (target)) + before_run(function (target) print("") - end + end) ``` ##### target:after_build @@ -1127,9 +1172,9 @@ target("test") ```lua target("test") - after_build(function (target)) + after_build(function (target) os.run("ldid -S %s", target:targetfile()) - end + end) ``` ##### target:after_clean @@ -1142,9 +1187,9 @@ target("test") ```lua target("test") - after_clean(function (target)) + after_clean(function (target) os.rm("$(buildir)/otherfiles") - end + end) ``` ##### target:after_package @@ -1155,9 +1200,9 @@ target("test") ```lua target("test") - after_package(function (target)) + after_package(function (target) print("") - end + end) ``` ##### target:after_install @@ -1168,9 +1213,9 @@ target("test") ```lua target("test") - after_install(function (target)) + after_install(function (target) print("") - end + end) ``` ##### target:after_uninstall @@ -1180,9 +1225,9 @@ target("test") ```lua target("test") - after_uninstall(function (target)) + after_uninstall(function (target) print("") - end + end) ``` ##### target:after_run @@ -1193,9 +1238,9 @@ target("test") ```lua target("test") - after_run(function (target)) + after_run(function (target) print("") - end + end) ``` ##### target:set_config_h @@ -1285,6 +1330,44 @@ target("demo") 上面的例子,在编译目标demo的时候,需要先编译test1, test2目标,因为demo会去用到他们 +<p class="tip"> +2.1.5版本后,target会自动继承依赖目标中的配置和属性,不再需要额外调用`add_links`, `add_includedirs`和`add_linkdirs`等接口去关联依赖目标了。 +</p> + +2.1.5版本之后,上述代码可简化为: + +```lua +target("test1") + set_kind("static") + set_files("*.c") + +target("test2") + set_kind("static") + set_files("*.c") + +target("demo") + add_deps("test1", "test2") -- 会自动链接依赖目标 +``` + +并且继承关系是支持级联的,例如: + +```lua +target("library1") + set_kind("static") + add_files("*.c") + add_headers("inc1/*.h") + +target("library2") + set_kind("static") + add_deps("library1") + add_files("*.c") + add_headers("inc2/*.h") + +target("test") + set_kind("binary") + add_deps("library2") +``` + ##### target:add_links ###### 添加链接库名 @@ -1316,6 +1399,7 @@ target("demo") | .go | golang文件 | | .o/.obj | 对象文件 | | .a/.lib | 静态库文件,会自动合并库到目标程序 | +| .rc | msvc的资源文件 | 其中通配符`*`表示匹配当前目录下文件,而`**`则匹配多级目录下的文件。 @@ -1637,6 +1721,8 @@ target("demo") #endif ``` +如果要更加灵活的函数检测,可以通过[lib.detect.has_cfuncs](#detect-has_cfuncs)在自定义脚本中实现。 + ##### target:add_cxxfunc ###### 添加单个c++库函数检测 @@ -1800,6 +1886,18 @@ target("test") 如果不是这两个平台,这些设置将会被忽略。 +##### target:add_frameworkdirs + +###### 添加链接框架搜索目录 + +对于一些第三方framework,那么仅仅通过[add_frameworks](#targetadd_frameworks)是没法找到的,还需要通过这个接口来添加搜索目录。 + +```lua +target("test") + add_frameworks("MyFramework") + add_frameworkdirs("/tmp/frameworkdir", "/tmp/frameworkdir2") +``` + #### Configuration Option 定义和设置选项开关,每个`option`对应一个选项,可用于自定义编译配置选项、开关设置。 @@ -1833,12 +1931,14 @@ option("test2") | ----------------------------------------------------- | -------------------------------------------- | -------- | | [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_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_bindings](#optionadd_bindings) | 添加正向关联选项,同步启用和禁用 | >= 2.0.1 | -| [add_rbindings](#optionadd_rbindings) | 添加逆向关联选项,同步启用和禁用 | >= 2.0.1 | | [add_links](#optionadd_links) | 添加链接库检测 | >= 1.0.1 | | [add_linkdirs](#optionadd_linkdirs) | 添加链接库检测需要的搜索目录 | >= 1.0.1 | | [add_rpathdirs](#optionadd_rpathdirs) | 添加运行时候动态链接库搜索目录 | >= 2.1.3 | @@ -1846,45 +1946,45 @@ option("test2") | [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_defines_if_ok](#optionadd_defines_if_ok) | 如果检测选项通过,则添加宏定义 | >= 1.0.1 | -| [add_defines_h_if_ok](#optionadd_defines_h_if_ok) | 如果检测选项通过,则添加宏定义到配置头文件 | >= 1.0.1 | -| [add_undefines_if_ok](#optionadd_undefines_if_ok) | 如果检测选项通过,则取消宏定义 | >= 1.0.1 | -| [add_undefines_h_if_ok](#optionadd_undefines_h_if_ok) | 如果检测选项通过,则在配置头文件中取消宏定义 | >= 1.0.1 | - -##### 通用接口 (target) - -下面的这些接口,是跟`target`目标域接口通用的,在`option()`和`target()`域范围内都能同时使用,可直接参考上面`target`中的接口描述。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------- | ------------------------------------ | -------- | -| [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_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_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_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 | +| 废弃接口 | 描述 | 支持版本 | +| ----------------------------------------------------- | -------------------------------------------- | ---------------- | +| [add_bindings](#optionadd_bindings) | 添加正向关联选项,同步启用和禁用 | >= 2.0.1 < 2.1.5 | +| [add_rbindings](#optionadd_rbindings) | 添加逆向关联选项,同步启用和禁用 | >= 2.0.1 < 2.1.5 | +| [add_defines_if_ok](#optionadd_defines_if_ok) | 如果检测选项通过,则添加宏定义 | >= 1.0.1 < 2.1.5 | +| [add_defines_h_if_ok](#optionadd_defines_h_if_ok) | 如果检测选项通过,则添加宏定义到配置头文件 | >= 1.0.1 < 2.1.5 | +| [add_undefines_if_ok](#optionadd_undefines_if_ok) | 如果检测选项通过,则取消宏定义 | >= 1.0.1 < 2.1.5 | +| [add_undefines_h_if_ok](#optionadd_undefines_h_if_ok) | 如果检测选项通过,则在配置头文件中取消宏定义 | >= 1.0.1 < 2.1.5 | ##### option @@ -1922,6 +2022,80 @@ $ xmake 这是一个可选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_default ###### 设置选项默认值 @@ -2096,6 +2270,10 @@ $ xmake f --mode=release ###### 添加正向关联选项,同步启用和禁用 +<p class="tip"> +2.1.5版本之后已废弃,请用[add_deps](#optionadd_deps), [on_check](#optionon_check), [after_check](#optionafter_check)等接口代替。 +</p> + 绑定关联选项,例如我想在命令行中配置一个`smallest`的参数:`xmake f --smallest=y` 这个时候,需要同时禁用多个其他的选项开关,来禁止编译多个模块,就是这个需求,相当于一个选项 与其他 多个选项之间 是有联动效应的。 @@ -2114,6 +2292,10 @@ option("smallest") ###### 添加逆向关联选项,同步启用和禁用 +<p class="tip"> +2.1.5版本之后已废弃,请用[add_deps](#optionadd_deps), [on_check](#optionon_check), [after_check](#optionafter_check)等接口代替。 +</p> + 逆向绑定关联选项,被关联选项的开关状态是相反的。 ```lua @@ -2185,6 +2367,8 @@ target("test") 此选项检测是否存在`pthread.h`的头文件,如果检测通过那么`test`目标程序将会加上`ENABLE_PTHREAD`的宏定义。 +如果想要更加灵活的检测,可以通过[lib.detect.has_cincludes](#detect-has_cincludes)在[option.on_check](#optionon_check)中去实现。 + ##### option:add_cxxincludes ###### 添加c++头文件检测 @@ -2209,22 +2393,56 @@ target("test") 此选项检测是否存在`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 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)中去实现。 + ##### option:add_defines_if_ok ###### 如果检测选项通过,则添加宏定义 +<p class="tip"> +2.1.5版本之后已废弃,请用[add_defines](#targetadd_defines)接口代替。 +</p> + 检测选项通过后才会被设置,具体使用见[add_cincludes](#optionadd_cincludes)中的例子。 ##### option:add_defines_h_if_ok ###### 如果检测选项通过,则添加宏定义到配置头文件 +<p class="tip"> +2.1.5版本之后已废弃,请用[add_defines_h](#targetadd_defines_h)接口代替。 +</p> + 跟[add_defines_if_ok](#optionadd_defines_if_ok)类似,只是检测通过后,会在`config.h`头文件中自动加上被设置的宏定义。 例如: @@ -2251,12 +2469,20 @@ target("test") ###### 如果检测选项通过,则取消宏定义 +<p class="tip"> +2.1.5版本之后已废弃,请用[add_undefines](#targetadd_undefines)接口代替。 +</p> + 跟[add_defines_if_ok](#optionadd_defines_if_ok)类似,只是检测通过后,取消被设置的宏定义。 ##### option:add_undefines_h_if_ok ###### 如果检测选项通过,则在配置头文件中取消宏定义 +<p class="tip"> +2.1.5版本之后已废弃,请用[add_undefines_h](#targetadd_undefines_h)接口代替。 +</p> + 跟[add_defines_h_if_ok](#optionadd_defines_h_if_ok)类似,只是检测通过后,会在`config.h`中取消被设置的宏定义。 ```c @@ -2944,6 +3170,8 @@ target("test") end) ``` +所有的内置变量,也可以通过[val](#val)接口,来获取他们的值。 + 这种使用内置变量的方式,使得描述编写更加的简洁易读,下面是一些xmake内置的变量,可以直接获取: | 接口 | 描述 | 支持版本 | @@ -2956,9 +3184,11 @@ target("test") | [$(scriptdir)](#var-scriptdir) | 获取工程描述脚本目录 | >= 2.1.1 | | [$(globaldir)](#var-globaldir) | 获取全局配置目录 | >= 2.0.1 | | [$(configdir)](#var-configdir) | 获取本地工程配置目录 | >= 2.0.1 | +| [$(programdir)](#var-programdir) | xmake安装脚本目录 | >= 2.1.5 | | [$(projectdir)](#var-projectdir) | 获取工程根目录 | >= 2.0.1 | -| [$(packagedir)](#var-packagedir) | 获取依赖包目录 | >= 2.0.1 | | [$(shell)](#var-shell) | 执行外部shell命令 | >= 2.0.1 | +| [$(env)](#var-env) | 获取外部环境变量 | >= 2.1.5 | +| [$(reg)](#var-reg) | 获取windows注册表配置项的值 | >= 2.1.5 | 当然这种变量模式,也是可以扩展的,默认通过`xmake f --var=val`命令,配置的参数都是可以直接获取,例如: @@ -3019,17 +3249,17 @@ xmake的`xmake g|global`全局配置命令,数据存储的目录路径,在� 当前工程的配置存储目录,也就是`xmake f|config`配置命令的存储目录,默认为:`projectdir/.config` -##### var.$(projectdir) +##### var.$(programdir) -###### 工程根目录 +###### xmake安装脚本目录 -也就是`xmake -P xxx`命令中指定的目录路径,默认不指定就是`xmake`命令执行时的当前目录,一般用于定位工程文件。 +也就是`XMAKE_PROGRAM_DIR`环境变量所在目录,我们也可以通过设置这个环境量,来修改xmake的加载脚本,实现版本切换。 -##### var.$(packagedir) +##### var.$(projectdir) -###### 依赖包目录 +###### 工程根目录 -也就是加载依赖包的搜索目录,通常用于获取一些包文件。 +也就是`xmake -P xxx`命令中指定的目录路径,默认不指定就是`xmake`命令执行时的当前目录,一般用于定位工程文件。 ##### var.$(shell) @@ -3051,6 +3281,27 @@ target("test") 但是这个例子可以说明,xmake是完全可以通过原生shell,来与一些第三方的工具进行配合使用。。 +##### var.$(env) + +###### 获取外部环境变量 + +例如,可以通过获取环境变量中的路径: + +```lua +target("test") + add_includedirs("$(env PROGRAMFILES)/OpenSSL/inc") +``` + +##### var.$(reg) + +###### 获取windows注册表配置项的值 + +通过 `regpath; name` 的方式获取注册表中某个项的值: + +```lua +print("$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)") +``` + #### Builtin Modules 在自定义脚本、插件脚本、任务脚本、平台扩展、模板扩展等脚本代码中使用,也就是在类似下面的代码块中,可以使用这些模块接口: @@ -3068,6 +3319,7 @@ end) | 接口 | 描述 | 可使用域 | 支持版本 | | ----------------------------------------------- | -------------------------------------------- | -------------------------- | -------- | +| [val](#val) | 获取内置变量的值 | 脚本域 | >= 2.1.5 | | [import](#import) | 导入扩展摸块 | 脚本域 | >= 2.0.1 | | [inherit](#inherit) | 导入并继承基类模块 | 脚本域 | >= 2.0.1 | | [ifelse](#ifelse) | 类似三元条件判断 | 描述域、脚本域 | >= 2.0.1 | @@ -3079,6 +3331,7 @@ end) | [cprint](#cprint) | 换行彩色打印终端日志 | 脚本域 | >= 2.0.1 | | [cprintf](#cprintf) | 无换行彩色打印终端日志 | 脚本域 | >= 2.0.1 | | [format](#format) | 格式化字符串 | 描述域、脚本域 | >= 2.0.1 | +| [vformat](#vformat) | 格式化字符串,支持内置变量转义 | 脚本域 | >= 2.0.1 | | [raise](#raise) | 抛出异常中断程序 | 脚本域 | >= 2.0.1 | | [os](#os) | 系统操作模块 | 部分只读操作描述域、脚本域 | >= 2.0.1 | | [io](#io) | 文件操作模块 | 脚本域 | >= 2.0.1 | @@ -3116,6 +3369,26 @@ target("test") -- 描述域 ``` +##### val + +###### 获取内置变量的值 + +[内置变量](#内置变量)可以通过此接口直接获取,而不需要再加`$()`的包裹,使用更加简单,例如: + +```lua +print(val("host")) +print(val("env PATH")) +local s = val("shell echo hello") +``` + +而用[vformat](#vformat)就比较繁琐了: + +```lua +local s = vformat("$(shell echo hello)") +``` + +不过`vformat`支持字符串参数格式化,更加强大, 所以应用场景不同。 + ##### import ###### 导入扩展摸块 @@ -3142,7 +3415,7 @@ import的主要用于导入xmake的扩展类库以及一些自定义的类库模 ```lua import("core.base.option") import("core.project") -import("core.project.task") +import("core.base.task") -- 2.1.5 以前是 core.project.task import("core") function main() @@ -3153,7 +3426,7 @@ function main() -- 运行任务和插件 task.run("hello") project.task.run("hello") - core.project.task.run("hello") + core.base.task.run("hello") end ``` @@ -3205,6 +3478,11 @@ import("xxx.xxx", {inherit = true}) 这样导入的不是这个模块的引用,而是导入的这个模块的所有公有接口本身,这样就会跟当前模块的接口进行合并,实现模块间的继承。 +2.1.5版本新增两个新属性:`import("xxx.xxx", {try = true, anonymous = true})` + +try为true,则导入的模块不存在的话,仅仅返回nil,并不会抛异常后中断xmake. +anonymous为true,则导入的模块不会引入当前作用域,仅仅在import接口返回导入的对象引用。 + ##### inherit ###### 导入并继承基类模块 @@ -3594,6 +3872,16 @@ xmake会同时支持这两种写法,内部会去自动智能检测,选择输 local s = format("hello %s", xmake) ``` +##### vformat + +###### 格式化字符串,支持内置变量转义 + +此接口跟[format](#format)接口类似,只是增加对内置变量的获取和转义支持。 + +```lua +local s = vformat("hello %s $(mode) $(arch) $(env PATH)", xmake) +``` + ##### raise ###### 抛出异常中断程序 @@ -3627,14 +3915,19 @@ if (errors) raise(errors) | [os.files](#os-files) | 遍历获取指定目录下的所有文件 | >= 2.0.1 | | [os.filedirs](#os-filedirs) | 遍历获取指定目录下的所有文件或目录 | >= 2.0.1 | | [os.run](#os-run) | 安静运行程序 | >= 2.0.1 | +| [os.runv](#os-runv) | 安静运行程序,带参数列表 | >= 2.1.5 | | [os.exec](#os-exec) | 回显运行程序 | >= 2.0.1 | +| [os.execv](#os-execv) | 回显运行程序,带参数列表 | >= 2.1.5 | | [os.iorun](#os-iorun) | 运行并获取程序输出内容 | >= 2.0.1 | +| [os.iorunv](#os-iorunv) | 运行并获取程序输出内容,带参数列表 | >= 2.1.5 | | [os.getenv](#os-getenv) | 获取环境变量 | >= 2.0.1 | | [os.setenv](#os-setenv) | 设置环境变量 | >= 2.0.1 | | [os.tmpdir](#os-tmpdir) | 获取临时目录路径 | >= 2.0.1 | | [os.tmpfile](#os-tmpfile) | 获取临时文件路径 | >= 2.0.1 | | [os.curdir](#os-curdir) | 获取当前目录路径 | >= 2.0.1 | | [os.scriptdir](#os-scriptdir) | 获取脚本目录路径 | >= 2.0.1 | +| [os.programdir](#os-programdir) | 获取xmake安装主程序脚本目录 | >= 2.1.5 | +| [os.projectdir](#os-projectdir) | 获取工程主目录 | >= 2.1.5 | | [os.arch](#os-arch) | 获取当前系统架构 | >= 2.0.1 | | [os.host](#os-host) | 获取当前主机系统 | >= 2.0.1 | @@ -3837,12 +4130,32 @@ os.run("ls -l $(buildir)") 更加高级的进程运行和控制,见[process](#process)模块接口。 +###### os.runv + +- 安静运行原生shell命令,带参数列表 + +跟[os.run](#os-run)类似,只是传递参数的方式是通过参数列表传递,而不是字符串命令,例如: + +```lua +os.runv("echo", {"hello", "xmake!"}) +``` + ###### os.exec - 回显运行原生shell命令 与[os.run](#os-run)接口类似,唯一的不同是,此接口执行shell程序时,是带回显输出的,一般调试的时候用的比较多 +###### os.execv + +- 回显运行原生shell命令,带参数列表 + +跟[os.execv](#os-execv)类似,只是传递参数的方式是通过参数列表传递,而不是字符串命令,例如: + +```lua +os.execv("echo", {"hello", "xmake!"}) +``` + ###### os.iorun - 安静运行原生shell命令并获取输出内容 @@ -3855,6 +4168,16 @@ os.run("ls -l $(buildir)") local outdata, errdata = os.iorun("echo hello xmake!") ``` +###### os.iorunv + +- 安静运行原生shell命令并获取输出内容,带参数列表 + +跟[os.iorunv](#os-iorunv)类似,只是传递参数的方式是通过参数列表传递,而不是字符串命令,例如: + +```lua +local result, errors = os.iorunv("echo", {"hello", "xmake!"}) +``` + ###### os.getenv - 获取系统环境变量 @@ -3909,6 +4232,18 @@ print("$(tmpdir)/file.txt")) 用法参考:[os.tmpdir](#os-tmpdir)。 +###### os.programdir + +- 获取xmake安装主程序脚本目录 + +跟[$(programdir)](#var-programdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 + +###### os.projectdir + +- 获取工程主目录 + +跟[$(projectdir)](#var-projectdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 + ###### os.arch - 获取当前系统架构 @@ -4501,6 +4836,121 @@ task("hello") end) ``` +##### core.base.global + +用于获取xmake全局的配置信息,也就是`xmake g|global --xxx=val` 传入的参数选项值。 + +| 接口 | 描述 | 支持版本 | +| ----------------------------------------------- | -------------------------------------------- | -------- | +| [global.get](#global-get) | 获取指定配置值 | >= 2.0.1 | +| [global.load](#global-load) | 加载配置 | >= 2.0.1 | +| [global.directory](#global-directory) | 获取全局配置信息目录 | >= 2.0.1 | +| [global.dump](#global-dump) | 打印输出所有全局配置信息 | >= 2.0.1 | + +<p class="tip"> +2.1.5版本之前为`core.project.global`。 +</p> + +###### global.get + +- 获取指定配置值 + +类似[config.get](#config-get),唯一的区别就是这个是从全局配置中获取。 + +###### global.load + +- 加载配置 + +类似[global.get](#global-get),唯一的区别就是这个是从全局配置中加载。 + +###### global.directory + +- 获取全局配置信息目录 + +默认为`~/.config`目录。 + +###### global.dump + +- 打印输出所有全局配置信息 + +输出结果如下: + +```lua +{ + clean = true +, ccache = "ccache" +, xcode_dir = "/Applications/Xcode.app" +} +``` + +##### core.base.task + +用于任务操作,一般用于在自定义脚本中、插件任务中,调用运行其他task任务。 + +| 接口 | 描述 | 支持版本 | +| ----------------------------------------------- | -------------------------------------------- | -------- | +| [task.run](#task-run) | 运行指定任务 | >= 2.0.1 | + +<p class="tip"> +2.1.5版本之前为`core.project.task`。 +</p> + +###### task.run + +- 运行指定任务 + +用于在自定义脚本、插件任务中运行[task](#task)定义的任务或插件,例如: + +```lua +task("hello") + on_run(function () + print("hello xmake!") + end) + +target("demo") + on_clean(function(target) + + -- 导入task模块 + import("core.base.task") + + -- 运行这个hello task + task.run("hello") + end) +``` + +我们还可以在运行任务时,增加参数传递,例如: + +```lua +task("hello") + on_run(function (arg1, arg2) + print("hello xmake: %s %s!", arg1, arg2) + end) + +target("demo") + on_clean(function(target) + + -- 导入task + import("core.base.task") + + -- {} 这个是给第一种选项传参使用,这里置空,这里在最后面传入了两个参数:arg1, arg2 + task.run("hello", {}, "arg1", "arg2") + end) +``` + +对于`task.run`的第二个参数,用于传递命令行菜单中的选项,而不是直接传入`function (arg, ...)`函数入口中,例如: + +```lua +-- 导入task +import("core.base.task") + +-- 插件入口 +function main(...) + + -- 运行内置的xmake配置任务,相当于:xmake f|config --plat=iphoneos --arch=armv7 + task.run("config", {plat="iphoneos", arch="armv7"}) +emd +``` + ##### core.tool.linker 链接器相关操作,常用于插件开发。 @@ -4509,7 +4959,9 @@ task("hello") | ----------------------------------------------- | -------------------------------------------- | -------- | | [linker.link](#linker-link) | 执行链接 | >= 2.0.1 | | [linker.linkcmd](#linker-linkcmd) | 获取链接命令行 | >= 2.0.1 | +| [linker.linkargv](#linker-linkargv) | 获取链接命令行列表 | >= 2.1.5 | | [linker.linkflags](#linker-linkflags) | 获取链接选项 | >= 2.0.1 | +| [linker.has_flags](#linker-has_flags) | 判断指定链接选项是否支持 | >= 2.1.5 | ###### linker.link @@ -4518,7 +4970,7 @@ task("hello") 针对target,链接指定对象文件列表,生成对应的目标文件,例如: ```lua -linker.link({"a.o", "b.o", "c.o"}, target:targetfile(), target) +linker.link({"a.o", "b.o", "c.o"}, target:targetfile(), {target = target}) ``` 其中[target](#target),为工程目标,这里传入,主要用于获取target特定的链接选项,具体如果获取工程目标对象,见:[core.project.project](#core-project-project) @@ -4526,30 +4978,68 @@ linker.link({"a.o", "b.o", "c.o"}, target:targetfile(), target) 当然也可以不指定target,例如: ```lua -linker.link({"a.o", "b.o", "c.o"}, "/tmp/targetfile") +linker.link("binary", "cc", {"a.o", "b.o", "c.o"}, "/tmp/targetfile") ``` ###### linker.linkcmd -- 获取链接命令行 +- 获取链接命令行字符串 直接获取[linker.link](#linker-link)中执行的命令行字符串,相当于: ```lua -os.run(linker.linkcmd({"a.o", "b.o", "c.o"}, target:targetfile(), target)) +local cmdstr = linker.linkcmd("static", "cxx", {"a.o", "b.o", "c.o"}, target:targetfile(), {target = target}) +``` + +注:后面`{target = target}`扩展参数部分是可选的,如果传递了target对象,那么生成的链接命令,会加上这个target配置对应的链接选项。 + +并且还可以自己传递各种配置,例如: + +```lua +local cmdstr = linker.linkcmd("static", "cxx", {"a.o", "b.o", "c.o"}, target:targetfile(), {linkdirs = "/usr/lib"}) +``` + +###### linker.linkargv + +- 获取链接命令行参数列表 + +跟[linker.linkcmd](#linker-linkcmd)稍微有点区别的是,此接口返回的是参数列表,table表示,更加方便操作: + +```lua +local program, argv = linker.linkargv("static", "cxx", {"a.o", "b.o", "c.o"}, target:targetfile(), {target = target}) ``` +其中返回的第一个值是主程序名,后面是参数列表,而`os.args(table.join(program, argv))`等价于`linker.linkcmd`。 + +我们也可以通过传入返回值给[os.runv](#os-runv)来直接运行它:`os.runv(linker.linkargv(..))` + ###### linker.linkflags - 获取链接选项 -获取[linker.linkcmd](#linker-linkcmd)中的链接选项字符串部分,不带shellname和对象文件列表,例如: +获取[linker.linkcmd](#linker-linkcmd)中的链接选项字符串部分,不带shellname和对象文件列表,并且是按数组返回,例如: ```lua -print(linker.linkflags(target)) +local flags = linker.linkflags("shared", "cc", {target = target}) +for _, flag in ipairs(flags) do + print(flag) +end ``` -获取target工程目标中的链接选项:`-L/tmp -lz -ldl ..` +返回的是flags的列表数组。 + +###### linker.has_flags + +- 判断指定链接选项是否支持 + +虽然通过[lib.detect.has_flags](detect-has_flags)也能判断,但是那个接口更加底层,需要指定链接器名称 +而此接口只需要指定target的目标类型,源文件类型,它会自动切换选择当前支持的链接器。 + +```lua +if linker.has_flags(target:targetkind(), target:sourcekinds(), "-L/usr/lib -lpthread") then + -- ok +end +``` ##### core.tool.compiler @@ -4559,8 +5049,11 @@ print(linker.linkflags(target)) | ----------------------------------------------- | -------------------------------------------- | -------- | | [compiler.compile](#compiler-compile) | 执行编译 | >= 2.0.1 | | [compiler.compcmd](#compiler-compcmd) | 获取编译命令行 | >= 2.0.1 | +| [compiler.compargv](#compiler-compargv) | 获取编译命令行列表 | >= 2.1.5 | | [compiler.compflags](#compiler-compflags) | 获取编译选项 | >= 2.0.1 | - +| [compiler.has_flags](#compiler-has_flags) | 判断指定编译选项是否支持 | >= 2.1.5 | +| [compiler.features](#compiler-features) | 获取所有编译器特性 | >= 2.1.5 | +| [compiler.has_features](#compiler-has_features) | 判断指定编译特性是否支持 | >= 2.1.5 | ###### compiler.compile @@ -4569,7 +5062,7 @@ print(linker.linkflags(target)) 针对target,链接指定对象文件列表,生成对应的目标文件,例如: ```lua -compiler.compile("xxx.c", "xxx.o", "xxx.h.d", target) +compiler.compile("xxx.c", "xxx.o", "xxx.h.d", {target = target}) ``` 其中[target](#target),为工程目标,这里传入主要用于获取taeget的特定编译选项,具体如果获取工程目标对象,见:[core.project.project](#core-project-project) @@ -4589,7 +5082,41 @@ compiler.compile("xxx.c", "xxx.o") 直接获取[compiler.compile](#compiler-compile)中执行的命令行字符串,相当于: ```lua -os.run(compiler.compcmd("xxx.c", "xxx.o", incdepfile, target)) +local cmdstr = compiler.compcmd("xxx.c", "xxx.o", {incdepfile = incdepfile, target = target}) +``` + +注:后面`{incdepfile = incdepfile, target = target}`扩展参数部分是可选的,如果传递了target对象,那么生成的编译命令,会加上这个target配置对应的链接选项。 + +如果传递了incdepfile,那么还会生成头文件依赖列表文件`xxx.d` + +并且还可以自己传递各种配置,例如: + +```lua +local cmdstr = compiler.compcmd("xxx.c", "xxx.o", {includedirs = "/usr/include", defines = "DEBUG"}) +``` + +通过target,我们可以导出指定目标的所有源文件编译命令: + +```lua +import("core.project.project") + +for _, target in pairs(project.targets()) do + for sourcekind, sourcebatch in pairs(target:sourcebatches()) do + for index, objectfile in ipairs(sourcebatch.objectfiles) do + local cmdstr = compiler.compcmd(sourcebatch.sourcefiles[index], objectfile, {target = target}) + end + end +end +``` + +###### compiler.compargv + +- 获取编译命令行列表 + +跟[compiler.compargv](#compiler-compargv)稍微有点区别的是,此接口返回的是参数列表,table表示,更加方便操作: + +```lua +local program, argv = compiler.compargv("xxx.c", "xxx.o") ``` ###### compiler.compflags @@ -4599,15 +5126,144 @@ os.run(compiler.compcmd("xxx.c", "xxx.o", incdepfile, target)) 获取[compiler.compcmd](#compiler-compcmd)中的编译选项字符串部分,不带shellname和文件列表,例如: ```lua -print(compiler.compflags(sourcefile, target)) +local flags = compiler.compflags(sourcefile, {target = target}) +for _, flag in ipairs(flags) do + print(flag) +end +``` + +返回的是flags的列表数组。 + +###### compiler.has_flags + +- 判断指定编译选项是否支持 + +虽然通过[lib.detect.has_flags](detect-has_flags)也能判断,但是那个接口更加底层,需要指定编译器名称。 +而此接口只需要指定语言类型,它会自动切换选择当前支持的编译器。 + +```lua +-- 判断c语言编译器是否支持选项: -g +if compiler.has_flags("c", "-g") then + -- ok +end + +-- 判断c++语言编译器是否支持选项: -g +if compiler.has_flags("cxx", "-g") then + -- ok +end ``` -其中第一个返回值是所有编译选项的字符串,第二个返回值是所有选项的数组列表,更加便于操作,例如: +###### compiler.features + +- 获取所有编译器特性 + +虽然通过[lib.detect.features](detect-features)也能获取,但是那个接口更加底层,需要指定编译器名称。 +而此接口只需要指定语言类型,它会自动切换选择当前支持的编译器,然后获取当前的编译器特性列表。 ```lua -local flagstr, flags = compiler.compcmd("xxx.c", "xxx.o") +-- 获取当前c语言编译器的所有特性 +local features = compiler.features("c") + +-- 获取当前c++语言编译器的所有特性,启用c++11标准,否则获取不到新标准的特性 +local features = compiler.features("cxx", {cxxflags = "-std=c++11"}) + +-- 获取当前c++语言编译器的所有特性,传递工程target的所有配置信息 +local features = compiler.features("cxx", {target = target, defines = "..", includedirs = ".."}) +``` + +所有c编译器特性列表: + +| 特性名 | +| --------------------- | +| c_static_assert | +| c_restrict | +| c_variadic_macros | +| c_function_prototypes | + +所有c++编译器特性列表: + +| 特性名 | +| ------------------------------------ | +| cxx_variable_templates | +| cxx_relaxed_constexpr | +| cxx_aggregate_default_initializers | +| cxx_contextual_conversions | +| cxx_attribute_deprecated | +| cxx_decltype_auto | +| cxx_digit_separators | +| cxx_generic_lambdas | +| cxx_lambda_init_captures | +| cxx_binary_literals | +| cxx_return_type_deduction | +| cxx_decltype_incomplete_return_types | +| cxx_reference_qualified_functions | +| cxx_alignof | +| cxx_attributes | +| cxx_inheriting_constructors | +| cxx_thread_local | +| cxx_alias_templates | +| cxx_delegating_constructors | +| cxx_extended_friend_declarations | +| cxx_final | +| cxx_nonstatic_member_init | +| cxx_override | +| cxx_user_literals | +| cxx_constexpr | +| cxx_defaulted_move_initializers | +| cxx_enum_forward_declarations | +| cxx_noexcept | +| cxx_nullptr | +| cxx_range_for | +| cxx_unrestricted_unions | +| cxx_explicit_conversions | +| cxx_lambdas | +| cxx_local_type_template_args | +| cxx_raw_string_literals | +| cxx_auto_type | +| cxx_defaulted_functions | +| cxx_deleted_functions | +| cxx_generalized_initializers | +| cxx_inline_namespaces | +| cxx_sizeof_member | +| cxx_strong_enums | +| cxx_trailing_return_types | +| cxx_unicode_literals | +| cxx_uniform_initialization | +| cxx_variadic_templates | +| cxx_decltype | +| cxx_default_function_template_args | +| cxx_long_long_type | +| cxx_right_angle_brackets | +| cxx_rvalue_references | +| cxx_static_assert | +| cxx_extern_templates | +| cxx_func_identifier | +| cxx_variadic_macros | +| cxx_template_template_parameters | + +###### compiler.has_features + +- 判断指定的编译器特性是否支持 + +虽然通过[lib.detect.has_features](detect-has-features)也能获取,但是那个接口更加底层,需要指定编译器名称。 +而此接口只需要指定需要检测的特姓名称列表,就能自动切换选择当前支持的编译器,然后判断指定特性在当前的编译器中是否支持。 + +```lua +if compiler.has_features("c_static_assert") then + -- ok +end + +if compiler.has_features({"c_static_assert", "cxx_constexpr"}, {languages = "cxx11"}) then + -- ok +end + +if compiler.has_features("cxx_constexpr", {target = target, defines = "..", includedirs = ".."}) then + -- ok +end ``` +具体特性名有哪些,可以参考:[compiler.features](#compiler-features)。 + ##### core.project.config 用于获取工程编译时候的配置信息,也就是`xmake f|config --xxx=val` 传入的参数选项值。 @@ -4731,123 +5387,30 @@ end ##### core.project.global -用于获取xmake全局的配置信息,也就是`xmake g|global --xxx=val` 传入的参数选项值。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [global.get](#global-get) | 获取指定配置值 | >= 2.0.1 | -| [global.load](#global-load) | 加载配置 | >= 2.0.1 | -| [global.directory](#global-directory) | 获取全局配置信息目录 | >= 2.0.1 | -| [global.dump](#global-dump) | 打印输出所有全局配置信息 | >= 2.0.1 | - -###### global.get - -- 获取指定配置值 - -类似[config.get](#config-get),唯一的区别就是这个是从全局配置中获取。 - -###### global.load - -- 加载配置 - -类似[global.get](#global-get),唯一的区别就是这个是从全局配置中加载。 - -###### global.directory - -- 获取全局配置信息目录 - -默认为`~/.config`目录。 - -###### global.dump - -- 打印输出所有全局配置信息 - -输出结果如下: - -```lua -{ - clean = true -, ccache = "ccache" -, xcode_dir = "/Applications/Xcode.app" -} -``` +<p class="tip"> +此模块自2.1.5版本后迁移至[core.base.global](#core-base-global)。 +</p> ##### core.project.task -用于任务操作,一般用于在自定义脚本中、插件任务中,调用运行其他task任务。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [task.run](#task-run) | 运行指定任务 | >= 2.0.1 | - -###### task.run - -- 运行指定任务 - -用于在自定义脚本、插件任务中运行[task](#task)定义的任务或插件,例如: - -```lua -task("hello") - on_run(function () - print("hello xmake!") - end) - -target("demo") - on_clean(function(target) - - -- 导入task模块 - import("core.project.task") - - -- 运行这个hello task - task.run("hello") - end) -``` - -我们还可以在运行任务时,增加参数传递,例如: - -```lua -task("hello") - on_run(function (arg1, arg2) - print("hello xmake: %s %s!", arg1, arg2) - end) - -target("demo") - on_clean(function(target) - - -- 导入task - import("core.project.task") - - -- {} 这个是给第一种选项传参使用,这里置空,这里在最后面传入了两个参数:arg1, arg2 - task.run("hello", {}, "arg1", "arg2") - end) -``` - -对于`task.run`的第二个参数,用于传递命令行菜单中的选项,而不是直接传入`function (arg, ...)`函数入口中,例如: - -```lua --- 导入task -import("core.project.task") - --- 插件入口 -function main(...) - - -- 运行内置的xmake配置任务,相当于:xmake f|config --plat=iphoneos --arch=armv7 - task.run("config", {plat="iphoneos", arch="armv7"}) -emd -``` +<p class="tip"> +此模块自2.1.5版本后迁移至[core.base.task](#core-base-task)。 +</p> ##### core.project.project 用于获取当前工程的一些描述信息,也就是在`xmake.lua`工程描述文件中定义的配置信息,例如:[target](#target)、[option](#option)等。 -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [project.load](#project-load) | 加载工程配置 | >= 2.0.1 | -| [project.directory](#project-directory) | 获取工程目录 | >= 2.0.1 | -| [project.target](#project-target) | 获取指定工程目标对象 | >= 2.0.1 | -| [project.targets](#project-targets) | 获取工程目标对象列表 | >= 2.0.1 | -| [project.name](#project-name) | 获取当前工程名 | >= 2.0.1 | -| [project.version](#project-version) | 获取当前工程版本号 | >= 2.0.1 | +| 接口 | 描述 | 支持版本 | +| ----------------------------------------------- | -------------------------------------------- | -------------------- | +| [project.load](#project-load) | 加载工程配置 | >= 2.0.1 (2.1.5废弃) | +| [project.directory](#project-directory) | 获取工程目录 | >= 2.0.1 | +| [project.target](#project-target) | 获取指定工程目标对象 | >= 2.0.1 | +| [project.targets](#project-targets) | 获取工程目标对象列表 | >= 2.0.1 | +| [project.option](#project-option) | 获取指定的选项对象 | >= 2.1.5 | +| [project.options](#project-options) | 获取工程所有的选项对象 | >= 2.1.5 | +| [project.name](#project-name) | 获取当前工程名 | >= 2.0.1 | +| [project.version](#project-version) | 获取当前工程版本号 | >= 2.0.1 | ###### project.load @@ -4870,12 +5433,20 @@ function main(...) end ``` +<p class="tip"> +2.1.5版本后,不在需要,工程加载会自动在合适时机延迟加载。 +</p> + ###### project.directory - 获取工程目录 获取当前工程目录,也就是`xmake -P xxx`中指定的目录,否则为默认当前`xmake`命令执行目录。 +<p class="tip"> +2.1.5版本后,建议使用[os.projectdir](#os-projectdir)来获取。 +</p> + ###### project.target - 获取指定工程目标对象 @@ -4914,7 +5485,32 @@ end ```lua for targetname, target in pairs(project.targets()) - -- ... + print(target:targetfile()) +end +``` + +###### project.option + +- 获取指定选项对象 + +获取和访问工程中指定的选项对象,例如: + +```lua +local option = project.option("test") +if option:enabled() then + option:enable(false) +end +``` + +###### project.options + +- 获取工程所有选项对象 + +返回当前工程的所有编译目标,例如: + +```lua +for optionname, option in pairs(project.options()) + print(option:enabled()) end ``` @@ -5134,3 +5730,915 @@ environment.leave("toolchains") - 离开指定环境 具体使用见:[environment.enter](#environment-enter) + +##### lib.detect + +此模块提供了非常强大的探测功能,用于探测程序、编译器、语言特性、依赖包等。 + +<p class="tip"> +此模块的接口分散在多个模块目录中,尽量通过导入单个接口来使用,这样效率更高,例如:`import("lib.detect.find_package")`,而不是通过`import("lib.detect")`导入所有来调用。 +</p> + +| 接口 | 描述 | 支持版本 | +| --------------------------------------------------- | -------------------------------------------- | -------------------- | +| [detect.find_file](#detect-find_file) | 查找文件 | >= 2.1.5 | +| [detect.find_path](#detect-find_path) | 查找文件路径 | >= 2.1.5 | +| [detect.find_library](#detect-find_library) | 查找库文件 | >= 2.1.5 | +| [detect.find_program](#detect-find_program) | 查找可执行程序 | >= 2.1.5 | +| [detect.find_programver](#detect-find_programver) | 查找可执行程序版本号 | >= 2.1.5 | +| [detect.find_package](#detect-find_package) | 查找包文件,包含库文件和搜索路径 | >= 2.1.5 | +| [detect.find_tool](#detect-find_tool) | 查找工具 | >= 2.1.5 | +| [detect.find_toolname](#detect-find_toolname) | 查找工具名 | >= 2.1.5 | +| [detect.features](#detect-features) | 获取指定工具的所有特性 | >= 2.1.5 | +| [detect.has_features](#detect-has_features) | 判断指定特性是否支持 | >= 2.1.5 | +| [detect.has_flags](#detect-has_flags) | 判断指定参数选项是否支持 | >= 2.1.5 | +| [detect.has_cfuncs](#detect-has_cfuncs) | 判断指定c函数是否存在 | >= 2.1.5 | +| [detect.has_cxxfuncs](#detect-has_cxxfuncs) | 判断指定c++函数是否存在 | >= 2.1.5 | +| [detect.has_cincludes](#detect-has_cincludes) | 判断指定c头文件是否存在 | >= 2.1.5 | +| [detect.has_cxxincludess](#detect-has_cxxincludes) | 判断指定c++头文件是否存在 | >= 2.1.5 | +| [detect.has_ctypes](#detect-has_ctypes) | 判断指定c类型是否存在 | >= 2.1.5 | +| [detect.has_cxxtypes](#detect-has_cxxtypes) | 判断指定c++类型是否存在 | >= 2.1.5 | +| [detect.check_cxsnippets](#detect-check_cxsnippets) | 检测c/c++代码片段是否能够编译通过 | >= 2.1.5 | + +###### detect.find_file + +- 查找文件 + +这个接口提供了比[os.files](#os-files)更加强大的工程, 可以同时指定多个搜索目录,并且还能对每个目录指定附加的子目录,来模式匹配查找,相当于是[os.files](#os-files)的增强版。 + +例如: + +```lua +import("lib.detect.find_file") +local file = find_file("ccache", { "/usr/bin", "/usr/local/bin"}) +``` + +如果找到,返回的结果是:`/usr/bin/ccache` + +它同时也支持模式匹配路径,进行递归查找,类似`os.files`: + +```lua +local file = find_file("test.h", { "/usr/include", "/usr/local/include/**"}) +``` + +不仅如此,里面的路径也支持内建变量,来从环境变量和注册表中获取路径进行查找: + +```lua +local file = find_file("xxx.h", { "$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)"}) +``` + +如果路径规则比较复杂多变,还可以通过自定义脚本来动态生成路径传入: + +```lua +local file = find_file("xxx.h", { "$(env PATH)", function () return val("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name"):match("\"(.-)\"") end}) +``` + +大部分场合下,上面的使用已经满足各种需求了,如果还需要一些扩展功能,可以通过传入第三个参数,自定义一些可选配置,例如: + +```lua +local file = find_file("test.h", { "/usr", "/usr/local"}, {suffixes = {"/include", "/lib"}}) +``` + +通过指定suffixes子目录列表,可以扩展路径列表(第二个参数),使得实际的搜索目录扩展为: + +``` +/usr/include +/usr/lib +/usr/local/include +/usr/local/lib +``` + +并且不用改变路径列表,就能动态切换子目录来搜索文件。 + +<p class="tip"> +我们也可以通过`xmake lua`插件来快速调用和测试此接口:`xmake lua lib.detect.find_file test.h /usr/local` +</p> + +###### detect.find_path + +- 查找路径 + +这个接口的用法跟[lib.detect.find_file](#detect-find_file)类似,唯一的区别是返回的结果不同。 +此接口查找到传入的文件路径后,返回的是对应的搜索路径,而不是文件路径本身,一般用于查找文件对应的父目录位置。 + +```lua +import("lib.detect.find_path") +local p = find_path("include/test.h", { "/usr", "/usr/local"}) +``` + +上述代码如果查找成功,则返回:`/usr/local`,如果`test.h`在`/usr/local/include/test.h`的话。 + +还有一个区别就是,这个接口传入不只是文件路径,还可以传入目录路径来查找: + +```lua +local p = find_path("lib/xxx", { "$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)"}) +``` + +同样,此接口也支持模式匹配和后缀子目录: + +```lua +local p = find_path("include/*.h", { "/usr", "/usr/local/**"}, {suffixes = "/subdir"}) +``` + +###### detect.find_library + +- 查找库文件 + +此接口用于指定的搜索目录中查找库文件(静态库,动态库),例如: + +```lua +import("lib.detect.find_library") +local library = find_library("crypto", {"/usr/lib", "/usr/local/lib"}) +``` + +在macosx上运行,返回的结果如下: + +```lua +{ + filename = libcrypto.dylib +, linkdir = /usr/lib +, link = crypto +, kind = shared +} +``` + +如果不指定是否需要静态库还是动态库,那么此接口会自动选择一个存在的库(有可能是静态库、也有可能是动态库)进行返回。 + +如果需要强制指定需要查找的库类型,可以指定kind参数为(`static/shared`): + +```lua +local library = find_library("crypto", {"/usr/lib", "/usr/local/lib"}, {kind = "static"}) +``` + +此接口也支持suffixes后缀子目录搜索和模式匹配操作: + +```lua +local library = find_library("cryp*", {"/usr", "/usr/local"}, {suffixes = "/lib"}) +``` + +###### detect.find_program + +- 查找可执行程序 + +这个接口比[lib.detect.find_tool](#detect-find_tool)较为原始底层,通过指定的参数目录来查找可执行程序。 + +```lua +import("lib.detect.find_program") +local program = find_program("ccache") +``` + +上述代码犹如没有传递搜索目录,所以它会尝试直接执行指定程序,如果运行ok,那么直接返回:`ccache`,表示查找成功。 + +指定搜索目录,修改尝试运行的检测命令参数(默认是:`ccache --version`): + +```lua +local program = find_program("ccache", {"/usr/bin", "/usr/local/bin"}, "--help") +``` + +上述代码会尝试运行:`/usr/bin/ccache --help`,如果运行成功,则返回:`/usr/bin/ccache`。 + +如果`--help`也没法满足需求,有些程序没有`--version/--help`参数,那么可以自定义运行脚本,来运行检测: + +```lua +local program = find_program("ccache", {"/usr/bin", "/usr/local/bin"}, function (program) os.run("%s -h", program) end) +``` + +同样,搜索路径列表支持内建变量和自定义脚本: + +```lua +local program = find_program("ccache", {"$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger)"}) +local program = find_program("ccache", {"$(env PATH)", function () return "/usr/local/bin" end}) +``` + +<p class="tip"> +为了加速频发查找的效率,此接口是默认自带cache的,所以就算频繁查找相同的程序,也不会花太多时间。 +如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 +</p> + +我们也可以通过`xmake lua lib.detect.find_program ccache` 来快速测试。 + +###### detect.find_programver + +- 查找可执行程序版本号 + + +```lua +import("lib.detect.find_programver") +local programver = find_programver("ccache") +``` + +返回结果为:3.2.2 + +默认它会通过`ccache --version`尝试获取版本,如果不存在此参数,可以自己指定其他参数: + +```lua +local version = find_programver("ccache", "-v") +``` + +甚至自定义版本获取脚本: + +```lua +local version = find_programver("ccache", function () return os.iorun("ccache --version") end) +``` + +对于版本号的提取规则,如果内置的匹配模式不满足要求,也可以自定义: + +```lua +local version = find_programver("ccache", "--version", "(%d+%.?%d*%.?%d*.-)%s") +local version = find_programver("ccache", "--version", function (output) return output:match("(%d+%.?%d*%.?%d*.-)%s") end) +``` + +<p class="tip"> +为了加速频发查找的效率,此接口是默认自带cache的,如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 +</p> + +我们也可以通过`xmake lua lib.detect.find_programver ccache` 来快速测试。 + +###### detect.find_package + +- 查找包文件 + +此接口也是用于查找库文件,但是比[lib.detect.find_library](#detect-find_library)更加上层,也更为强大和简单易用,因为它是以包为力度进行查找。 + +那怎样算是一个完整的包,它包含: + +1. 多个静态库或者动态库文件 +2. 库的搜索目录 +3. 头文件的搜索目录 +4. 可选的编译链接选项,例如:`defines`等 +5. 可选的版本号 + +例如我们查找一个openssl包: + +```lua +import("lib.detect.find_package") +local package = find_package("openssl") +``` + +返回的结果如下: + +```lua +{links = {"ssl", "crypto", "z"}, linkdirs = {"/usr/local/lib"}, includedirs = {"/usr/local/include"}} +``` + +如果查找成功,则返回一个包含所有包信息的table,如果失败返回nil + +这里的返回结果可以直接作为`target:add`, `option:add`的参数传入,用于动态增加`target/option`的配置: + +```lua +option("zlib") + set_showmenu(true) + before_check(function (option) + import("lib.detect.find_package") + option:add(find_package("zlib")) + end) +``` + +```lua +target("test") + on_load(function (target) + import("lib.detect.find_package") + target:add(find_package("zlib")) + end) +``` + +如果系统上装有`homebrew`, `pkg-config`等第三方工具,那么此接口会尝试使用它们去改进查找结果。 + +我们也可以通过指定版本号,来选择查找指定版本的包(如果这个包获取不到版本信息或者没有匹配版本的包,则返回nil): + +```lua +local package = find_package("openssl", {version = "1.0.1"}) +``` + +默认情况下查找的包是根据如下规则匹配平台,架构和模式的: + +1. 如果参数传入指定了`{plat = "iphoneos", arch = "arm64", mode = "release"}`,则优先匹配,例如:`find_package("openssl", {plat = "iphoneos"})`。 +2. 如果是在当前工程环境,存在配置文件,则优先尝试从`config.get("plat")`, `config.get("arch")`和`config.get("mode")`获取平台架构进行匹配。 +3. 最后从`os.host()`和`os.arch()`中进行匹配,也就是当前主机的平台架构环境。 + +如果系统的库目录以及`pkg-config`都不能满足需求,找不到包,那么可以自己手动设置搜索路径: + +```lua +local package = find_package("openssl", {pathes = {"/usr/lib", "/usr/local/lib", "/usr/local/include"}}) +``` + +也可以同时指定需要搜索的链接名,头文件名: + +```lua +local package = find_package("openssl", {links = {"ssl", "crypto"}, includes = "ssl.h"}}) +``` + +甚至可以指定xmake的`packagedir/*.pkg`包目录,用于查找对应的`openssl.pkg`包,一般用于查找内置在工程目录中的本地包。 + +例如,tbox工程内置了`pkg/openssl.pkg`本地包载项目中,我们可以通过下面的脚本,传入`{packagedirs = ""}`参数优先查找本地包,如果找不到再去找系统包。 + +```lua +target("test") + on_load(function (target) + import("lib.detect.find_package") + target:add(find_package("openssl", {packagedirs = path.join(os.projectdir(), "pkg")})) + end) +``` + +总结下,现在的查找顺序: + +1. 如果指定`{packagedirs = ""}`参数,优先从这个参数指定的路径中查找本地包`*.pkg` +2. 如果在`xmake/modules`下面存在`detect.packages.find_xxx`脚本,那么尝试调用此脚本来改进查找结果 +3. 如果系统存在`pkg-config`,并且查找的是系统环境的库,则尝试使用`pkg-config`提供的路径和链接信息进行查找 +4. 如果系统存在`homebrew`,并且查找的是系统环境的库,则尝试使用`brew --prefix xxx`提供的信息进行查找 +5. 从参数中指定的pathes路径和一些已知的系统路径`/usr/lib`, `/usr/include`中进行查找 + +这里需要着重说下第二点,通过在`detect.packages.find_xxx`脚本来改进查找结果,很多时候自动的包探测是没法完全探测到包路径的, +尤其是针对windows平台,没有默认的库目录,也没有包管理app,很多库装的时候,都是自己所处放置在系统目录,或者添加注册表项。 + +因此查找起来没有同意的规则,这个时候,就可以自定义一个查找脚本,去改进`find_package`的查找机制,对指定包进行更精准的查找。 + +在xmake自带的`xmake/modules/detect/packages`目录下,已经有许多的内置包脚本,来对常用的包进行更好的查找支持。 +当然这不可能满足所有用户的需求,如果用户需要的包还是找不到,那么可以自己定义一个查找脚本,例如: + +查找一个名为`openssl`的包,可以编写一个`find_openssl.lua`的脚本放置在工程目录: + +``` +projectdir + - xmake + - modules + - detect/package/find_openssl.lua +``` + +然后在工程的`xmake.lua`文件的开头指定下这个modules的目录: + +```lua +add_moduledirs("$(projectdir)/xmake/modules") +``` + +这样xmake就能找到自定义的扩展模块了。 + +接下来我们看下`find_openssl.lua`的实现: + +```lua +-- imports +import("lib.detect.find_path") +import("lib.detect.find_library") + +-- find openssl +-- +-- @param opt the package options. e.g. see the options of find_package() +-- +-- @return see the return value of find_package() +-- +function main(opt) + + -- for windows platform + -- + -- http://www.slproweb.com/products/Win32OpenSSL.html + -- + if opt.plat == "windows" then + + -- init bits + local bits = ifelse(opt.arch == "x64", "64", "32") + + -- init search pathes + local pathes = {"$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL %(" .. bits .. "-bit%)_is1;Inno Setup: App Path)", + "$(env PROGRAMFILES)/OpenSSL", + "$(env PROGRAMFILES)/OpenSSL-Win" .. bits, + "C:/OpenSSL", + "C:/OpenSSL-Win" .. bits} + + -- find library + local result = {links = {}, linkdirs = {}, includedirs = {}} + for _, name in ipairs({"libssl", "libcrypto"}) do + local linkinfo = find_library(name, pathes, {suffixes = "lib"}) + if linkinfo then + table.insert(result.links, linkinfo.link) + table.insert(result.linkdirs, linkinfo.linkdir) + end + end + + -- not found? + if #result.links ~= 2 then + return + end + + -- find include + table.insert(result.includedirs, find_path("openssl/ssl.h", pathes, {suffixes = "include"})) + + -- ok + return result + end +end +``` + +里面对windows平台进行注册表读取,去查找指定的库文件,其底层其实也是调用的[find_library](#detect-find_library)等接口。 + +<p class="tip"> +为了加速频发查找的效率,此接口是默认自带cache的,如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 +也可以通过指定force参数,来禁用cache,强制重新查找:`find_package("openssl", {force = true})` +</p> + +我们也可以通过`xmake lua lib.detect.find_package openssl` 来快速测试。 + +###### detect.find_tool + +- 查找工具 + +此接口也是用于查找可执行程序,不过比[lib.detect.find_program](#detect-find_program)更加的高级,功能也更加强大,它对可执行程序进行了封装,提供了工具这个概念: + +* toolname: 工具名,可执行程序的简称,用于标示某个工具,例如:`gcc`, `clang`等 +* program: 可执行程序命令,例如:`xcrun -sdk macosx clang` + +其对应关系如下: + +| toolname | program | +| --------- | ----------------------------------- | +| clang | `xcrun -sdk macosx clang` | +| gcc | `/usr/toolchains/bin/arm-linux-gcc` | +| link | `link.exe -lib` | + +[lib.detect.find_program](#detect-find_program)只能通过传入的原始program命令或路径,去判断该程序是否存在。 +而`find_tool`则可以通过更加一致的toolname去查找工具,并且返回对应的program完整命令路径,例如: + +```lua +import("lib.detect.find_tool") +local tool = find_tool("clang") +``` + +返回的结果为:`{name = "clang", program = "clang"}`,这个时候还看不出区别,我们可以手动指定可执行的命令: + +```lua +local tool = find_tool("clang", {program = "xcrun -sdk macosx clang"}) +``` + +返回的结果为:`{name = "clang", program = "xcrun -sdk macosx clang"}` + +而在macosx下,gcc就是clang,如果我们执行`gcc --version`可以看到就是clang的一个马甲,我们可以通过`find_tool`接口进行智能识别: + +```lua +local tool = find_tool("gcc") +``` + +返回的结果为:`{name = "clang", program = "gcc"}` + +通过这个结果就可以看的区别来了,工具名实际会被标示为clang,但是可执行的命令用的是gcc。 + +我们也可以指定`{version = true}`参数去获取工具的版本,并且指定一个自定义的搜索路径,也支持内建变量和自定义脚本哦: + +```lua +local tool = find_tool("clang", {version = true, {pathes = {"/usr/bin", "/usr/local/bin", "$(env PATH)", function () return "/usr/xxx/bin" end}}) +``` + +返回的结果为:`{name = "clang", program = "/usr/bin/clang", version = "4.0"}` + +这个接口是对`find_program`的上层封装,因此也支持自定义脚本检测: + +```lua +local tool = find_tool("clang", {check = "--help"}) +local tool = find_tool("clang", {check = function (tool) os.run("%s -h", tool) end}) +``` + +最后总结下,`find_tool`的查找流程: + +1. 优先通过`{program = "xxx"}`的参数来尝试运行和检测。 +2. 如果在`xmake/modules/detect/tools`下存在`detect.tools.find_xxx`脚本,则调用此脚本进行更加精准的检测。 +3. 尝试从`/usr/bin`,`/usr/local/bin`等系统目录进行检测。 + +我们也可以在工程`xmake.lua`中`add_moduledirs`指定的模块目录中,添加自定义查找脚本,来改进检测机制: + +``` +projectdir + - xmake/modules + - detect/tools/find_xxx.lua +``` + +例如我们自定义一个`find_7z.lua`的查找脚本: + +```lua +import("lib.detect.find_program") +import("lib.detect.find_programver") + +function main(opt) + + -- init options + opt = opt or {} + + -- find program + local program = find_program(opt.program or "7z", opt.pathes, opt.check or "--help") + + -- find program version + local version = nil + if program and opt and opt.version then + version = find_programver(program, "--help", "(%d+%.?%d*)%s") + end + + -- ok? + return program, version +end +``` + +将它放置到工程的模块目录下后,执行:`xmake l lib.detect.find_tool 7z`就可以查找到了。 + +<p class="tip"> +为了加速频发查找的效率,此接口是默认自带cache的,如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 +</p> + +我们也可以通过`xmake lua lib.detect.find_tool clang` 来快速测试。 + +###### detect.find_toolname + +- 查找工具名 + +通过program命令匹配对应的工具名,例如: + +| program | toolname | +| ------------------------- | ---------- | +| `xcrun -sdk macosx clang` | clang | +| `/usr/bin/arm-linux-gcc` | gcc | +| `link.exe -lib` | link | +| `gcc-5` | gcc | +| `arm-android-clang++` | clangxx | +| `pkg-config` | pkg_config | + +toolname相比program,更能唯一标示某个工具,也方便查找和加载对应的脚本`find_xxx.lua`。 + +###### detect.features + +- 获取指定工具的所有特性 + +此接口跟[compiler.features](#compiler-features)类似,区别就是此接口更加的原始,传入的参数是实际的工具名toolname。 + +并且此接口不仅能够获取编译器的特性,任何工具的特性都可以获取,因此更加通用。 + +```lua +import("lib.detect.features") +local features = features("clang") +local features = features("clang", {flags = "-O0", program = "xcrun -sdk macosx clang"}) +local features = features("clang", {flags = {"-g", "-O0", "-std=c++11"}}) +``` + +通过传入flags,可以改变特性的获取结果,例如一些c++11的特性,默认情况下获取不到,通过启用`-std=c++11`后,就可以获取到了。 + +所有编译器的特性列表,可以见:[compiler.features](#compiler-features)。 + +###### detect.has_features + +- 判断指定特性是否支持 + +此接口跟[compiler.has_features](#compiler-has_features)类似,但是更加原始,传入的参数是实际的工具名toolname。 + +并且此接口不仅能够判断编译器的特性,任何工具的特性都可以判断,因此更加通用。 + +```lua +import("lib.detect.has_features") +local features = has_features("clang", "cxx_constexpr") +local features = has_features("clang", {"cxx_constexpr", "c_static_assert"}, {flags = {"-g", "-O0"}, program = "xcrun -sdk macosx clang"}) +local features = has_features("clang", {"cxx_constexpr", "c_static_assert"}, {flags = "-g"}) +``` + +如果指定的特性列表存在,则返回实际支持的特性子列表,如果都不支持,则返回nil,我们也可以通过指定flags去改变特性的获取规则。 + +所有编译器的特性列表,可以见:[compiler.features](#compiler-features)。 + +###### detect.has_flags + +- 判断指定参数选项是否支持 + +此接口跟[compiler.has_flags](#compiler-has_flags)类似,但是更加原始,传入的参数是实际的工具名toolname。 + +```lua +import("lib.detect.has_flags") +local ok = has_flags("clang", "-g") +local ok = has_flags("clang", {"-g", "-O0"}, {program = "xcrun -sdk macosx clang"}) +local ok = has_flags("clang", "-g -O0", {toolkind = "cxx"}) +``` + +如果检测通过,则返回true。 + +此接口的检测做了一些优化,除了cache机制外,大部分场合下,会去拉取工具的选项列表(`--help`)直接判断,如果选项列表里获取不到的话,才会通过尝试运行的方式来检测。 + +###### detect.has_cfuncs + +- 判断指定c函数是否存在 + +此接口是[lib.detect.check_cxsnippets](#detect-check_cxsnippets)的简化版本,仅用于检测函数。 + +```lua +import("lib.detect.has_cfuncs") +local ok = has_cfuncs("setjmp") +local ok = has_cfuncs({"sigsetjmp((void*)0, 0)", "setjmp"}, {includes = "setjmp.h"}) +``` + +对于函数的描述规则如下: + +| 函数描述 | 说明 | +| ----------------------------------------------- | ------------- | +| `sigsetjmp` | 纯函数名 | +| `sigsetjmp((void*)0, 0)` | 函数调用 | +| `sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}` | 函数名 + {}块 | + +在最后的可选参数中,除了可以指定`includes`外,还可以指定其他的一些参数用于控制编译检测的选项条件: + +```lua +{ verbose = false, target = [target|option], linkdirs = .., links = .., includes = .., defines = .., .. } +``` + +其中verbose用于回显检测信息,target用于在检测前追加target中的配置信息。 + +###### detect.has_cxxfuncs + +- 判断指定c++函数是否存在 + +此接口跟[lib.detect.has_cfuncs](#detect-has_cfuncs)类似,请直接参考它的使用说明,唯一区别是这个接口用于检测c++函数。 + +###### detect.has_cincludes + +- 判断指定c头文件是否存在 + +此接口是[lib.detect.check_cxsnippets](#detect-check_cxsnippets)的简化版本,仅用于检测函数。 + +```lua +import("lib.detect.has_cincludes") +local ok = has_cincludes("stdio.h") +local ok = has_cincludes({"stdio.h", "stdlib.h"}, {target = target}) +local ok = has_cincludes({"stdio.h", "stdlib.h"}, {defines = "_GNU_SOURCE=1", languages = "cxx11"}) +``` + +###### detect.has_cxxincludes + +- 判断指定c++头文件是否存在 + +此接口跟[lib.detect.has_cincludess](#detect-has_cincludes)类似,请直接参考它的使用说明,唯一区别是这个接口用于检测c++头文件。 + +###### detect.has_ctypes + +- 判断指定c类型是否存在 + +此接口是[lib.detect.check_cxsnippets](#detect-check_cxsnippets)的简化版本,仅用于检测函数。 + +```lua +import("lib.detect.has_ctypes") +local ok = has_ctypes("wchar_t") +local ok = has_ctypes({"char", "wchar_t"}, {includes = "stdio.h"}) +local ok = has_ctypes("wchar_t", {includes = {"stdio.h", "stdlib.h"}, "defines = "_GNU_SOURCE=1", languages = "cxx11"}) +``` + +###### detect.has_cxxtypes + +- 判断指定c++类型是否存在 + +此接口跟[lib.detect.has_ctypess](#detect-has_ctypes)类似,请直接参考它的使用说明,唯一区别是这个接口用于检测c++类型。 + +###### detect.check_cxsnippets + +- 检测c/c++代码片段是否能够编译通过 + +通用的c/c++代码片段检测接口,通过传入多个代码片段列表,它会自动生成一个编译文件,然后常识对它进行编译,如果编译通过返回true。 + +对于一些复杂的编译器特性,连[compiler.has_features](#compiler-has_features)都无法检测到的时候,可以通过此接口通过尝试编译来检测它。 + +```lua +import("lib.detect.check_cxsnippets") +local ok = check_cxsnippets("void test() {}") +local ok = check_cxsnippets({"void test(){}", "#define TEST 1"}, {types = "wchar_t", includes = "stdio.h"}) +``` + +此接口是[detect.has_cfuncs](#detect-has_cfuncs), [detect.has_cincludes](#detect-has_cincludes)和[detect.has_ctypes](detect-has_ctypes)等接口的通用版本,也更加底层。 + +因此我们可以用它来检测:types, functions, includes 还有 links,或者是组合起来一起检测。 + +第一个参数为代码片段列表,一般用于一些自定义特性的检测,如果为空,则可以仅仅检测可选参数中条件,例如: + +```lua +local ok = check_cxsnippets({}, {types = {"wchar_t", "char*"}, includes = "stdio.h", funcs = {"sigsetjmp", "sigsetjmp((void*)0, 0)"}}) +``` + +上面那个调用,会去同时检测types, includes和funcs是否都满足,如果通过返回true。 + +还有其他一些可选参数: + +```lua +{ verbose = false, target = [target|option], sourcekind = "[cc|cxx]"} +``` + +其中verbose用于回显检测信息,target用于在检测前追加target中的配置信息, sourcekind 用于指定编译器等工具类型,例如传入`cxx`强制作为c++代码来检测。 + +##### net.http + +此模块提供http的各种操作支持,目前提供的接口如下: + +| 接口 | 描述 | 支持版本 | +| --------------------------------------------------- | -------------------------------------------- | -------------------- | +| [http.download](#http-download) | 下载http文件 | >= 2.1.5 | + +###### http.download + +- 下载http文件 + +这个接口比较简单,就是单纯的下载文件。 + +```lua +import("net.http") + +http.download("http://xmake.io", "/tmp/index.html") +``` + +##### privilege.sudo + +此接口用于通过`sudo`来运行命令,并且提供了平台一致性处理,对于一些需要root权限运行的脚本,可以使用此接口。 + +<p class="warning"> +为了保证安全性,除非必须使用的场合,其他情况下尽量不要使用此接口。 +</p> + +| 接口 | 描述 | 支持版本 | +| --------------------------------------------------- | -------------------------------------------- | -------------------- | +| [sudo.has](#sudo-has) | 判断sudo是否支持 | >= 2.1.5 | +| [sudo.run](#sudo-run) | 安静运行程序 | >= 2.1.5 | +| [sudo.runv](#sudo-runv) | 安静运行程序,带参数列表 | >= 2.1.5 | +| [sudo.exec](#sudo-exec) | 回显运行程序 | >= 2.1.5 | +| [sudo.execv](#sudo-execv) | 回显运行程序,带参数列表 | >= 2.1.5 | +| [sudo.iorun](#sudo-iorun) | 运行并获取程序输出内容 | >= 2.1.5 | +| [sudo.iorunv](#sudo-iorunv) | 运行并获取程序输出内容,带参数列表 | >= 2.1.5 | + +###### sudo.has + +- 判断sudo是否支持 + +目前仅在`macosx/linux`下支持sudo,windows上的管理员权限运行暂时还不支持,因此建议使用前可以通过此接口判断支持情况后,针对性处理。 + +```lua +import("privilege.sudo") + +if sudo.has() then + sudo.run("rm /system/file") +end +``` + +###### sudo.run + +- 安静运行原生shell命令 + +具体用法可参考:[os.run](#os-run)。 + +```lua +import("privilege.sudo") + +sudo.run("rm /system/file") +``` + +###### sudo.runv + +- 安静运行原生shell命令,带参数列表 + +具体用法可参考:[os.runv](#os-runv)。 + +###### sudo.exec + +- 回显运行原生shell命令 + +具体用法可参考:[os.exec](#os-exec)。 + +###### sudo.execv + +- 回显运行原生shell命令,带参数列表 + +具体用法可参考:[os.execv](#os-execv)。 + +###### sudo.iorun + +- 安静运行原生shell命令并获取输出内容 + +具体用法可参考:[os.iorun](#os-iorun)。 + +###### sudo.iorunv + +- 安静运行原生shell命令并获取输出内容,带参数列表 + +具体用法可参考:[os.iorunv](#os-iorunv)。 + +##### devel.git + +此接口提供了git各种命令的访问接口,相对于直接调用git命令,此模块提供了更加上层易用的封装接口,并且提供对git的自动检测和跨平台处理。 + +<p class="tip"> +目前windows上,需要手动安装git包后,才能检测到,后续版本会提供自动集成git功能,用户将不用关心如何安装git,就可以直接使用。 +</p> + +| 接口 | 描述 | 支持版本 | +| --------------------------------------------------- | -------------------------------------------- | -------------------- | +| [git.clone](#git-clone) | clone代码库 | >= 2.1.5 | +| [git.pull](#git-pull) | 拉取代码库最新提交 | >= 2.1.5 | +| [git.clean](#git-clean) | 清理代码库文件 | >= 2.1.5 | +| [git.checkout](#git-checkout) | 签出指定分支版本 | >= 2.1.5 | +| [git.refs](#git-refs) | 获取所有引用列表 | >= 2.1.5 | +| [git.tags](#git-tags) | 获取所有标记列表 | >= 2.1.5 | +| [git.branches](#git-branches) | 获取所有分支列表 | >= 2.1.5 | + +###### git.clone + +- clone代码库 + +此接口对应`git clone`命令 + +```lua +import("devel.git") + +git.clone("[email protected]:tboox/xmake.git") +git.clone("[email protected]:tboox/xmake.git", {depth = 1, branch = "master", outputdir = "/tmp/xmake"}) +``` + +###### git.pull + +- 拉取代码库最新提交 + +此接口对应`git pull`命令 + +```lua +import("devel.git") + +git.pull() +git.pull({remote = "origin", tags = true, branch = "master", repodir = "/tmp/xmake"}) +``` + +###### git.clean + +- 清理代码库文件 + +此接口对应`git clean`命令 + +```lua +import("devel.git") + +git.clean() +git.clean({repodir = "/tmp/xmake", force = true}) +``` + +###### git.checkout + +- 签出指定分支版本 + +此接口对应`git checkout`命令 + +```lua +import("devel.git") + +git.checkout("master", {repodir = "/tmp/xmake"}) +git.checkout("v1.0.1", {repodir = "/tmp/xmake"}) +``` + +###### git.refs + +- 获取所有引用列表 + +此接口对应`git ls-remote --refs`命令 + +```lua +import("devel.git") + +local refs = git.refs(url) +``` + +###### git.tags + +- 获取所有标记列表 + +此接口对应`git ls-remote --tags`命令 + +```lua +import("devel.git") + +local tags = git.tags(url) +``` + +###### git.branches + +- 获取所有分支列表 + +此接口对应`git ls-remote --heads`命令 + +```lua +import("devel.git") + +local branches = git.branches(url) +``` + +##### utils.archive + +此模块用于压缩和解压缩文件。 + +| 接口 | 描述 | 支持版本 | +| --------------------------------------------------- | -------------------------------------------- | -------------------- | +| [archive.extract](#archive-extract) | 解压文件 | >= 2.1.5 | + +###### archive.extract + +- 解压文件 + +支持大部分常用压缩文件的解压,它会自动检测系统提供了哪些解压工具,然后适配到最合适的解压器对指定压缩文件进行解压操作。 + +```lua +import("utils.archive") + +archive.extract("/tmp/a.zip", "/tmp/outputdir") +archive.extract("/tmp/a.7z", "/tmp/outputdir") +archive.extract("/tmp/a.gzip", "/tmp/outputdir") +archive.extract("/tmp/a.tar.bz2", "/tmp/outputdir") +``` diff --git a/docs/zh/manual.md b/docs/zh/manual.md index 23e3e8ff4..7494ace5e 100644 --- a/docs/zh/manual.md +++ b/docs/zh/manual.md @@ -6462,11 +6462,183 @@ http.download("http://xmake.io", "/tmp/index.html") ##### privilege.sudo -此接口用于通过`sudo`来运行命令,并且提供了平台一致性处理。 +此接口用于通过`sudo`来运行命令,并且提供了平台一致性处理,对于一些需要root权限运行的脚本,可以使用此接口。 + +<p class="warning"> +为了保证安全性,除非必须使用的场合,其他情况下尽量不要使用此接口。 +</p> + +| 接口 | 描述 | 支持版本 | +| --------------------------------------------------- | -------------------------------------------- | -------------------- | +| [sudo.has](#sudo-has) | 判断sudo是否支持 | >= 2.1.5 | +| [sudo.run](#sudo-run) | 安静运行程序 | >= 2.1.5 | +| [sudo.runv](#sudo-runv) | 安静运行程序,带参数列表 | >= 2.1.5 | +| [sudo.exec](#sudo-exec) | 回显运行程序 | >= 2.1.5 | +| [sudo.execv](#sudo-execv) | 回显运行程序,带参数列表 | >= 2.1.5 | +| [sudo.iorun](#sudo-iorun) | 运行并获取程序输出内容 | >= 2.1.5 | +| [sudo.iorunv](#sudo-iorunv) | 运行并获取程序输出内容,带参数列表 | >= 2.1.5 | + +###### sudo.has + +- 判断sudo是否支持 + +目前仅在`macosx/linux`下支持sudo,windows上的管理员权限运行暂时还不支持,因此建议使用前可以通过此接口判断支持情况后,针对性处理。 + +```lua +import("privilege.sudo") + +if sudo.has() then + sudo.run("rm /system/file") +end +``` + +###### sudo.run + +- 安静运行原生shell命令 + +具体用法可参考:[os.run](#os-run)。 + +```lua +import("privilege.sudo") + +sudo.run("rm /system/file") +``` + +###### sudo.runv + +- 安静运行原生shell命令,带参数列表 + +具体用法可参考:[os.runv](#os-runv)。 + +###### sudo.exec + +- 回显运行原生shell命令 + +具体用法可参考:[os.exec](#os-exec)。 + +###### sudo.execv + +- 回显运行原生shell命令,带参数列表 + +具体用法可参考:[os.execv](#os-execv)。 + +###### sudo.iorun + +- 安静运行原生shell命令并获取输出内容 + +具体用法可参考:[os.iorun](#os-iorun)。 + +###### sudo.iorunv + +- 安静运行原生shell命令并获取输出内容,带参数列表 + +具体用法可参考:[os.iorunv](#os-iorunv)。 ##### devel.git -此接口提供了git各种命令的访问接口。 +此接口提供了git各种命令的访问接口,相对于直接调用git命令,此模块提供了更加上层易用的封装接口,并且提供对git的自动检测和跨平台处理。 + +<p class="tip"> +目前windows上,需要手动安装git包后,才能检测到,后续版本会提供自动集成git功能,用户将不用关心如何安装git,就可以直接使用。 +</p> + +| 接口 | 描述 | 支持版本 | +| --------------------------------------------------- | -------------------------------------------- | -------------------- | +| [git.clone](#git-clone) | clone代码库 | >= 2.1.5 | +| [git.pull](#git-pull) | 拉取代码库最新提交 | >= 2.1.5 | +| [git.clean](#git-clean) | 清理代码库文件 | >= 2.1.5 | +| [git.checkout](#git-checkout) | 签出指定分支版本 | >= 2.1.5 | +| [git.refs](#git-refs) | 获取所有引用列表 | >= 2.1.5 | +| [git.tags](#git-tags) | 获取所有标记列表 | >= 2.1.5 | +| [git.branches](#git-branches) | 获取所有分支列表 | >= 2.1.5 | + +###### git.clone + +- clone代码库 + +此接口对应`git clone`命令 + +```lua +import("devel.git") + +git.clone("[email protected]:tboox/xmake.git") +git.clone("[email protected]:tboox/xmake.git", {depth = 1, branch = "master", outputdir = "/tmp/xmake"}) +``` + +###### git.pull + +- 拉取代码库最新提交 + +此接口对应`git pull`命令 + +```lua +import("devel.git") + +git.pull() +git.pull({remote = "origin", tags = true, branch = "master", repodir = "/tmp/xmake"}) +``` + +###### git.clean + +- 清理代码库文件 + +此接口对应`git clean`命令 + +```lua +import("devel.git") + +git.clean() +git.clean({repodir = "/tmp/xmake", force = true}) +``` + +###### git.checkout + +- 签出指定分支版本 + +此接口对应`git checkout`命令 + +```lua +import("devel.git") + +git.checkout("master", {repodir = "/tmp/xmake"}) +git.checkout("v1.0.1", {repodir = "/tmp/xmake"}) +``` + +###### git.refs + +- 获取所有引用列表 + +此接口对应`git ls-remote --refs`命令 + +```lua +import("devel.git") + +local refs = git.refs(url) +``` + +###### git.tags + +- 获取所有标记列表 + +此接口对应`git ls-remote --tags`命令 + +```lua +import("devel.git") + +local tags = git.tags(url) +``` + +###### git.branches + +- 获取所有分支列表 + +此接口对应`git ls-remote --heads`命令 + +```lua +import("devel.git") + +local branches = git.branches(url) +``` ##### utils.archive |
