This is a mirror page, please see the original page:

https://xmake.io/#/zh-cn/manual/global_interfaces

全局接口影响整个工程描述,被调用后,后面被包含进来的所有子xmake.lua都会受影响。

接口 描述 支持版本
includes 添加子工程文件和目录 >= 2.1.5
set_modes 设置支持的编译模式 >= 2.1.2
set_project 设置工程名 >= 2.0.1
set_version 设置工程版本 >= 2.0.1
set_xmakever 设置最小xmake版本 >= 2.1.1
add_moduledirs 添加模块目录 >= 2.1.5
add_plugindirs 添加插件目录 >= 2.0.1
add_packagedirs 添加包目录 >= 2.0.1
get_config 获取给的配置值 >= 2.2.2
set_config 设置默认的配置值 >= 2.2.2
add_requires 添加需要的依赖包 >= 2.2.2
add_repositories 添加依赖包仓库 >= 2.2.2

includes

添加子工程文件和目录

我们能够使用此接口添加工程子文件(xmake.lua)或者带有xmake.lua的工程子目录。

projectdir
  - subdirs
    - xmake.lua
  - src

添加子工程目录:

includes("subdirs")

target("test")
    set_kind("binary")
    add_files("src/*.c")

或者添加子工程文件:

includes("subdirs/xmake.lua")

target("test")
    set_kind("binary")
    add_files("src/*.c")

我们也可以通过模式匹配的方式,递归添加多个工程子目录文件:

includes("**/xmake.lua")

target("test")
    set_kind("binary")
    add_files("src/*.c")

另外,此接口在2.2.5之后的版本,提供了一些内置的辅助函数,可以直接includes后使用,具体有哪些内置函数可以看下:https://github.com/xmake-io/xmake/tree/master/xmake/includes

关于这块的更加完整的说明,可以看下:https://github.com/xmake-io/xmake/issues/342

例子:

检测links, c/c++ type, includes和编译器特性,并且写入宏定义到config.h

includes("check_links.lua")
includes("check_ctypes.lua")
includes("check_cfuncs.lua")
includes("check_features.lua")
includes("check_csnippets.lua")
includes("check_cincludes.lua")

target("test")
    set_kind("binary")
    add_files("*.c")
    add_configfiles("config.h.in")

    configvar_check_ctypes("HAS_WCHAR", "wchar_t")
    configvar_check_cincludes("HAS_STRING_H", "string.h")
    configvar_check_cincludes("HAS_STRING_AND_STDIO_H", {"string.h", "stdio.h"})
    configvar_check_ctypes("HAS_WCHAR_AND_FLOAT", {"wchar_t", "float"})
    configvar_check_links("HAS_PTHREAD", {"pthread", "m", "dl"})
    configvar_check_csnippets("HAS_STATIC_ASSERT", "_Static_assert(1, \"\");")
    configvar_check_cfuncs("HAS_SETJMP", "setjmp", {includes = {"signal.h", "setjmp.h"}})
    configvar_check_features("HAS_CONSTEXPR", "cxx_constexpr")
    configvar_check_features("HAS_CONSEXPR_AND_STATIC_ASSERT", {"cxx_constexpr", "c_static_assert"}, {languages = "c++11"})

config.h.in

${define HAS_STRING_H}
${define HAS_STRING_AND_STDIO_H}
${define HAS_WCHAR}
${define HAS_WCHAR_AND_FLOAT}
${define HAS_PTHREAD}
${define HAS_STATIC_ASSERT}
${define HAS_SETJMP}
${define HAS_CONSTEXPR}
${define HAS_CONSEXPR_AND_STATIC_ASSERT}

config.h

/* #undef HAS_STRING_H */
#define HAS_STRING_AND_STDIO_H 1
/* #undef HAS_WCHAR */
/* #undef HAS_WCHAR_AND_FLOAT */
#define HAS_PTHREAD 1
#define HAS_STATIC_ASSERT 1
#define HAS_SETJMP 1
/* #undef HAS_CONSTEXPR */
#define HAS_CONSEXPR_AND_STATIC_ASSERT 1

set_modes

设置支持的编译模式

这个是可选接口,一般情况下不需要设置,目前仅用于对工程增加更加细致的描述信息,方便vs工程的多模式生成,以及其他xmake插件中获取模式信息。

例如:

set_modes("debug", "release")

如果设置了这个,xmake就知道当前工程支持哪些编译模式,这样生成vs工程文件的时候,只需要:

$ xmake project -k vs2017

不再需要额外手动指定需要的编译模式了,此外其他一些想要获取工程信息的插件,也许也会需要这些设置信息。


当然,对于is_mode接口,set_modes不是必须的,就算不设置,也是可以通过is_mode正常判断当前的编译模式。

set_project

设置工程名

设置工程名,在doxygen自动文档生成插件、工程文件生成插件中会用到,一般设置在xmake.lua的最开头,当然放在其他地方也是可以的

