前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >xmake v2.5.1 发布, 支持 Apple Silicon 并改进 C/C++ 包依赖管理

xmake v2.5.1 发布, 支持 Apple Silicon 并改进 C/C++ 包依赖管理

作者头像
ruki
发布2021-02-19 10:47:12
9050
发布2021-02-19 10:47:12
举报

xmake 是一个基于 Lua 的轻量级跨平台构建工具,使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。

这是 xmake 在今年的首个版本,也是完全适配支持 Apple Silicon (macOS ARM) 设备的首个版本。

这个版本,我们主要改进了对 C/C++ 依赖包的集成支持,更加的稳定,并且能够更加灵活的实现定制化配置编译。

另外,我们还重点改进 vs/vsxmake 两个vs工程生成器插件,修复了很多细节问题,并且对子工程分组也做了支持,现在可以生成类似下图的工程结构。

关于 Zig 方面,0.7.1 版本修复了很多我之前反馈的问题,现在 xmake 也已经可以很好的支持对 zig 项目的编译。

同时,我们还新开发了一个 luarocks=build-xmake 插件去用 xmake 替换 luarocks 内置的构建系统。

最后,在这个版本中,我们继续改进了 xmake f --menu 图形化配置菜单,完全支持鼠标操作和滚动支持,也对 utf8 做了支持。

  • 项目源码
  • 官方文档
  • 入门课程

新特性介绍

新增 add_requireconfs 改进包配置

尽管之前的版本,我们可以通过 add_requires("libpng", {configs = {shared = true}}) 的方式来定义和配置依赖包。

但是,如果用户项目的工程庞大,依赖包非常多,且每个包都需要不同的编译配置参数,那么配置起来还是会非常繁琐,并且具有局限性,比如无法改写内部的子依赖包配置。

因此,我们新增了 add_requireconfs 去更灵活方便的配置每个包的配置以及它的子依赖,下面我们重点介绍几种用法:

扩充指定包的配置

这是基本用法,比如我们已经通过 add_requires("zlib") 声明了一个包,想要在后面对这个 zlib 的配置进行扩展,改成动态库编译,可以通过下面的方式配置。

add_requires("zlib")
add_requireconfs("zlib", {configs = {shared = true}})

它等价于

add_requires("zlib", {configs = {shared = true}})
设置通用的默认配置

上面的用法,我们还看不出有什么实际用处,但如果依赖多了就能看出效果了,比如下面这样:

add_requires("zlib", {configs = {shared = true}})
add_requires("pcre", {configs = {shared = true}})
add_requires("libpng", {configs = {shared = true}})
add_requires("libwebp", {configs = {shared = true}})
add_requires("libcurl", {configs = {shared = false}})

是不是非常繁琐,如果我们用上 add_requireconfs 来设置默认配置,就可以极大的简化成下面的配置:

add_requireconfs("*", {configs = {shared = true}})
add_requires("zlib")
add_requires("pcre")
add_requires("libpng")
add_requires("libwebp")
add_requires("libcurl", {configs = {shared = false}})

上面的配置,我们通过 add_requireconfs("*", {configs = {shared = true}}) 使用模式匹配的方式,设置所有的依赖包默认走动态库编译安装。

但是,我们又通过 add_requires("libcurl", {configs = {shared = false}}) 将 libcurl 进行了特殊配置,强制走静态库编译安装。

最终的配置结果为:zlib/pcre/libpng/libwebp 是 shared 库,libcurl 是静态库。

我们通过模式匹配的方式,可以将一些每个包的常用配置都放置到统一的 add_requireconfs 中去预先配置好,极大简化每个 add_requires 的定义。

!> 默认情况下,对于相同的配置,xmake 会优先使用 add_requires 中的配置,而不是 add_requireconfs。

如果 add_requires("zlib 1.2.11") 中设置了版本,就会优先使用 add_requires 的配置,完全忽略 add_requireconfs 里面的版本配置,当然我们也可以通过 override 来完全重写 add_requires 中指定的版本。

add_requires("zlib 1.2.11")
add_requireconfs("zlib", {override = true, version = "1.2.10"})
改写包依赖配置

其实 add_requireconfs 最大的用处是可以让用户改写安装包的特定依赖包的配置。

什么意思呢,比如我们项目中集成使用 libpng 这个包,并且使用了动态库版本,但是 libpng 内部依赖的 zlib 库其实还是静态库版本。

