基于Lua的跨平台构建工具-XMake
2023-08-25 14:57:49 阿炯

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


A cross-platform build utility based on Lua. Simple, Fast and Lightweight, Modern C/C++ build tools, Powerful dependency package integration.


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

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

Xmake = Build backend + Project Generator + Package Manager + [Remote|Distributed] Build + Cache

尽管不是很准确,但还是可以把 Xmake 按下面的方式来理解:
Xmake ≈ Make/Ninja + CMake/Meson + Vcpkg/Conan + distcc + ccache/sccache

课程
xmake 官方也推出了一些入门课程带你一步步快速上手,课程列表如下:
Xmake 带你轻松构建 C/C++ 项目

安装

使用 curl
bash <(curl -fsSL https://xmake.io/shget.text)

使用 wget
bash <(wget https://xmake.io/shget.text -O -)

使用 powershell
Invoke-Expression (Invoke-Webrequest 'https://xmake.io/psget.text' -UseBasicParsing).Content

简单的工程描述

包依赖描述

官方的 xmake 包管理仓库: xmake-repo

构建工程
$ xmake

运行目标
$ xmake run console

调试程序
$ xmake run -d console

配置平台
$ xmake f -p [windows|linux|macosx|android|iphoneos ..] -a [x86|arm64 ..] -m [debug|release]
$ xmake

图形化菜单配置
$ xmake f --menu


包依赖管理

架构和流程


包管理特性
官方仓库提供近 800+ 常用包,真正做到全平台一键下载集成编译
全平台包支持,支持交叉编译的依赖包集成
支持包虚拟环境管理和加载,xrepo env shell
Windows 云端预编译包加速
支持自建包仓库,私有仓库部署
第三方包仓库支持,提供更加丰富的包源,例如:vcpkg, conan, conda 等等
支持自动拉取使用云端工具链
支持包依赖锁定

支持平台
Windows (x86, x64)
macOS (i386, x86_64, arm64)
Linux (i386, x86_64, cross-toolchains ..)
*BSD (i386, x86_64)
Android (x86, x86_64, armeabi, armeabi-v7a, arm64-v8a)
iOS (armv7, armv7s, arm64, i386, x86_64)
WatchOS (armv7k, i386)
AppleTVOS (armv7, arm64, i386, x86_64)
MSYS (i386, x86_64)
MinGW (i386, x86_64, arm, arm64)
Cygwin (i386, x86_64)
Wasm (wasm32)
Haiku (i386, x86_64)
Cross (cross-toolchains ..)

支持工具链
$ xmake show -l toolchains
xcode         Xcode IDE
msvc          Microsoft Visual C/C++ Compiler
clang-cl      LLVM Clang C/C++ Compiler compatible with msvc
yasm          The Yasm Modular Assembler
clang         A C language family frontend for LLVM
go            Go Programming Language Compiler
dlang         D Programming Language Compiler (Auto)
dmd           D Programming Language Compiler
ldc           The LLVM-based D Compiler
gdc           The GNU D Compiler (GDC)
gfortran      GNU Fortran Programming Language Compiler
zig           Zig Programming Language Compiler
sdcc          Small Device C Compiler
cuda          CUDA Toolkit (nvcc, nvc, nvc++, nvfortran)
ndk           Android NDK
rust          Rust Programming Language Compiler
swift         Swift Programming Language Compiler
llvm          A collection of modular and reusable compiler and toolchain technologies
cross         Common cross compilation toolchain
nasm          NASM Assembler
gcc           GNU Compiler Collection
mingw         Minimalist GNU for Windows
gnu-rm        GNU Arm Embedded Toolchain
envs          Environment variables toolchain
fasm          Flat Assembler
tinycc        Tiny C Compiler
emcc          A toolchain for compiling to asm.js and WebAssembly
icc           Intel C/C++ Compiler
ifort         Intel Fortran Compiler
muslcc        The musl-based cross-compilation toolchain
fpc           Free Pascal Programming Language Compiler
wasi          WASI-enabled WebAssembly C/C++ toolchain
nim           Nim Programming Language Compiler
circle        A new C++20 compiler
armcc         ARM Compiler Version 5 of Keil MDK
armclang      ARM Compiler Version 6 of Keil MDK
c51           Keil development tools for the 8051 Microcontroller Architecture
icx           Intel LLVM C/C++ Compiler
dpcpp         Intel LLVM C++ Compiler for data parallel programming model based on Khronos SYCL
masm32        The MASM32 SDK
iverilog      Icarus Verilog
verilator     Verilator open-source SystemVerilog simulator and lint system

支持语言
C/C++
Objc/Objc++
Swift
Assembly
Golang
Rust
Dlang
Fortran
Cuda
Zig
Vala
Pascal
Nim
Verilog

支持特性
语法简单易上手
快速安装,无任何依赖
全平台一键编译
支持交叉编译,智能分析交叉工具链信息
极速,多任务并行编译支持
C++20 Module 支持
支持跨平台的 C/C++ 依赖包快速集成,内置包管理器
多语言混合编译支持
丰富的插件支持,提供各种工程生成器,例如:vs/makefile/cmakelists/compile_commands 生成插件
REPL 交互式执行支持
增量编译支持,头文件依赖自动分析
工具链的快速切换、定制化支持
丰富的扩展模块支持
远程编译支持
分布式编译支持
内置的本地和远程编译缓存支持

工程类型
静态库程序
动态库类型
控制台程序
Cuda 程序
Qt 应用程序
WDK Windows 驱动程序
WinSDK 应用程序
MFC 应用程序
iOS/MacOS 应用程序(支持.metal)
Framework和Bundle程序(iOS/MacOS)
SWIG/Pybind11 模块 (Lua, python, ...)
Luarocks 模块
Protobuf 程序
Lex/yacc 程序
C++20 模块
Linux 内核驱动模块
Keil MDK/C51 嵌入式程序
Verilog 仿真程序

分布式编译和缓存
跨平台支持
支持 msvc, clang, gcc 和交叉编译工具链
支持构建 android, ios, linux, win, macOS 程序
除了编译工具链,无任何其他依赖
支持编译服务器负载均衡调度
支持大文件实时压缩传输 (lz4)
几乎零配置成本,无需共享文件系统,更加方便和安全


最新版本:2.8
2023年8月下旬发布的2.8版本中新增了不少实用的 API,并且移除了一些几年前就被标记为废弃的接口,另外改进了动态库对 soname 的支持。

增加 soname 支持
新版本中对 set_version 接口新增了 soname 版本支持,用于控制 so/dylib 动态库的版本兼容性控制。可以配置 soname 的版本后缀名称,xmake 会在编译、安装动态库的时候,自动生成符号链接,执行指定版本的动态库。

改进 add_vectorexts 接口
add_vectorexts 接口主要用于添加扩展指令优化选项,目前支持以下几种扩展指令集:
add_vectorexts("mmx")
add_vectorexts("neon")
add_vectorexts("avx", "avx2", "avx512")
add_vectorexts("sse", "sse2", "sse3", "ssse3", "sse4.2")

其中,avx512, sse4.2 是我们新版本新增的指令配置,另外我们还新增了一个 all 配置项,可以用于尽可能的开启所有扩展指令优化。
add_vectorexts("all")

新增 set_encodings 接口
这个新接口主要用于设置源文件、目标执行文件的编码。默认情况下,我们仅仅指定编码,是会同时对源文件,目标文件生效。目前仅仅支持设置成 utf-8 编码,将来会不断扩展。如果仅仅想单独设置源文件编码,或者目标文件编码,也是可以的。

新增 add_forceincludes 接口
还新增了 add_forceincludes 接口,用于在配置文件中直接强制添加 includes 头文件。
add_forceincludes("config.h")

它的效果类似于 #include <config.h>,但是不需要在源码中显式添加它了。另外它的搜索路径也是需要通过 add_includedirs 来控制,而不是直接配置文件路径。
add_forceincludes("config.h")
add_includedirs("src")

默认 add_forceincludes 匹配 c/c++/objc。如果仅仅只想匹配 c++ 可以这么配置:
add_forceincludes("config.h", {sourcekinds = "cxx"})

如果想同时匹配多个源文件类型,也是可以的:
add_forceincludes("config.h", {sourcekinds = {"cxx", "mxx"}})

对于 gcc,它会设置 -include config.h 标志,对于 msvc,它会设置 -FI config.h 标志。

新增 add_extrafiles 接口
在之前的版本中,如果我们要在 vs/vsxmake 工程生成器中添加一些额外的文件到工程列表中去,只能通过 add_headerfiles 来添加,但是这有一点 Hack。

因此新增了 add_extrafiles 接口,专门用于配置一些额外的文件到工程中,这样用户也可以快速点击编辑它们。这些被添加文件不是代码文件,不会参与编译,也不会被安装,仅仅只是能够让用户方便的在生成的工程 IDE 中,快速编辑访问它们。将来也可能用此接口做更多其他的事情。

改进 Rust 交叉编译支持
新版本还对 Rust 项目构建做了改进,新增了交叉编译支持,包括对依赖包的交叉编译。

修复 macOS/Linux 上子子进程无法快速退出问题。

官方主页:https://xmake.io/