-- 设置工程名
set_project("tbox")

-- 设置工程版本
set_version("1.5.1")

set_version

设置工程版本

设置项目版本,可以放在xmake.lua任何地方,一般放在最开头,例如:

set_version("1.5.1")

2.1.7版本支持buildversion的配置:

set_version("1.5.1", {build = "%Y%m%d%H%M"})

我们也能够添加版本宏定义到头文件,请参考:add_configfiles

set_xmakever

设置最小xmake版本

用于处理xmake版本兼容性问题,如果项目的xmake.lua,通过这个接口设置了最小xmake版本支持,那么用户环境装的xmake低于要求的版本,就会提示错误。

一般情况下,建议默认对其进行设置,这样对用户比较友好,如果xmake.lua中用到了高版本的api接口,用户那边至少可以知道是否因为版本不对导致的构建失败。

设置如下:

-- 设置最小版本为:2.1.0,低于此版本的xmake编译此工程将会提示版本错误信息
set_xmakever("2.1.0")

add_moduledirs

添加模块目录

xmake内置的扩展模块都在xmake/modules目录下,可通过import来导入他们,如果自己在工程里面实现了一些扩展模块,
可以放置在这个接口指定的目录下,import也就会能找到,并且优先进行导入。

例如定义一个find_openssl.lua的扩展模块,用于扩展内置的lib.detect.find_package接口,则只需要将它放置在:

projectdir/xmake/modules/detect/packages/find_openssl.lua

然后在工程xmake.lua下指定这个模块目录,find_package就可以自动找到了:

add_moduledirs("projectdir/xmake/modules")

add_plugindirs

添加插件目录

xmake内置的插件都是放在xmake/plugins目录下,但是对于用户自定义的一些特定工程的插件,如果不想放置在xmake安装目录下,那么可以在xmake.lua中进行配置指定的其他插件路径。

-- 将当前工程下的plugins目录设置为自定义插件目录
add_plugindirs("$(projectdir)/plugins")

这样,xmake在编译此工程的时候,也就加载这些插件。

add_packagedirs

添加包目录

通过设置依赖包目录,可以方便的集成一些第三方的依赖库,以tbox工程为例,其依赖包如下:

- base.pkg
- zlib.pkg
- polarssl.pkg
- openssl.pkg
- mysql.pkg
- pcre.pkg
- ...

如果要让当前工程识别加载这些包,首先要指定包目录路径,例如:

add_packagedirs("packages")

指定好后,就可以在target作用域中,通过add_packages接口,来添加集成包依赖了,例如:

target("tbox")
    add_packages("zlib", "polarssl", "pcre", "mysql")

get_config

获取给定的配置值

此接口从2.2.2版本开始引入,用于快速获取给定的配置值,可用于描述域。

if get_config("myconfig") == "xxx" then
    add_defines("HELLO")
end

set_config

设置给定的默认配置值

此接口从2.2.2版本开始引入,用于快速在xmake.lua中设置一个默认配置值,仅用于描述域。

之前很多配置,包括编译工具链,构建目录等只能通过$ xmake f --name=value的方式来配置,如果我们想写死在xmake.lua提供一个默认值,就可以通过下面的方式来配置:

set_config("name", "value")
set_config("buildir", "other/buildir")
set_config("cc", "gcc")
set_config("ld", "g++")

不过,我们还是可以通过$ xmake f --name=value的方式,去修改xmake.lua中的默认配置。

add_requires

添加需要的依赖包

xmake的依赖包管理是完全支持语义版本选择的,例如:"~1.6.1",对于语义版本的具体描述见:https://semver.org/

一些语义版本写法:

add_requires("tbox 1.6.*", "pcre 1.3.x", "libpng ^1.18")
add_requires("libpng ~1.16", "zlib 1.1.2 || >=1.2.11 <1.3.0")

目前xmake使用的语义版本解析器是uael贡献的sv库,里面也有对版本描述写法的详细说明,可以参考下:版本描述说明

当然,如果我们对当前的依赖包的版本没有特殊要求,那么可以直接这么写:

add_requires("tbox", "libpng", "zlib")

这会使用已知的最新版本包,或者是master分支的源码编译的包,如果当前包有git repo地址,我们也能指定特定分支版本:

add_requires("tbox master")
add_requires("tbox dev")

如果指定的依赖包当前平台不支持,或者编译安装失败了,那么xmake会编译报错,这对于有些必须要依赖某些包才能工作的项目,这是合理的。
但是如果有些包是可选的依赖,即使没有也可以正常编译使用的话,可以设置为可选包:

add_requires("tbox", {optional = true})

默认的设置,xmake会去优先检测系统库是否存在(如果没设置版本要求),如果用户完全不想使用系统库以及第三方包管理提供的库,那么可以设置:

add_requires("tbox", {system = false})

如果我们想同时源码调试依赖包,那么可以设置为使用debug版本的包(当然前提是这个包支持debug编译):

