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
- 项目源码
- 官方文档
- 入门课程
新版别改动
这个版别首要新增两大特性:
- Linux 内核驱动模块的构建支撑
- 分组构建和批量运转支撑,可用于完成
Run all tests
功用
剩余的首要是一些零散的功用改善和 Bugs 修正,能够看下文末的更新内容明细,一些比较大的改动,下面也会逐个说明。
新特性介绍
构建 Linux 内核驱动模块
Xmake 或许是首个供给 Linux 内核驱动开发 内置支撑的第三方构建东西了。
尽管网上也有介绍 CMake 怎么去装备构建 linux 驱动,可是大都是经过 add_custom_command
方法自界说各种指令,然后履行 echo
去自己拼接生成 Linux 的 Makefile 文件。
也就是说,其实仍是依靠 Linux 内核源码的 Makefile 来履行的构建,因而假如想自己追加一些编译装备和宏界说都会十分麻烦。
而运用 Xmake,咱们能够供给愈加灵敏的可装备性,愈加简略的装备文件,以及一键编译、主动依靠拉取集成、Linux kernel 源码主动下载集成,内核驱动穿插编译等特性。
Hello World
咱们经过一个最简略的字符驱动来直观感受下。
首要,咱们准备一个 Hello World 驱动代码,例如:
add_requires("linux-headers", {configs = {driver_modules = true}})
target("hello")
add_rules("platform.linux.driver")
add_files("src/*.c")
add_packages("linux-headers")
set_license("GPL-2.0")
它的装备十分简略,只需求装备上支撑模块的 linux-headers 包,然后运用 platform.linux.driver
构建规矩就行了。
然后直接履行 xmake 指令,一键编译,生成内核驱动模块 hello.ko。
$ xmake
[ 20%]: ccache compiling.release src/add.c
[ 20%]: ccache compiling.release src/hello.c
[ 60%]: linking.release build/linux/x86_64/release/hello.ko
[100%]: build ok!
简略么,或许你会说,这跟直接用 Makefile 装备,然后 make 编译也没啥太大区别么。
那么要点来了,Xmake 是会主动帮你拉取指定版别依靠内核源码,make 不会,CMake 也不会,用户必须经过 sudo apt install linux-headers-generic
自己装置它们。
可是 Xmake 不需求,上面的一键编译,我其实省掉了部分输出,实际上是这样的。
$ xmake
note: install or modify (m) these packages (pass -y to skip confirm)?
in xmake-repo:
-> m4 1.4.19 [from:linux-headers,bison,flex,elfutils]
-> flex 2.6.4 [from:bc,linux-headers]
-> bison 3.8.2 [from:bc,linux-headers]
-> ed 1.17 [from:bc,linux-headers]
-> texinfo 6.7 [from:bc,linux-headers]
-> bc 1.07.1 [from:linux-headers]
-> pkg-config 0.29.2 [from:linux-headers]
-> openssl 1.1.1l [private, from:linux-headers]
-> elfutils 0.183 [private, from:linux-headers]
-> linux-headers 5.10.46 [driver_modules:y]
please input: y (y/n/m)
=> download https://github.com/xmake-mirror/ed/archive/refs/tags/1.17.tar.gz .. ok
=> install ed 1.17 .. ok
=> download https://ftp.gnu.org/gnu/m4/m4-1.4.19.tar.xz .. ok
=> download https://ftp.gnu.org/gnu/texinfo/texinfo-6.7.tar.xz .. ok
=> download https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz .. ok
=> download https://github.com/openssl/openssl/archive/OpenSSL_1_1_1l.zip .. ok
=> install m4 1.4.19 .. ok
=> download https://github.com/westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz .. ok
=> install texinfo 6.7 .. ok
=> install pkg-config 0.29.2 .. ok
=> download http://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.gz .. ok
=> install flex 2.6.4 .. ok
=> download https://sourceware.org/elfutils/ftp/0.183/elfutils-0.183.tar.bz2 .. ok
=> install elfutils 0.183 .. ok
=> install bison 3.8.2 .. ok
=> download https://ftp.gnu.org/gnu/bc/bc-1.07.1.tar.gz .. ok
=> install bc 1.07.1 .. ok
=> install openssl 1.1.1l .. ok
=> download https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.46.tar.xz .. ok
=> install linux-headers 5.10.46 .. ok
[ 16%]: ccache compiling.release src/add.c
[ 16%]: ccache compiling.release src/hello.c
[ 16%]: ccache compiling.release src/hello.mod.c
[ 66%]: linking.release build/linux/x86_64/release/hello.ko
[100%]: build ok!
初次编译,Xmake 会拉取全部依靠,假如用户自己现现已过 apt 等第三方保证理装置了它们,Xmake 也会优先用系统现已装置的版别,省去下载装置进程。
也就是说,不管在哪个环境,用户都不需求关怀怎么去搭建内核驱动开发环境,仅仅只需求一个 xmake
指令,就能搞定全部。
而这些依靠拉取,都是经过 add_requires("linux-headers", {configs = {driver_modules = true}})
装备包来完成的。
别的,咱们也能够看完好构建指令参数。
$ xmake -v
[ 20%]: ccache compiling.release src/add.c
/usr/bin/ccache /usr/bin/gcc -c -m64 -O2 -std=gnu89 -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated -I/usr/src/linux-headers-5.11.0-41-generic/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -DCONFIG_X86_X32_ABI -isystem /usr/lib/gcc/x86_64-linux-gnu/10/include -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/kconfig.h -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/compiler_types.h -nostdinc -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -mindirect-branch=thunk-extern -mindirect-branch-register -mrecord-mcount -fmacro-prefix-map=./= -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -fcf-protection=none -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-allow-store-data-races -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -DKBUILD_BASENAME=\"add\" -o build/.objs/hello/linux/x86_64/release/src/add.c.o src/add.c
[ 20%]: ccache compiling.release src/hello.c
/usr/bin/ccache /usr/bin/gcc -c -m64 -O2 -std=gnu89 -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated -I/usr/src/linux-headers-5.11.0-41-generic/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -DCONFIG_X86_X32_ABI -isystem /usr/lib/gcc/x86_64-linux-gnu/10/include -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/kconfig.h -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/compiler_types.h -nostdinc -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -mindirect-branch=thunk-extern -mindirect-branch-register -mrecord-mcount -fmacro-prefix-map=./= -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -fcf-protection=none -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-allow-store-data-races -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -DKBUILD_BASENAME=\"hello\" -o build/.objs/hello/linux/x86_64/release/src/hello.c.o src/hello.c
[ 60%]: linking.release build/linux/x86_64/release/hello.ko
/usr/bin/ld -m elf_x86_64 -r -o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.o build/.objs/hello/linux/x86_64/release/src/add.c.o build/.objs/hello/linux/x86_64/release/src/hello.c.o
/usr/src/linux-headers-5.11.0-41-generic/scripts/mod/modpost -m -a -o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/Module.symvers -e -N -T -
WARNING: modpost: Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.
/usr/bin/ccache /usr/bin/gcc -c -m64 -O2 -std=gnu89 -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated -I/usr/src/linux-headers-5.11.0-41-generic/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -DCONFIG_X86_X32_ABI -isystem /usr/lib/gcc/x86_64-linux-gnu/10/include -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/kconfig.h -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/compiler_types.h -nostdinc -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -mindirect-branch=thunk-extern -mindirect-branch-register -mrecord-mcount -fmacro-prefix-map=./= -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -fcf-protection=none -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-allow-store-data-races -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.mod.o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.mod.c
/usr/bin/ld -m elf_x86_64 -r --build-id=sha1 -T /usr/src/linux-headers-5.11.0-41-generic/scripts/module.lds -o build/linux/x86_64/release/hello.ko build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.mod.o
运用特定版别的内核源码
咱们也能够指定版别语义规矩,选取自己需求的内核源码作为构建源。
add_requires("linux-headers 5.9.x", {configs = {driver_modules = true}})
穿插编译
咱们也支撑内核驱动模块的穿插编译,比方在 Linux x86_64 上运用穿插编译东西链来构建 Linux Arm/Arm64 的驱动模块。
咱们只需求准备好自己的穿插编译东西链,经过 --sdk=
指定它的根目录,然后装备切换到 -p cross
渠道, 最终指定需求构建的架构 arm/arm64 即可。
同样的,咱们不必关怀怎么准备 linux-headers 去支撑穿插编译,Xmake 的依靠保证理会帮你准本好全部,拉取构建支撑对应架构的内核源码。
这儿用到的穿插东西链,能够从这儿下载: Download toolchains
更多,穿插编译装备文档,见:装备穿插编译
注:现在仅仅支撑 arm/arm64 穿插编译架构,后续会支撑更多的渠道架构。
构建 Arm 驱动模块
$ xmake f -p cross -a arm --sdk=/mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf -c
$ xmake
[ 20%]: ccache compiling.release src/add.c
[ 20%]: ccache compiling.release src/hello.c
[ 60%]: linking.release build/cross/arm/release/hello.ko
[100%]: build ok!
构建 Arm64 驱动模块
$ xmake f -p cross -a arm64 --sdk=/mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu -c
$ xmake
[ 20%]: ccache compiling.release src/add.c
[ 20%]: ccache compiling.release src/hello.c
[ 60%]: linking.release build/cross/arm64/release/hello.ko
[100%]: build ok!
分组批量构建和运转支撑
前期,咱们现已支撑了经过 set_group
设置方针分组,完成 vs/vsxmake 工程在 vs 下的源文件分组办理展示。
可是,这个分组仅限于这个特性,没有用于其他地方,而新版别中,咱们继续改善运用分组特性,完成指定构建一批方针程序,以及批量运转一批方针程序。
这一般有什么用呢,比方能够用来供给 Run all tests
和 Run all benchmarks
等功用。
编译指定一批方针程序
咱们能够运用 set_group()
将给定的方针标记为 test/benchmark/...
并运用 set_default(false)
禁用来默许构建它。
这样,默许情况下 Xmake 不会去构建它们,可是咱们能够经过 xmake -g xxx
指令就能指定构建一批方针程序了。
比方,咱们能够运用此功用来构建全部测验。
target("test1")
set_kind("binary")
set_default(false)
set_group("test")
add_files("src/*.cpp")
target("test2")
set_kind("binary")
set_default(false)
set_group("test")
add_files("src/*.cpp")
$ xmake -g test
$ xmake --group=test
运转指定一批方针程序
咱们也能够经过设置分组,来指定运转全部带有 test
分组的测验程序。
这一般十分有用,在此之前想要完成 Run all tests
功用,咱们只能经过界说一个 task("tests")
在里面调用 os.exec
去挨个履行测验方针,装备比较繁琐,对用户要求比较高。
而现在,咱们只需求对需求履行的测验方针程序标记为 set_group("test")
,然后就能够批量运转它们了。
$ xmake run -g test
$ xmake run --group=test
支撑分组形式匹配
别的,咱们还能够支撑分组的形式匹配,十分的灵敏:
$ xmake build -g test_*
$ xmake run -g test/foo_*
$ xmake build -g bench*
$ xmake run -g bench*
更多信息见:#1913
改善 CMake 包源的查找和集成
之前的版别中,咱们供给了 find_package("cmake::xxx")
来查找 cmake 内部的包,可是这种方法对于用户集成运用仍是很繁琐。
因而,新版别中,咱们进一步改善它,经过 add_requires
来完成统一快速的 cmake 包集成。
add_requires("cmake::ZLIB", {alias = "zlib", system = true})
target("test")
set_kind("binary")
add_files("src/*.c")
add_packages("zlib")
咱们指定 system = true
告知 xmake 强制从系统中调用 cmake 查找包,假如找不到,不再走装置逻辑,由于 cmake 没有供给类似 vcpkg/conan 等保证理器的装置功用,
只供给了包查找特性。
指定版别
add_requires("cmake::OpenCV 4.1.1", {system = true})
指定组件
add_requires("cmake::Boost", {system = true, configs = {components = {"regex", "system"}})}
预设开关
add_requires("cmake::Boost", {system = true, configs = {components = {"regex", "system"},
presets = {Boost_USE_STATIC_LIB = true}}})
相当于内部调用 find_package 查找包之前,在 CMakeLists.txt 中预界说一些装备,控制 find_package 的查找战略和状态。
set(Boost_USE_STATIC_LIB ON) -- will be used in FindBoost.cmake
find_package(Boost REQUIRED COMPONENTS regex system)
设置环境变量
add_requires("cmake::OpenCV", {system = true, configs = {envs = {CMAKE_PREFIX_PATH = "xxx"}}})
指定自界说 FindFoo.cmake 模块脚本目录
mydir/cmake_modules/FindFoo.cmake
add_requires("cmake::Foo", {system = true, configs = {moduledirs = "mydir/cmake_modules"}})
相关 issues: #1632
xmake-idea 插件更新
xmake-idea 这个插件由于个人时刻和精力的联系,一直没有花时刻去维护更新,而 IDEA 插件的兼容性问题有十分多,只需一段时刻不必,就无法在新的 Idea/Clion 上正常运用。
最近,我花了点时刻,修正了一些兼容性问题,比方 Windows 上创立工程会卡死的问题,新版别 Clion 无法装置等问题。
现在,最新版别应该能够在全渠道正常运用了。
别的一些值得提起的事情
年终总结
这是 2021 年我发布的最终一个版别,这一年下来,阅历了很多,Xmake 也在逐步生长为一个愈加强壮的构建东西。
到今年年底,Xmake 一共收成了 4.2k stars,处理了 1.9k 的 issues/pr,超过 8k 多次 commits。
而官方的保证理库房 xmake-repo 也现已收录了近 500+ 的常用依靠包。
感谢
感谢各位奉献者对 xmake-repo 库房 和 Xmake 的奉献,完好奉献者列表见:Contributors。
也十分感谢大家对 Xmake 的赞助的支撑,使得我能够有满足的动力去继续维护,完好捐助列表见:Sponsors。
更新内容
新特性
- #1902: 支撑构建 linux 内核驱动模块
- #1913: 经过 group 形式匹配,指定构建和运转一批方针程序
改善
- #1872: 支撑转义 set_configvar 中字符串值
- #1888: 改善 windows 装置器,防止错误删除其他装置目录下的文件
-
#1895: 改善
plugin.vsxmake.autoupdate
规矩 - #1893: 改善勘探 icc 和 ifort 东西链
- #1905: 改善 msvc 对 external 头文件搜索勘探支撑
- #1904: 改善 vs201x 工程生成器
- 增加
XMAKE_THEME
环境变量去切换主题装备 -
#1907: 增加
-f/--force
参数使得xmake create
能够在费控目录被强制创立 - #1917: 改善 find_package 和装备
Bugs 修正
- #1885: 修正 package:fetch_linkdeps 链接次序问题
- #1903: 修正包链接次序