xmake

介绍

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

虽然,简单易用是 xmake 的一大特色,但 xmake 的功能也是非常强大的,既能够像 Make/Ninja 那样可以直接编译项目,也可以像 CMake/Meson 那样生成工程文件,还有内置的包管理系统来帮助用户解决 C/C++依赖库的集成使用问题。

目前,xmake主要用于C/C++项目的构建,但是同时也支持其他native语言的构建,可以实现跟C/C++进行混合编译,同时编译速度也是非常的快,可以跟Ninja持平。

快速入门

安装

Windows

使用安装包

  1. Releases 上下载windows安装包
  2. 运行安装程序 xmake-[version].[win32|win64].exe

releases下面xmake-[version].[win32|win64].zip的包是不带安装程序的,可直接解压使用,绿色无依赖,不过需要自己添加PATH环境变量。

另外,Releases下面带有 xmake-tinyc 开头的exe安装包,内部集成了 tinyc 编译器环境,自带 libc 和 winapi 头文件,安装这个包,可以实现在没有 msvc 环境下,也能正常编译 c 程序。 这对于临时想写一些 c 测试或者算法代码,又不想安装 msvc 的用户非常有用,不过安装包会稍微大2-3M,不过也还好。

Msys/Mingw
mingw64
1
pacman -Sy mingw-w64-x86_64-xmakeCopy to clipboardErrorCopied
mingw32
1
pacman -Sy mingw-w64-i686-xmakeCopy to clipboardErrorCopied
MacOS
1
2
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install xmake
Ubuntu
使用apt安装
1
2
3
sudo add-apt-repository ppa:xmake-io/xmake
sudo apt update
sudo apt install xmake
更新升级
1
2
3
4
5
6
7
8
9
10
11
xmake update
xmake update 2.7.1

#我们也可以指定更新到master/dev分支版本:
xmake update master
xmake update dev

#从指定git源更新
xmake update github:xmake-io/xmake#master
xmake update gitee:tboox/xmake#dev # gitee镜像

卸载xmake
1
xmake update --uninstall

快速上手

创建工程

1
xmake create -l c -P ./hello

构建工程

1
2
cd hello
xmake

运行程序

1
2
3
xmake run hello
xmake run
xmake r

调试程序

首先你需要切换到 debug 模式去重新编译程序。

1
2
xmake config -m debug 
xmake

然后执行下面的命令去开始调试:

1
xmake run -d hello 

配置说明

Windows
1
2
xmake f -p windows [-a x86|x64]
xmake
Mingw

xmake 除了支持 Msys2/MingW, MingW for macOS/linux 之外,还支持 llvm-mingw 工具链,可以切换 arm/arm64 架构来编译。

1
2
$ xmake f -p mingw --sdk=/usr/local/i386-mingw32-4.3.0/ [-a i386|x86_64|arm|arm64]
$ xmake

使用vs

1
xmake project -k vsxmake -m "debug,release"

添加包

例子

1
2
3
4
5
6
7
add_requires("tbox >1.6.1", "libuv master", "vcpkg::ffmpeg", "brew::pcre2/libpcre2-8")
add_requires("conan::openssl/1.1.1g", {alias = "openssl", optional = true, debug = true})
target("test")
set_kind("binary")
add_files("src/*.c")
add_packages("tbox", "libuv", "vcpkg::ffmpeg", "brew::pcre2/libpcre2-8", "openssl")

1
xmake f -p windows -a x64 -m debug

xmake配置编译工具

设置编译器:通过指定编译器的路径或名称,你可以选择特定的编译器来构建项目。

1
xmake f --cc=gcc --cxx=g++

指定构建平台:可以为不同的操作系统平台配置项目,如 Windows、Linux、macOS 等。

1
2
xmake f -p windows
xmake f -p linux

选择构建模式:设置构建模式,如 debug 或 release,这影响编译器的优化级别和调试信息的生成。

1
2
xmake f -m debug
xmake f -m release

配置目标架构:可以指定目标处理器架构,如 x86、x64、arm 等。

1
2
xmake f -a x86_64
xmake f -a armv7

清除配置缓存:重新检测和配置项目,常用于更改环境或解决配置问题。

1
xmake f -c

设置其他选项:如启用或禁用某些特性、添加宏定义、配置库路径等。

1
xmake f --cxxflags="-DDEBUG -O0" --ldflags="-L/usr/local/lib"

使用示例

mingw

1
xmake f -p windows -a x86_64 --toolchain=mingw -m release -c

msvc

1
xmake f -p windows --toolchain=msvc -m release -c

linux

1
xmake f -p linux 