add_requires("tbox", {debug = true})

如果当前包还不支持debug编译,可在仓库中提交修改编译规则,对debug进行支持,例如:

package("openssl")
    on_install("linux", "macosx", function (package)
        os.vrun("./config %s --prefix=\"%s\"", package:debug() and "--debug" or "", package:installdir())
        os.vrun("make -j4")
        os.vrun("make install")
    end)

某些包在编译时候有各种编译选项,我们也可以传递进来,当然包本身得支持:

add_requires("tbox", {config = {small=true}})

传递--small=true给tbox包,使得编译安装的tbox包是启用此选项的。

v2.2.3之后,可以通过optionhas_config配合,在自己定义配置选项参数中控制是否需要添加某个依赖包:

option("luajit")
    set_default(false)
    set_showmenu(true)
    set_category("option")
    set_description("Enable the luajit runtime engine.")
option_end()

if has_config("luajit") then
    add_requires("luajit")
else
    add_requires("lua")
end

我们可以通过$xmake f --luajit=y去切换依赖包。

并且我们也新增了group参数,来分组依赖包,同一个组下的所有依赖包,只能有一个生效启用,启用顺序依赖add_requires添加的顺序:

add_requires("openssl", {group = "ssl", optional = true})
add_requires("mbedtls", {group = "ssl", optional = true})

target("test")
    add_packages("openssl", "mbedtls")

例如上面,所以同时依赖两个ssl包,实际上只会启用生效实际安装成功的那一个ssl包,并不会同时链接两个依赖包。

2.2.5版本之后,xmake支持对对第三方包管理器里面的依赖库安装支持,例如:conan,brew, vcpkg等

添加homebrew的依赖包:

add_requires("brew::zlib", {alias = "zlib"}})
add_requires("brew::pcre2/libpcre2-8", {alias = "pcre2"}})

target("test")
    set_kind("binary")
    add_files("src/*.c") 
    add_packages("pcre2", "zlib")

添加vcpkg的依赖包:

add_requires("vcpkg::zlib", "vcpkg::pcre2")

target("test")
    set_kind("binary")
    add_files("src/*.c") 
    add_packages("vcpkg::zlib", "vcpkg::pcre2")

添加conan的依赖包:

add_requires("CONAN::zlib/1.2.11@conan/stable", {alias = "zlib", debug = true})
add_requires("CONAN::OpenSSL/1.0.2n@conan/stable", {alias = "openssl", 
    configs = {options = "OpenSSL:shared=True"}})

target("test")
    set_kind("binary")
    add_files("src/*.c") 
    add_packages("openssl", "zlib")

执行xmake进行编译后:

ruki:test_package ruki$ xmake
checking for the architecture ... x86_64
checking for the Xcode directory ... /Applications/Xcode.app
checking for the SDK version of Xcode ... 10.14
note: try installing these packages (pass -y to skip confirm)?
  -> CONAN::zlib/1.2.11@conan/stable  (debug)
  -> CONAN::OpenSSL/1.0.2n@conan/stable  
please input: y (y/n)

  => installing CONAN::zlib/1.2.11@conan/stable .. ok
  => installing CONAN::OpenSSL/1.0.2n@conan/stable .. ok

[  0%]: ccache compiling.release src/main.c
[100%]: linking.release test

关于这块的更多详情见:https://github.com/xmake-io/xmake/issues/339

添加clib的依赖包:

clib是一款基于源码的依赖包管理器,拉取的依赖包是直接下载对应的库源码,集成到项目中编译,而不是二进制库依赖。

其在xmake中集成也很方便,唯一需要注意的是,还需要自己添加上对应库的源码到xmake.lua,例如:

add_requires("clib::clibs/bytes@0.0.4", {alias = "bytes"})

target("xmake-test")
    set_kind("binary")
    add_files("clib/bytes/*.c")
    add_files("src/*.c") 
    add_packages("bytes")

add_repositories

添加依赖包仓库

如果需要的包不在官方仓库xmake-repo中,我们可以提交贡献代码到仓库进行支持。
但如果有些包仅用于个人或者私有项目,我们可以建立一个私有仓库repo,仓库组织结构可参考:xmake-repo

比如,现在我们有一个一个私有仓库repo:`git@github.com:myrepo/xmake-repo.git`

我们可以通过此接口来添加:

add_repositories("my-repo git@github.com:myrepo/xmake-repo.git")

如果我们只是想添加一两个私有包,这个时候特定去建立一个git repo太小题大做了,我们可以直接把包仓库放置项目里面,例如:

projectdir
  - myrepo
    - packages
      - t/tbox/xmake.lua
      - z/zlib/xmake.lua
  - src
    - main.c
  - xmake.lua

上面myrepo目录就是自己的私有包仓库,内置在自己的项目里面,然后在xmake.lua里面添加一下这个仓库位置:

add_repositories("my-repo myrepo")

这个可以参考benchbox项目,里面就内置了一个私有仓库。