add_requires("libpng", {configs = {shared = true}})

那如果我们想让 libpng 依赖的 zlib 包也改成动态库编译,应该怎么配置呢?这就需要 add_requireconfs 了。

add_requires("libpng", {configs = {shared = true}})
add_requireconfs("libpng.zlib", {configs = {shared = true}})

通过 libpng.zlib 依赖路径的写法,指定内部某个依赖,改写内部依赖配置。

如果依赖路径很深,比如 foo -> bar -> xyz 的依赖链,我们可以写成:foo.bar.xyz

我们也可以改写 libpng 依赖的内部 zlib 库版本:

add_requires("libpng")
add_requireconfs("libpng.zlib", {version = "1.2.10"})
级联依赖的模式匹配

如果一个包的依赖非常多,且依赖层次也很深,怎么办呢,比如 libwebp 这个包,它的依赖有:

libwebp
  - libpng
    - zlib
    - cmake
  - libjpeg
  - libtiff
    - zlib
  - giflib
  - cmake

如果我想改写 libwebp 里面的所有的依赖库都加上特定配置,那么挨个配置,就会非常繁琐,这个时候就需要 add_requireconfs() 的递归依赖模式匹配来支持了。

add_requires("libwebp")
add_requireconfs("libwebp.**|cmake", {configs = {cxflags = "-DTEST"}})

上面的配置,我们将 libwebp 中所以的库依赖就额外加上了 -DTEST 来编译,但是 cmake 依赖属于构建工具依赖,我们可以通过 |xxx 的方式排除它。

这里的模式匹配写法,与 add_files() 非常类似。

我们在给几个例子,比如这回我们只改写 libwebp 下单级的依赖配置,启用调试库:

add_requires("libwebp")
add_requireconfs("libwebp.*|cmake", {debug = true})

图形化配置支持鼠标和滚动操作

我们升级了 xmake 所使用的 tui 组件库:LTUI,增加了对鼠标的支持,以及部分组件的滚动支持,我们可以再图形化配置中,更加灵活方便的配置编译选项。

stdin 重定向输入支持

之前的版本中,xmake 提供的 os.execv/os.runv 等进程执行接口,仅仅只支持 stdout/stderr 输出重定向,但是并不支持 stdin 输入重定向,因此在这个版本中,我们对其也做了支持。

使用方式如下:

os.execv("foo", {"arg1", "arg2"}, {stdin = "/tmp/a"})

我们可以执行进程的时候,将 /tmp/a 文件作为重定向输入,当然我们还可以传递 {stdout = "/tmp/out"} 等作为重定向输出。

vs 工程分组支持

我们新增了一个接口 set_group,来对每个 target 进行分组支持,此接口目前仅用于 vs/vsxmake 工程生成,对 vs 工程内部子工程目录树按指定结构分组展示,不过后续也可能对其他模块增加分组支持。

比如对于下面的分组配置:

add_rules("mode.debug", "mode.release")

target("test1")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group1")

target("test2")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group1")

target("test3")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group1/group2")

target("test4")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group3/group4")

target("test5")
    set_kind("binary")
    add_files("src/*.cpp")

target("test6")
    set_kind("binary")
    add_files("src/*.cpp")

生成的 vs 工程目录结构效果如下:

其中 set_group("group1/group2") 可以将 target 设置到二级分组中去。

vs 工程自动更新规则

如果觉得每次通过 xmake project -k vsxmake 命令来生成和更新 vs 工程很繁琐,我们现在可以通过在 xmake.lua 中配置 plugin.vsxmake.autoupdate 规则来实现自动更新。

用户可以在 vs 工程中每次执行构建后,如果文件列表或者 xmake.lua 有改动,vs 工程都会自动更新。

add_rules("plugin.vsxmake.autoupdate")

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

vs/vsxmake 工程插件改进

除了上面提到的分组支持和自动更新,这个版本中,我们还修复了不少 vs 工程相关的问题,比如:intellisense 提示改进,路径被截断的问题修复,全面支持远程依赖包

改进 windows 注册表支持

xmake 改进了内部的 winos 模块,新增了一些接口来更加方便的访问注册表,获取 windows 上的注册表配置。

winos.registry_keys
  • 获取注册表建列表