工具链测试

  • -c 清除之前的配置缓存,基于新的编译器设置重新检测环境。
  • 使用 -p 选项 指定编译环境
  • xmake 中,f 命令是 xmake fxmake config 的简写,用于配置项目

msvc

1
2
xmake f --toolchain=msvc -c
xmake

gcc

1
2
xmake f --toolchain=gcc -c
xmake

clang

1
2
xmake f --toolchain=clang -c
xmake

LLVM

1
2
xmake f --toolchain=llvm  -c
xmake

mingw

因此建议整个切到 mingw 平台编译,还能支持依赖包下载。

1
xmake f -p mingw -c

xmake 默认会自动探测 mingw 工具链位置,macOS 和 msys/mingw64 环境通常都能自动探测到,如果检测到,也可以手动指定 mingw sdk 路径。

1
2
xmake f -p mingw --mingw=/xxx/mingw -c
xmake

LLVM-mingw

这其实是一个独立于 Mingw 的项目,用法跟 Mingw 完全一直,但是它是基于 LLVM 的,并且提供了 arm/arm64 等其他更多架构的支持,而不仅仅是 i386/x86_64

1
2
xmake f -p mingw -a arm64 --mingw=/xxx/llvm-mingw -c
xmake
1
xmake f -p mingw -a arm64 --mingw=C:\softwares\llvm-mingw-20240502-msvcrt-x86_64-gcc-15.0.0\llvm-mingw-20240502-msvcrt-x86_64  -c

如果要使用 llvm-mingw 的 arm/arm64 架构,则需要额外指定 -a arm64 参数才行,另外 llvm-mingw 默认 xmake 不一定能够检测到,需要额外设置 sdk 路径。

CUDA

对于 Cuda 程序,我们需要手动切换到 cuda 工具链。

1
2
xmake f --toolchain=cuda -c
xmake

我们也可以手动切换 nvcc 内部调用的 C/C++ 编译器。

1
2
xmake f --toolchain=cuda --cu-ccbin=clang -c
xmake

msys2

1
xmake f -p mingw --sdk=C:\softwares\msys64\ucrt64 -c -v

给linux编译

1
xmake f -p  linux --sdk=C:\softwares\x86_64-linux-gnu\gcc-9.3.0  -c

自动下载工具链

拉取指定版本的 llvm 工具链

我们使用 llvm-10 中的 clang 来编译项目。

