# 条件判断 条件判断的 API,一般用于必须要处理特定平台的编译逻辑的场合,他们通常跟 lua 的 if 语句配合使用。 ## is_os ### 判断当前构建目标的操作系统 #### 函数原型 ::: tip API ```lua is_os(os: , ...) ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | os | 操作系统名称字符串 | | ... | 可变参数,可传递多个操作系统名称 | #### 用法说明 ```lua -- 如果当前操作系统是ios if is_os("ios") then add_files("src/xxx/*.m") end ``` 目前支持的操作系统有: * windows * linux * android * macosx * ios ## is_arch ### 判断当前编译架构 #### 函数原型 ::: tip API ```lua is_arch(arch: , ...) ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | arch | 架构名称字符串 | | ... | 可变参数,可传递多个架构名称 | #### 用法说明 用于检测编译配置:`xmake f -a armv7` ```lua -- 如果当前架构是x86_64或者i386 if is_arch("x86_64", "i386") then add_files("src/xxx/*.c") end -- 如果当前平台是armv7, arm64, armv7s, armv7-a if is_arch("armv7", "arm64", "armv7s", "armv7-a") then -- ... end ``` 如果像上面那样一个个去判断所有arm架构,也许会很繁琐,毕竟每个平台的架构类型很多,xmake提供了比[add_files](#targetadd_files)更强的lua正则表达式匹配模式,来更加简洁的进行判断: ```lua --如果当前平台是arm平台 if is_arch("arm.*") then -- ... end ``` 用`.*`就可以匹配所有了。 ## is_plat ### 判断当前编译平台 #### 函数原型 ::: tip API ```lua is_plat(plat: , ...) ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | plat | 平台名称字符串 | | ... | 可变参数,可传递多个平台名称 | #### 用法说明 用于检测编译配置:`xmake f -p iphoneos` ```lua -- 如果当前平台是android if is_plat("android") then add_files("src/xxx/*.c") end -- 如果当前平台是macosx或者iphoneos if is_plat("macosx", "iphoneos") then add_frameworks("Foundation") end ``` 目前支持的平台有: * windows * cross * linux * macosx * android * iphoneos * watchos 当然你也可以自己扩展添加自己的平台,甚至直接指定自己的平台名: ```sh $ xmake f -p other --sdk=... ``` 如果指定的平台名不存在,就会自动切到`cross`平台进行交叉编译,但是却可以通过`is_plat("other")`来判断自己的平台逻辑。 ## is_host ### 判断当前主机环境的操作系统 #### 函数原型 ::: tip API ```lua is_host(host: , ...) ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | host | 主机系统名称字符串 | | ... | 可变参数,可传递多个主机名称 | #### 用法说明 有些编译平台是可以在多个不同的操作系统进行构建的,例如:android的ndk就支持linux,macOS还有windows环境。 这个时候就可以通过这个接口,区分当前是在哪个系统环境下进行的构建。 ```lua -- 如果当前主机环境是windows if is_host("windows") then add_includedirs("C:\\includes") else add_includedirs("/usr/includess") end ``` 目前支持的主机环境有: * windows * linux * macosx 你也可以通过[$(host)](/zh/api/description/builtin-variables#var-host)内置变量或者[os.host](/zh/api/scripts/builtin-modules/os#os-host)接口,来进行获取 ## is_subhost ### 判断当前主机的子系统环境 #### 函数原型 ::: tip API ```lua is_subhost(subhost: , ...) ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | subhost | 子系统名称字符串 | | ... | 可变参数,可传递多个子系统名称 | #### 用法说明 目前主要用于 windows 系统上 cygwin, msys2 等子系统环境的探测,如果在 msys2 shell 环境下运行 xmake,那么 `is_subhost("windows")` 想将会返回 false,而 `is_host("windows")` 依旧会返回 true。 目前支持的子系统: * msys * cygwin 配置例子: ```lua if is_subhost("msys", "cygwin") then -- 当前在 msys2/cygwin 的 shell 环境下 end ``` 我们也可以通过执行 `xmake l os.subhost` 来快速查看当前的子系统平台。 ::: tip 提示 后期也有可能会支持 linux 和 macos 系统下的其他子系统环境,如果存在话。 ::: ## is_subarch ### 判断当前主机子系统环境下的架构 #### 函数原型 ::: tip API ```lua is_subarch(subarch: , ...) ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | subarch | 子系统架构名称字符串 | | ... | 可变参数,可传递多个子系统架构名称 | #### 用法说明 目前主要用于 windows 系统上 cygwin, msys2 等子系统环境下架构的探测,通常在 windows 编译平台采用 msvc 工具链,那边编译架构时 x64,x86。 而在 msys/cygwin 子系统环境下,编译架构默认为 x86_64/i386,是有差异的。 我们也可以通过执行 `xmake l os.subarch` 来快速查看当前的子系统架构。 ## is_cross ### 判断当前平台是否为交叉编译 #### 函数原型 ::: tip API ```lua is_cross() ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | - | 无参数 | #### 用法说明 如果当前的目标架构和平台,不是当前的主机平台,属于交叉编译,这个接口就会返回 true。 ## is_mode ### 判断当前编译模式 #### 函数原型 ::: tip API ```lua is_mode(mode: , ...) ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | mode | 编译模式名称字符串 | | ... | 可变参数,可传递多个模式名称 | #### 用法说明 用于检测编译配置:`xmake f -m debug` 编译模式的类型并不是内置的,可以自由指定,一般指定:`debug`, `release`, `profile` 这些就够用了,当然你也可以在xmake.lua使用其他模式名来判断。 ```lua -- 如果当前编译模式是debug if is_mode("debug") then add_defines("DEBUG") set_symbols("debug") set_optimize("none") end -- 如果是release模式 if is_mode("release") then set_symbols("hidden") set_strip("all") end ``` ## is_kind ### 判断当前编译类型 #### 函数原型 ::: tip API ```lua is_kind(kind: , ...) ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | kind | 目标类型名称字符串 | | ... | 可变参数,可传递多个类型名称 | #### 用法说明 判断当前是否编译的是动态库还是静态库,用于检测编译配置:`xmake f -k [static|shared]` 一般用于如下场景: ```lua target("test") -- 通过配置设置目标的kind set_kind("$(kind)") add_files("src/*c") -- 如果当前编译的是静态库,那么添加指定文件 if is_kind("static") then add_files("src/xxx.c") end ``` 编译配置的时候,可手动切换,编译类型: ```sh # 编译静态库 $ xmake f -k static $ xmake ``` ```sh # 编译动态库 $ xmake f -k shared $ xmake ``` ## is_config ### 判断指定配置是否为给定的值 #### 函数原型 ::: tip API ```lua is_config(name: , values: , ...) ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | name | 配置选项名称字符串 | | values | 配置值字符串 | | ... | 可变参数,可传递多个值 | #### 用法说明 此接口从2.2.2版本开始引入,用于判断指定配置是否为给定的值,可用于描述域。 例如: ```sh $ xmake f --test=hello1 ``` ```lua -- 自定义一个配置选项到命令行菜单 option("test") set_showmenu(true) set_description("The test config option") option_end() -- 如果自定义的test配置值是hello1或者hello2 if is_config("test", "hello1", "hello2") then add_defines("HELLO") end ``` 可以用来根据配置值增加对应的依赖包,例如: ```lua -- 根据lua_flavor的配置值,选择依赖lua还是luajit option("lua_flavor") set_showmenu(true) set_values("luajit", "lua") option_end() if is_config("lua_flavor", "luajit") then add_requires("luajit") elseif is_config("lua_flavor", "lua") then add_requires("lua") end ``` 不仅如此,我们还可以设置模式匹配规则去判断值,例如: ```lua -- 如果自定义的test配置值带有hello前缀 if is_config("test", "hello.*") then add_defines("HELLO") end ``` ::: tip 提示 此接口不仅能够判断通过[option](/zh/api/description/configuration-option#option)定义的自定义配置选项,同时还能判断内置的全局配置、本地配置。 ::: ## has_config ### 判断配置是否启用或者存在 #### 函数原型 ::: tip API ```lua has_config(configs: , ...) ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | configs | 配置名称字符串 | | ... | 可变参数,可传递多个配置名称 | #### 用法说明 此接口从2.2.2版本开始引入,用于检测自定义或者内置的编译配置是否存在或启用,可用于描述域。 例如以下配置情况,都会返回true: ```sh # 启用某个配置选项(如果是boolean类型配置) $ xmake f --test1=y $ xmake f --test1=yes $ xmake f --test1=true # 设置某个配置选项的值 $ xmake f --test2=value ``` ```lua -- 如果test1或者test2被设置或者启用 if has_config("test1", "test2") then add_defines("TEST") end ``` 而下面的情况则会禁用配置,返回false: ```sh # 禁用配置(如果是boolean类型配置) $ xmake f --test1=n $ xmake f --test1=no $ xmake f --test1=false ``` ::: tip 提示 此接口不仅能够判断内置的全局配置、本地配置,同时还可以判断通过[option](/zh/api/description/configuration-option#option)定义的自定义配置选项。 此接口与[get_config](/zh/api/description/global-interfaces#get-config)接口配合使用,可以完整地获取和判断用户通过`xmake f --option1=xxx`设置的选项状态。 ::: ## has_package ### 判断依赖包是否启用或者存在 #### 函数原型 ::: tip API ```lua has_package(packages: , ...) ``` ::: #### 参数说明 | 参数 | 描述 | |------|------| | packages | 包名称字符串 | | ... | 可变参数,可传递多个包名称 | #### 用法说明 此接口从2.2.3版本开始引入,用于检测远程依赖包是否存在或启用,可用于描述域。 一般配合[add_requires](/zh/api/description/global-interfaces#add-requires)一起使用,例如: ```lua add_requires("tbox", {optional = true}) target("test") set_kind("binary") add_files("src/*.c") add_packages("tbox") if has_package("tbox") then add_defines("HAVE_TBOX") end ``` 如果通过`add_requires`添加的可选依赖包,远程下载安装失败,或者当前平台不支持导致实际上没有被正常安装上,那么`has_package`就会返回false, 表示不存在,然后对其他flags定义甚至源文件编译控制做一些特殊处理。 ::: tip 注意 此接口跟[has_config](#has_config)的区别在于,[has_config](#has_config)用于[option](/zh/api/description/configuration-option#option),而它用于[add_requires](/zh/api/description/global-interfaces#add-requires)。 :::