Xmake 是一个基于 Lua 的轻量级跨平台构建工具。
它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时。
它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。
我们能够使用它像 Make/Ninja 那样可以直接编译项目,也可以像 CMake/Meson 那样生成工程文件,另外它还有内置的包管理系统来帮助用户解决 C/C++ 依赖库的集成使用问题。
目前,Xmake 主要用于 C/C++ 项目的构建,但是同时也支持其他 native 语言的构建,可以实现跟 C/C++ 进行混合编译,同时编译速度也是非常的快,可以跟 Ninja 持平。
Xmake = Build backend + Project Generator + Package Manager + [Remote|Distributed] Build + Cache
尽管不是很准确,但我们还是可以把 Xmake 按下面的方式来理解:
Xmake ≈ Make/Ninja + CMake/Meson + Vcpkg/Conan + distcc + ccache/sccache
新版本中,我们新增了鸿蒙系统的 native 工具链支持,并且实现了一种新的 native 原生 lua 模块的导入支持。另外,我们也对构建速度做了很多的优化,效果非常明显。
我们新增了鸿蒙 OS 平台的 native 工具链编译支持:
$ xmake f -p harmony
xmake 也会自动探测默认的 SDK 路径,当然我们也可以指定 Harmony SDK 路径。
$ xmake f -p Harmony --sdk=/Users/ruki/Library/Huawei/Sdk/...
我们知道,在 xmake 中,可以通过 import 接口去导入一些 lua 模块在脚本域中使用,但是如果一些模块的操作比较耗时,那么 lua 实现并不是理想的选择。 因此,新版本中,我们新增了 native lua 模块的支持,可以通过 native 实现,来达到提速优化的效果,并且模块导入和使用,还是跟 lua 模块一样简单。
使用原生模块时,xmake 会进行两段编译,先会自动编译原生模块,后将模块导入 lua 作为库或二进制,而对于用户,仅仅只需要调用 import 导入即可。
动态库模块的好处是,不仅仅通过 native 实现了性能加速,另外避免了每次调用额外的子进程创建,因此更加的轻量,速度进一步得到提升。
我们可以先定义一个动态库模块,里面完全支持 lua 的所有 c API,因此我们也可以将一些第三方的开源 lua native 模块直接引入进来使用。
这里我们也有一个完整的导入 lua-cjson 模块的例子可以参考:native_module_cjson
首先,我们先实现 shared 的 native 代码,所以接口通过 lua API 导出。
./modules/foo/foo.c
#include <xmi.h>
static int c_add(lua_State* lua) {
int a = lua_tointeger(lua, 1);
int b = lua_tointeger(lua, 2);
lua_pushinteger(lua, a + b);
return 1;
}
static int c_sub(lua_State* lua) {
int a = lua_tointeger(lua, 1);
int b = lua_tointeger(lua, 2);
lua_pushinteger(lua, a - b);
return 1;
}
int luaopen(foo, lua_State* lua) {
// 收集add和sub
static const luaL_Reg funcs[] = {
{"add", c_add},
{"sub", c_sub},
{NULL, NULL}
};
lua_newtable(lua);
// 传递函数列表
luaL_setfuncs(lua, funcs, 0);
return 1;
}
注意到这里,我们 include 了一个 xmi.h
的接口头文件,其实我们也可以直接引入 lua.h
,luaconf.h
,效果是一样的,但是会提供更好的跨平台性,内部会自动处理 lua/luajit还有版本间的差异。
然后,我们配置 add_rules("modules.shared")
作为 shared native 模块来编译,不需要引入任何其他依赖。
甚至连 lua 的依赖也不需要引入,因为 xmake 主程序已经对其导出了所有的 lua 接口,可直接使用,所以整个模块是非常轻量的。
./modules/foo/xmake.lua
add_rules("mode.debug", "mode.release")
target("foo")
-- 指定目标为库lua模块
add_rules("module.shared")
add_files("foo.c")
Xmake 是一个基于 Lua 的轻量级跨平台构建工具。
它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时。
它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。
我们能够使用它像 Make/Ninja 那样可以直接编译项目,也可以像 CMake/Meson 那样生成工程文件,另外它还有内置的包管理系统来帮助用户解决 C/C++ 依赖库的集成使用问题。
目前,Xmake 主要用于 C/C++ 项目的构建,但是同时也支持其他 native 语言的构建,可以实现跟 C/C++ 进行混合编译,同时编译速度也是非常的快,可以跟 Ninja 持平。
Xmake = Build backend + Project Generator + Package Manager + [Remote|Distributed] Build + Cache
尽管不是很准确,但我们还是可以把 Xmake 按下面的方式来理解:
Xmake ≈ Make/Ninja + CMake/Meson + Vcpkg/Conan + distcc + ccache/sccache
新版本中,我们新增了 cosmocc 工具链支持,使用它,我们可以实现一次编译,到处运行。另外,我们还重构了 C++ Modules 的实现,解决了很多 C++ Modules 相关的问题。
cosmocc 工具链是 cosmopolitan 项目提供的编译工具链,使用这个工具链编译的程序可以实现一次编译,到处运行。
而新版本中,我们对这个工具链也做了支持,可以实现在 macosx/linux/windows 下编译程序,并且还能够支持自动下载 cosmocc 工具链。
对于用户,仅仅只需要配置 xmake.lua 工程文件,然后执行 xmake
命令,即可实现一键编译,到处运行。
xmake.lua 内容如下,这是一个最基础的 hello world 终端程序的构建配置。
add_rules("mode.debug", "mode.release")
add_requires("cosmocc")
target("test")
set_kind("binary")
add_files("src/*.c")
set_toolchains("@cosmocc")
然后,我们执行 xmake 命令,它会先下载集成 cosmocc 工具链,然后使用这个工具链去编译程序。
ruki:console$ xmake
checking for platform ... linux
checking for architecture ... x86_64
note: install or modify (m) these packages (pass -y to skip confirm)?
in xmake-repo:
-> cosmocc 3.2.4
please input: y (y/n/m)
=> install cosmocc 3.2.4 .. ok
[ 25%]: cache compiling.release src/main.c
[ 50%]: linking.release test
[100%]: build ok, spent 1.548s
ruki:console$ xmake run
hello world
Xmake 是一个基于 Lua 的轻量级跨平台构建工具。
它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时。
它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。
我们能够使用它像 Make/Ninja 那样可以直接编译项目,也可以像 CMake/Meson 那样生成工程文件,另外它还有内置的包管理系统来帮助用户解决 C/C++ 依赖库的集成使用问题。
目前,Xmake 主要用于 C/C++ 项目的构建,但是同时也支持其他 native 语言的构建,可以实现跟 C/C++ 进行混合编译,同时编译速度也是非常的快,可以跟 Ninja 持平。
Xmake = Build backend + Project Generator + Package Manager + [Remote|Distributed] Build + Cache
尽管不是很准确,但我们还是可以把 Xmake 按下面的方式来理解:
Xmake ≈ Make/Ninja + CMake/Meson + Vcpkg/Conan + distcc + ccache/sccache
在介绍新特性之前,还有个好消息告诉大家,上个版本 Xmake 被收入到了 debian 仓库,而最近 Xmake 又进入了 Fedora 官方仓库,大家可以在 Fedora 39 上,直接通过下面的命令安装 Xmake。
$ sudo dnf install xmake
非常感谢 @topazus @mochaaP 对 Xmake 的贡献,相关信息见:#941。
接下来,我们来介绍下,新版本带来的重量级特性:XPack。
它类似于 CMake 的 CPack 命令,可以将用户工程快速打包生成各种格式的安装包。
目前 Xmake 的 XPack 已经支持以下格式的打包:
除了上述已经支持的打包格式,还有 deb 等包格式也在陆续支持中,并且用户也可以配置生成自定义的包格式文件。
Xmake 是一个基于 Lua 的轻量级跨平台构建工具。
它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时。
它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。
我们能够使用它像 Make/Ninja 那样可以直接编译项目,也可以像 CMake/Meson 那样生成工程文件,另外它还有内置的包管理系统来帮助用户解决 C/C++ 依赖库的集成使用问题。
目前,Xmake 主要用于 C/C++ 项目的构建,但是同时也支持其他 native 语言的构建,可以实现跟 C/C++ 进行混合编译,同时编译速度也是非常的快,可以跟 Ninja 持平。
Xmake = Build backend + Project Generator + Package Manager + [Remote|Distributed] Build + Cache
尽管不是很准确,但我们还是可以把 Xmake 按下面的方式来理解:
Xmake ≈ Make/Ninja + CMake/Meson + Vcpkg/Conan + distcc + ccache/sccache
在介绍新特性之前,我们有一个好消息要告诉大家,Xmake 最近进入了 Debian 的官方仓库:https://packages.debian.org/sid/xmake,
等到明年4月份 Ubuntu 24.04 发布,我们应该就能直接通过 apt install xmake
命令去快速安装 Xmake 了。
同时也感谢 @Lance Lin 的帮助,他全程帮助我们维护并上传 Xmake 包到 Debian 仓库,真的非常感谢!
接下来,我们来介绍下 2.8.5 版本引入的一些改动,这个版本带来了很多的新特性,尤其是对链接排序,链接组的支持,还有对 xmake test
内置单元测试的支持。
另外,我们还新增了 Apple XROS 平台的构建支持,可以用于构建苹果新的 VisionOS 上的程序,还有我们还提供了更加灵活通用的 check_sizeof
检测接口,用于快速检测类型的大小。
这是一个存在了两年多的需求,主要用于调整 target 内部的链接顺序。
由于 xmake 提供了 add_links
, add_deps
, add_packages
, add_options
接口,可以配置目标、依赖,包和选项中的链接,尽管 add_links
本身的链接顺序可以根据添加顺序来调整。
但是 links,deps 和 packages 之间的链接顺序,只能按固定顺序生成,无法灵活调整,这对于一些复杂的项目,就有点显得力不从心了。
而我们在这个版本,彻底解决了这个问题,新增了 add_linkorders
接口,可用于配置目标、依赖、包、选项、链接组引入的各种链接顺序。
更多详情和背景,请见:#1452
为了更加灵活的调整 target 内部的各种链接顺序,我们可以通过 add_linkorders
这个新接口来实现,例如:
add_links("a", "b", "c", "d", "e")
-- e -> b -> a
add_linkorders("e", "b", "a")
-- e -> d
add_linkorders("e", "d")
add_links 是配置的初始链接顺序,然后我们通过 add_linkorders 配置了两个局部链接依赖 e -> b -> a
和 e -> d
后。
xmake 内部就会根据这些配置,生成 DAG 图,通过拓扑排序的方式,生成最终的链接顺序,提供给链接器。
当然,如果存在循环依赖,产生了环,它也会提供警告信息。
另外,对于循环依赖,我们也可以通过 add_linkgroups
配置链接组的方式也解决。
并且 add_linkorders
也能够对链接组进行排序。
add_links("a", "b", "c", "d", "e")
add_linkgroups("c", "d", {name = "foo", group = true})
add_linkorders("e", "linkgroup::foo")
如果要排序链接组,我们需要对每个链接组取个名,{name = "foo"}
,然后就能在 add_linkorders
里面通过 linkgroup::foo
去引用配置了。
我们也可以排序链接和 macOS/iPhoneOS 的 frameworks。
add_links("a", "b", "c", "d", "e")
add_frameworks("Foundation", "CoreFoundation")
add_linkorders("e", "framework::CoreFoundation")
Xmake 是一个基于 Lua 的轻量级跨平台构建工具。
它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时。
它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLists.txt,配置语法更加简洁直观,对新手非常友好,短时间内就能快速入门,能够让用户把更多的精力集中在实际的项目开发上。
我们能够使用它像 Make/Ninja 那样可以直接编译项目,也可以像 CMake/Meson 那样生成工程文件,另外它还有内置的包管理系统来帮助用户解决 C/C++ 依赖库的集成使用问题。
目前,Xmake 主要用于 C/C++ 项目的构建,但是同时也支持其他 native 语言的构建,可以实现跟 C/C++ 进行混合编译,同时编译速度也是非常的快,可以跟 Ninja 持平。
Xmake = Build backend + Project Generator + Package Manager + [Remote|Distributed] Build + Cache
尽管不是很准确,但我们还是可以把 Xmake 按下面的方式来理解:
Xmake ≈ Make/Ninja + CMake/Meson + Vcpkg/Conan + distcc + ccache/sccache
新版本中,我们新增了 Xmake 自身源码的断点调试支持,这可以帮助贡献者更加快速的熟悉 xmake 源码,也可以帮助用户去快速调试分析自身项目的配置脚本。
另外,我们 xmake-repo 官方仓库包的数量也即将突破 1100,短短一个月的时间,就新增了 100 多个包,非常感谢 @star-hengxing 的贡献。
同时,我们重点改进了 Wasm 的构建支持,以及 Qt6 for wasm 的支持。
2.8.3 版本,我们新增了 Lua 断点调试支持,配合 VSCode-EmmyLua 插件,我们可以很方便的在 VSCode 中断点调试 Xmake 自身源码。
首先,我们需要在 VSCode 的插件市场安装 VSCode-EmmyLua 插件,然后执行下面的命令更新下 xmake-repo 仓库保持最新。
xrepo update-repo
!> Xmake 也需要保持最新版本。
然后,在自己的工程目录下执行以下命令:
$ xrepo env -b emmylua_debugger -- xmake build
其中 xrepo env -b emmylua_debugger
用于绑定 EmmyLua 调试器插件环境,而 --
后面的参数,就是我们实际需要被调试的 xmake 命令。
通常我们仅仅调试 xmake build
构建,如果想要调试其他命令,可以自己调整,比如想要调试 xmake install -o /tmp
安装命令,那么可以改成:
$ xrepo env -b emmylua_debugger -- xmake install -o /tmp
执行完上面的命令后,它不会立即退出,会一直处于等待调试状态,有可能没有任何输出。
这个时候,我们不要急着退出它,继续打开 VSCode,并在 VSCode 中打开 Xmake 的 Lua 脚本源码目录。
也就是这个目录:Xmake Lua Scripts,我们可以下载的本地,也可以直接打开 Xmake 安装目录中的 lua 脚本目录。
然后切换到 VSCode 的调试 Tab 页,点击 RunDebug
-> Emmylua New Debug
就能连接到我们的 xmake build
命令调试端,开启调试。
如下图所示,默认的起始断点会自动中断到 debugger:_start_emmylua_debugger
内部,我们可以点击单步跳出当前函数,就能进入 main 入口。
然后设置自己的断点,点击继续运行,就能中断到自己想要调试的代码位置。
我们也可以在项目工程的配置脚本中设置断点,也可以实现快速调试自己的配置脚本,而不仅仅是 Xmake 自身源码。