1
2
3
4
5
add_requires("llvm 10.x", {alias = "llvm-10"})
target("test")
set_kind("binary")
add_files("src/*.c)
set_toolchains("llvm@llvm-10")

拉取交叉编译工具链

我们也可以拉取指定的交叉编译工具链来编译项目。

1
2
3
4
5
add_requires("muslcc")
target("test")
set_kind("binary")
add_files("src/*.c)
set_toolchains("@muslcc")

拉取工具链并且集成对应工具链编译的依赖包

我们也可以使用指定的muslcc交叉编译工具链去编译和集成所有的依赖包。

1
2
3
4
5
6
7
8
9
add_requires("muslcc")
add_requires("zlib", "libogg", {system = false})

set_toolchains("@muslcc")

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

使用镜像-可能有问题

1.添加仓库: 使用 xmake repo --add 命令来添加一个新的仓库。例如:

1
xrepo add-repo gitee https://gitee.com/tboox/xmake-repo

2.使用指定仓库安装包: 在项目的 xmake.lua 文件中,你可以通过设置 add_requires 函数中的 repositories 属性来指定使用特定的仓库。例如:

1
add_requires("libpng", {repositories = "gitee"})

3.更新仓库: 如果你需要更新仓库的内容,可以使用:

1
xmake repo --update gitee

设置仓库的优先级

xrepo

分布式仓库支持

除了可以直接从官方仓库:xmake-repo 检索安装包之外, 我们还可以添加任意多个自建的仓库,甚至可以完全隔离外网,仅仅在公司内部网络维护私有包的安装集成。

只需要通过下面的命令,添加上自己的仓库地址:

1
2
# xrepo add-repo myrepo https://github.com/mygroup/myrepo
xrepo add-repo gitee https://gitee.com/tboox/xmake-repo

基本使用

1
$ xrepo install zlib tbox

安装指定版本包

完整支持 Semantic Versioning (语义版本)。

1
2
$ xrepo install "zlib 1.2.x"
$ xrepo install "zlib >=1.2.0"

安装指定平台包

1
2
3
4
$ xrepo install -p iphoneos -a arm64 zlib
$ xrepo install -p android [--ndk=/xxx] zlib
$ xrepo install -p mingw [--mingw=/xxx] zlib
$ xrepo install -p cross --sdk=/xxx/arm-linux-musleabi-cross zlib

安装调试版本包

1
$ xrepo install -m debug zlib

安装动态库版本包

1
$ xrepo install -k shared zlib

安装指定配置包

1
2
$ xrepo install -f "vs_runtime='MD'" zlib
$ xrepo install -f "regex=true,thread=true" boost

安装第三方包管理器的包

1
2
3
$ xrepo install brew::zlib
$ xrepo install vcpkg::zlib
$ xrepo install conan::zlib/1.2.11

查找包的库使用信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ xrepo fetch pcre2
{
{
linkdirs = {
"/usr/local/Cellar/pcre2/10.33/lib"
},
links = {
"pcre2-8"
},
defines = {
"PCRE2_CODE_UNIT_WIDTH=8"
},
includedirs = "/usr/local/Cellar/pcre2/10.33/include"
}
}Copy to clipboardErrorCopied
$ xrepo fetch --ldflags openssl
-L/Users/ruki/.xmake/packages/o/openssl/1.1.1/d639b7d6e3244216b403b39df5101abf/lib -lcrypto -lsslCopy to clipboardErrorCopied
$ xrepo fetch --cflags openssl
-I/Users/ruki/.xmake/packages/o/openssl/1.1.1/d639b7d6e3244216b403b39df5101abf/includeCopy to clipboardErrorCopied
$ xrepo fetch -p [iphoneos|android] --cflags "zlib 1.2.x"
-I/Users/ruki/.xmake/packages/z/zlib/1.2.11/df72d410e7e14391b1a4375d868a240c/includeCopy to clipboardErrorCopied
$ xrepo fetch --cflags --ldflags conan::zlib/1.2.11
-I/Users/ruki/.conan/data/zlib/1.2.11/_/_/package/f74366f76f700cc6e991285892ad7a23c30e6d47/include -L/Users/ruki/.conan/data/zlib/1.2.11/_/_/package/f74366f76f700cc6e991285892ad7a23c30e6d47/lib -lz

导出安装后的包

xrepo 可以快速导出已经安装后的包,包括对应的库文件,头文件等等。

1
$ xrepo export -o /tmp/output zlib

搜索支持的包

1
2
3
4
5
6
$ xrepo search zlib "pcr*"
zlib:
-> zlib: A Massively Spiffy Yet Delicately Unobtrusive Compression Library (in xmake-repo)
pcr*:
-> pcre2: A Perl Compatible Regular Expressions Library (in xmake-repo)
-> pcre: A Perl Compatible Regular Expressions Library (in xmake-repo)

查看包环境信息

1
2
3
4
5
6
7
8
9
10
11
12
13
$ xrepo env --show luajit
{
OLDPWD = "/mnt/tbox",
HOME = "/home/ruki",
PATH = "/home/ruki/.xmake/packages/l/luajit/2.1.0-beta3/fbac76d823b844f0b91abf3df0a3bc61/bin:/tmp:/tmp/arm-linux-musleabi-cross/bin:~/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
TERM = "xterm",
PWD = "/mnt/xmake",
XMAKE_PROGRAM_DIR = "/mnt/xmake/xmake",
HOSTNAME = "e6edd61ff1ab",
LD_LIBRARY_PATH = "/home/ruki/.xmake/packages/l/luajit/2.1.0-beta3/fbac76d823b844f0b91abf3df0a3bc61/lib",
SHLVL = "1",
_ = "/mnt/xmake/scripts/xrepo.sh"
}

包虚拟环境

进入虚拟环境

我们可以通过在当前目录下,添加 xmake.lua 文件,定制化一些包配置,然后进入特定的包虚拟环境。

1
2
3
4
5
add_requires("zlib 1.2.11")
add_requires("python 3.x", "luajit")
$ xrepo env shell
> python --version
> luajit --version

我们也可以在 xmake.lua 配置加载对应的工具链环境,比如加载 vs 的编译环境。

1
set_toolchains("msvc")

管理虚拟环境

我们可以使用下面的命令,把指定的虚拟环境配置全局注册到系统中,方便快速切换。

1
$ xrepo env --add /tmp/base.lua

这个时候,我们就保存了一个名叫 base 的全局虚拟环境,我们可以通过 list 命令去查看它。

1
2
3
4
$ xrepo env --list
/Users/ruki/.xmake/envs:
- base
envs(1) found!

我们也可以删除它。

1
$ xrepo env --remove base

切换全局虚拟环境

如果我们注册了多个虚拟环境,我们也可以快速切换它们。

1
2
$ xrepo env -b base shell
> python --version

或者直接加载指定虚拟环境运行特定命令

1
$ xrepo env -b base python --version

xrepo env -b/--bind 就是绑定指定的虚拟环境,更多详情见:#1762

查看包信息

1
$ xrepo info zlib

参考

xmake