支持通过模式匹配的方式,遍历获取注册表键路径列表,* 为单级路径匹配,** 为递归路径匹配。

local keypaths = winos.registry_keys("HKEY_LOCAL_MACHINE\\SOFTWARE\\*\\Windows NT\\*\\CurrentVersion\\AeDebug")
for _, keypath in ipairs(keypaths) do
    print(winos.registry_query(keypath .. ";Debugger"))
end
winos.registry_values
  • 获取注册表值名列表

支持通过模式匹配的方式,获取指定键路径的值名列表,; 之后的就是指定的键名模式匹配字符串。

local valuepaths = winos.registry_values("HKEY_LOCAL_MACHINE\\SOFTWARE\\xx\\AeDebug;Debug*")
for _, valuepath in ipairs(valuepaths) do
    print(winos.registry_query(valuepath))
end
winos.registry_query
  • 获取注册表建值

获取指定注册表建路径下的值,如果没有指定值名,那么获取键路径默认值

local value, errors = winos.registry_query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug")
local value, errors = winos.registry_query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger")

Zig 项目构建支持

在上个版本中,xmake 已经对 zig 进行了实验性支持,但是期间也躺了不少坑,尤其是 windows/macos 上构建中遇到了不少问题。

然后在最新的 zig 0.7.1 中,已经将我遇到的大部分问题都修复了,现在 xmake 已经可以很好的支持 zig 项目编译。

我们可以通过下面的命令,快速创建一个 Zig 空工程:

$ xmake create -l zig console

xmake.lua 内容如下:

add_rules("mode.debug", "mode.release")

target("console")
    set_kind("binary")
    add_files("src/*.zig")

可以看到,其实配置方式跟 C/C++ 并没有什么不同,由于 Zig 和 C 有很好的二进制兼容,因此我们也可以使用 add_requires 来给 zig 项目添加 C/C++ 包的远程依赖支持。

然后执行 xmake 就可以完成编译了。

$ xmake

然后继续运行 run 命令,就可以直接执行 zig 程序,输出运行结果。

$ xmake run
Hello world!

我们还可以很方便的实现 C 和 Zig 的混合编译支持,只需要添加上对应的 C 代码文件就可以了。

add_rules("mode.debug", "mode.release")

target("console")
    set_kind("binary")
    add_files("src/*.zig", "src/*.c")

完整代码例子见:Zig with C

Luarocks 插件

luarocks 是 lua 的一个包管理工具,提供了各种 lua 模块的安装集成,不过它本身在对 lua c 模块进行构建是采用的内建的构建机制。

比如在它的 rockspec 文件中通过 builtin 构建类型来描述常用 lua c 模块的构建:

build = {
    type = "builtin",
    modules = {
        ["module.hello"] = {
            sources = "src/test.c"
        }
    },
    copy_directories = {}
}

这对于小模块而言,并没有什么问题,但如果模块的 c 代码结构比较复杂,它内置的构建规则还是有很多的局限性,并不灵活,另外切换 msvc / mingw 工具链以及参数配置什么的都不够灵活。

因此,xmake 提供了 luarocks=build-xmake 插件去替换 luarocks 内置的构建系统,替换方式也很简单,只需要将 builtin 构建类型改成 xmake,并加上 luarocks-build-xmake 依赖就行了。

dependencies = {
    "lua >= 5.1",
    "luarocks-build-xmake"
}
build = {
    type = "xmake",
    modules = {
        ["module.hello"] = {
            sources = "src/test.c"
        }
    },
    copy_directories = {}
}

但是这样还是很繁琐,还是要基于 rockspec 文件中 modules 中的源文件列表来描述规则,然后 luarocks-build-xmake 会自动根据配置生成 xmake.lua 来完成构建。

不过既然用了 xmake,那么自己的 lua 模块,完全可以用 xmake.lua 来维护,这样构建配置就更加灵活了,因此我们只需要下面这样就行了。

dependencies = {
    "lua >= 5.1",
    "luarocks-build-xmake"
}
build = {
    type = "xmake",
    copy_directories = {}
}

只需要设置当前切换到 xmake 编译,完全使用 lua 模块项目内置的 xmake.lua 规则文件。

支持在 windows 安装部署 Qt 程序

非常感谢 @SirLynix 的贡献,xmake 已经可以支持在 windows 上部署安装 Qt 应用程序。

我们只需要正常维护一个 Qt 程序,例如:

add_rules("mode.debug", "mode.release")

target("demo")
    add_rules("qt.quickapp")
    add_headerfiles("src/*.h")
    add_files("src/*.cpp")
    add_files("src/qml.qrc")

然后,我们只需要执行下面的编译安装命令,xmake 就会自动调用 windeployqt.exe 程序去安装部署我们的 Qt 应用。

$ xmake
$ xmake install -o d:\installdir

相关补丁:#1145

另外,在之前的版本中,xmake 也已经支持对 macOS 和 android 版本的 Qt 程序进行部署打包,每次只需要正常的编译命令,就可以生成 QT .app/.apk 安装包。

$ xmake f -p android --ndk=/xxx/android-ndk-r20b --sdk=/xxx
$ xmake

一些问题修复

我们还修复了不少用户反馈的问题,这里我们介绍一些比较重要的 bug 修复,例如:

我们修复了 add_defines("TEST=\"hello world\"") 中内部带有空的双引号问题,之前编译会出错。

另外我们改进了 vstudio 环境的查找和支持,解决了用户 home 目录和环境变量中带有中文导致的编译失败问题。

我们也改进了 llvm 工具链,解决了 macOS 下如果没有安装 xcode 的情况下,使用 llvm 工具链缺少 isysroot 配置问题,以及 msvc 下头文件依赖编译偶尔失效问题。

更新内容

新特性

  • #1035: 图形配置菜单完整支持鼠标事件,并且新增滚动栏
  • #1098: 支持传递 stdin 到 os.execv 进行输入重定向
  • #1079: 为 vsxmake 插件添加工程自动更新插件,add_rules("plugin.vsxmake.autoupdate")
  • 添加 xmake f --vs_runtime=MTset_runtimes("MT") 去更方便的对 target 和 package 进行设置
  • #1032: 支持枚举注册表 keys 和 values
  • #1026: 支持对 vs/vsmake 工程增加分组设置
  • #1178: 添加 add_requireconfs() 接口去重写依赖包的配置
  • #1043: 为 luarocks 模块添加 luarocks.module 构建规则
  • #1190: 添加对 Apple Silicon (macOS ARM) 设备的支持
  • #1145: 支持在 windows 上安装部署 Qt 程序, 感谢 @SirLynix

改进

  • #1072: 修复并改进 cl 编译器头文件依赖信息
  • 针对 ui 模块和 xmake f --menu 增加 utf8 支持
  • 改进 zig 语言在 macOS 上的支持
  • #1135: 针对特定 target 改进多平台多工具链同时配置支持
  • #1153: 改进 llvm 工具链,针对 macos 上编译增加 isysroot 支持
  • #1071: 改进 vs/vsxmake 生成插件去支持远程依赖包
  • 改进 vs/vsxmake 工程生成插件去支持全局的 set_arch() 设置
  • #1164: 改进 vsxmake 插件调试加载 console 程序
  • #1179: 改进 llvm 工具链,添加 isysroot

Bugs 修复

  • #1091: 修复不正确的继承链接依赖
  • #1105: 修复 vsxmake 插件 c++ 语言标准智能提示错误
  • #1132: 修复 vsxmake 插件中配置路径被截断问题
  • #1142: 修复安装包的时候,出现git找不到问题
  • 修复在 macOS Big Sur 上 macos.version 问题
  • #1084: 修复 add_defines() 中带有双引号和空格导致无法正确处理宏定义的问题
  • #1195: 修复 unicode 编码问题,改进 vs 环境查找和进程执行

关注公众号

TBOOX开源工程

专注C跨平台开发解决方案

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 TBOOX开源工程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 新特性介绍
    • 新增 add_requireconfs 改进包配置
      • 图形化配置支持鼠标和滚动操作
        • stdin 重定向输入支持
          • vs 工程分组支持
            • vs 工程自动更新规则
              • vs/vsxmake 工程插件改进
                • 改进 windows 注册表支持
                  • winos.registry_keys
                  • winos.registry_values
                  • winos.registry_query
                • Zig 项目构建支持
                  • Luarocks 插件
                    • 支持在 windows 安装部署 Qt 程序
                      • 一些问题修复
                      • 更新内容
                        • 新特性
                          • 改进
                            • Bugs 修复
                              • 关注公众号
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档