xmake v2.5.3 發佈,支持構建 linux bpf 程序和 Conda 包集成

xmake 是一個基於 Lua 的輕量級跨平臺構建工具,使用 xmake.lua 維護項目構建,相比 makefile/CMakeLists.txt,配置語法更加簡潔直觀,對新手很是友好,短期內就能快速入門,可以讓用戶把更多的精力集中在實際的項目開發上。linux

在 2.5.3 版本,咱們新增了對 linux bpf 程序的構建支持,而且同時支持 android bpf 程序的構建。android

儘管 bpf 對 編譯工具鏈有必定的要求,好比須要較新的 llvm/clang 和 android ndk 工具鏈,可是 xmake 可以自動拉取特定版本的 llvm/ndk 來用於編譯,而且還能自動拉取 libbpf 等依賴庫,徹底省去了用戶折騰編譯環境和 libbpf 庫集成的問題。ios

另外,在新版本中咱們還新增了對 Conda 包倉庫的集成支持,如今除了可以從 Conan/Vcpkg/brew/pacman/clib/dub 等包倉庫集成使用包,還能從 Conda 包倉庫中集成各類二進制 C/C++ 包。c++

新特性介紹

構建 Linux Bpf 程序

新版本,咱們開始支持 bpf 程序構建,同時支持 linux 以及 android 平臺,可以自動拉取 llvm 和 android ndk 工具鏈。git

更多詳情見:#1274es6

支持 linux 和 android 兩端構建的配置大概以下,若是咱們不須要構建 android 版本,能夠作一些刪減,配置會更加精簡:github

add_rules("mode.release", "mode.debug")
add_rules("platform.linux.bpf")

add_requires("linux-tools", {configs = {bpftool = true}})
add_requires("libbpf")
if is_plat("android") then
    add_requires("ndk >=22.x")
    set_toolchains("@ndk", {sdkver = "23"})
else
    add_requires("llvm >=10.x")
    set_toolchains("@llvm")
    add_requires("linux-headers")
end

target("minimal")
    set_kind("binary")
    add_files("src/*.c")
    add_packages("linux-tools", "linux-headers", "libbpf")
    set_license("GPL-2.0")
複製代碼

經過上面的配置,大概能夠看出,咱們集成配置了特定版本的 llvm 和 NDK 工具鏈,以及 libbpf, linux-headers, linux-tools 等包,xmake 都會去自動拉取它們,而後使用對應的工具鏈集成編譯這些依賴包,最後生成 bpf 程序。bootstrap

其中 linux-tools 包主要使用了裏面的 libtool 程序,用於生成 bpf skeleton 頭文件,xmake 也會自動調用這個工具去生成它。windows

編譯 linux bpf 程序

咱們只須要執行 xmake 命令便可完成編譯,即便你還沒安裝 llvm/clang,固然,若是你已經安裝了它們,若是版本匹配,xmake 也會去優先使用。api

$ xmake
複製代碼

咱們也能夠經過 xmake -v 來編譯而且查看完整詳細的編譯命令:

$ xmake -v
[ 20%]: compiling.bpf src/minimal.bpf.c
/usr/bin/ccache /usr/bin/clang -c -Qunused-arguments -m64 -fvisibility=hidden -O3 -Ibuild/.gens/minimal/linux/x86_64/release/rules/bpf -isystem /home/ruki/.xmake/packages/l/linux-tools/5.9.16/0c52e491268946fe9a4bc91d4906d66b/include -isystem /home/ruki/.xmake/packages/z/zlib/1.2.11/3a7e4427eda94fc69fad0009a1629fd8/include -isystem /home/ruki/.xmake/packages/l/libelf/0.8.13/ced4fdd8151a475dafc5f51e2a031997/include -isystem /home/ruki/.xmake/packages/l/libelf/0.8.13/ced4fdd8151a475dafc5f51e2a031997/include/libelf -isystem /home/ruki/.xmake/packages/l/libcap/2.27/c55b28aa3b3745489b93895d0d606ed1/include -isystem /home/ruki/.xmake/packages/l/linux-headers/5.9.16/8e3a440cbe1f42249aef3d89f1528ecb/include -DNDEBUG -target bpf -g -o build/.gens/minimal/linux/x86_64/release/rules/bpf/minimal.bpf.o src/minimal.bpf.c
llvm-strip -g build/.gens/minimal/linux/x86_64/release/rules/bpf/minimal.bpf.o
bpftool gen skeleton build/.gens/minimal/linux/x86_64/release/rules/bpf/minimal.bpf.o
[ 40%]: ccache compiling.release src/minimal.c
/usr/bin/ccache /usr/bin/clang -c -Qunused-arguments -m64 -fvisibility=hidden -O3 -Ibuild/.gens/minimal/linux/x86_64/release/rules/bpf -isystem /home/ruki/.xmake/packages/l/linux-tools/5.9.16/0c52e491268946fe9a4bc91d4906d66b/include -isystem /home/ruki/.xmake/packages/z/zlib/1.2.11/3a7e4427eda94fc69fad0009a1629fd8/include -isystem /home/ruki/.xmake/packages/l/libelf/0.8.13/ced4fdd8151a475dafc5f51e2a031997/include -isystem /home/ruki/.xmake/packages/l/libelf/0.8.13/ced4fdd8151a475dafc5f51e2a031997/include/libelf -isystem /home/ruki/.xmake/packages/l/libcap/2.27/c55b28aa3b3745489b93895d0d606ed1/include -isystem /home/ruki/.xmake/packages/l/linux-headers/5.9.16/8e3a440cbe1f42249aef3d89f1528ecb/include -DNDEBUG -o build/.objs/minimal/linux/x86_64/release/src/minimal.c.o src/minimal.c
[ 60%]: linking.release minimal
/usr/bin/clang++ -o build/linux/x86_64/release/minimal build/.objs/minimal/linux/x86_64/release/src/minimal.c.o -m64 -L/home/ruki/.xmake/packages/l/linux-tools/5.9.16/0c52e491268946fe9a4bc91d4906d66b/lib64 -L/home/ruki/.xmake/packages/z/zlib/1.2.11/3a7e4427eda94fc69fad0009a1629fd8/lib -L/home/ruki/.xmake/packages/l/libelf/0.8.13/ced4fdd8151a475dafc5f51e2a031997/lib -L/home/ruki/.xmake/packages/l/libcap/2.27/c55b28aa3b3745489b93895d0d606ed1/lib -s -lbpf -lz -lelf -lcap
[100%]: build ok!
複製代碼

編譯 Android bpf 程序

若是編譯 Android 版本,咱們也只須要切換到 android 平臺便可,同樣很方便

$ xmake f -p android
$ xmake
複製代碼

xmake 會去自動下來 ndk 工具鏈和對應 android 版本 libbpf 等庫來使用。

$ xmake f -p android -c
checking for architecture ... armeabi-v7a
checking for Android SDK directory ... no
checking for NDK directory ... no
note: try installing these packages (pass -y to skip confirm)?
in local-repo:
  -> libcap 2.27 [linux, x86_64, from:linux-tools]
  -> libelf 0.8.13 [linux, x86_64, from:linux-tools]
  -> zlib 1.2.11 [linux, x86_64, from:linux-tools]
  -> linux-tools 5.9.16 [bpftool:y]
  -> ndk 22.0
  -> libelf#1 0.8.13 [toolchains:@ndk, from:libbpf]
  -> zlib#1 1.2.11 [toolchains:@ndk, from:libbpf]
  -> libbpf v0.3 [toolchains:@ndk]
please input: y (y/n)

  => install libcap 2.27 .. ok
  => install zlib 1.2.11 .. ok
  => install libelf 0.8.13 .. ok
  => install ndk 22.0 .. ok
  => install linux-tools 5.9.16 .. ok
  => install libelf#1 0.8.13 .. ok
  => install zlib#1 1.2.11 .. ok
  => install libbpf v0.3 .. ok
ruki@010689392c4d:/mnt/bpf_minimal$ xmake
[ 20%]: compiling.bpf src/minimal.bpf.c
[ 40%]: ccache compiling.release src/minimal.c
[ 60%]: linking.release minimal
[100%]: build ok!
複製代碼

固然,若是你已經手動下載了對應版本的 ndk 工具鏈,咱們也能夠指定使用,再也不走自動拉取。

$ xmake f -p android --ndk=/xxx/android-ndk-r22
$ xmake
複製代碼

不過,若是本身下載的話,記得至少要下載 ndk r22 以上版本的,由於低版本 ndk 裏面的 clang 不支持編譯生成 bpf 程序。

最後,這裏有個完整的基於 xmake 的 bpf 腳手架工程,你們能夠參考下:github.com/hack0z/libb…

另外這裏也有個最小 bpf 例子程序:github.com/xmake-io/xm…

集成使用 Conda 包

Conda 是一個很強大的第三方包管理器,支持各類語言的二進制包拉取,這裏咱們僅僅使用裏面的 C/C++ 包。

它的集成使用方式跟 conan/vcpkg 相似,僅僅只是包命名空間改爲了 conda::

add_requires("conda::libpng 1.6.37", {alias = "libpng"})
add_requires("conda::openssl")
target("testco")
    set_kind("binary")
    add_files("src/*.cpp")
    add_packages("libpng", "conda::openssl")
複製代碼

注:雖然咱們支持不少的第三方包管理器,好比 conan/conda/vcpkg/brew 等等,可是 xmake 也有自建的包倉庫管理,目前已有將近 300 個經常使用包,支持不一樣的平臺,其中部分包還支持 android/ios/mingw 甚至交叉編譯環境。

所以,若是官方 xmake-repo 倉庫已經提供了須要的包,能夠直接使用,不須要指定包命名空間。xmake 對第三方包管理的支持僅僅是做爲補充,儘量複用已有 c/c++ 生態,避免生態碎片化。

獲取主機 cpu 信息

當前版本,咱們新增了一個 core.base.cpu 模塊和 os.cpuinfo 接口,用於獲取 cpu 的各類信息,好比:cpu family/model, microarchitecture,core number, features 等信息。

這一般在追求性能的項目中很是有用,這些項目一般須要根據CPU的內存模型和擴展指令集來優化,同時想要跨平臺的話,就須要根據當前cpu信息指定對應的代碼,(例如intel haswell以後一套,amd zen以後一套,更老的默認到沒有優化)。不少高性能計算庫裏面也會用到這些信息。

所以,經過這個模塊接口就能夠在編譯配置的時候獲取當前主機 cpu 的信息和特性支持力度,來針對性開啓相關優化編譯。

咱們能夠經過 os.cpuinfo() 快速獲取全部信息,也能夠指定 os.cpuinfo("march") 獲取特定信息,好比 march,也就是 microarchitecture

咱們也能夠經過 xmake l 命令來快速查看獲取結果。

$ xmake l os.cpuinfo
{
  features = "fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clfsh ds acpi mmx fxsr sse sse2 ss htt tm pbe sse3 pclmulqdq dtes64 mon dscpl vmx est tm2 ssse3 fma cx16 tpr pdcm sse4_1 sse4_2 x2apic movbe popcnt aes pcid xsave osxsave seglim64 tsctmr avx1_0 rdrand f16c",
  vendor = "GenuineIntel",
  model_name = "Intel(R) Core(TM) i7-8569U CPU @ 2.80GHz",
  family = 6,
  march = "Kaby Lake",
  model = 142,
  ncpu = 8
}

$ xmake l os.cpuinfo march
"Kaby Lake"

$ xmake l os.cpuinfo ncpu
8
複製代碼

若是要判斷 sse 等擴展特性支持,就得須要 import 導入 core.base.cpu 模塊來獲取了。

target("test")
    set_kind("binary")
    add_files("src/*.c")
    on_load(function (target)
        import("core.base.cpu")
        local ncpu = os.cpuinfo("ncpu")
        -- local ncpu = cpu.number()
        if cpu.has_feature("sse") then
            target:add("defines", "HAS_SSE")
        end
    end)
複製代碼

新增 cmake 導入文件規則

若是,咱們開發的是庫程序,在執行 xmake install 安裝到系統後,僅僅只安裝了庫文件,沒有 .cmake/.pc 等導入文件信息,所以 cmake 工程想經過 find_package 集成使用,一般是找不到咱們的庫。

爲了可以讓第三方 cmake 工程正常找到它並使用集成,那麼咱們可使用 utils.install.cmake_importfiles 規則在安裝 target 目標庫文件的時候,導出 .cmake 文件,用於其餘 cmake 項目的庫導入和查找。

咱們只須要經過 add_rules 接口應用此規則到指定的 target 庫目標便可。

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_rules("utils.install.cmake_importfiles")
複製代碼

配置以後,xmake install 安裝命令就可以自動導出 .cmake 導入文件。

新增 pkgconfig 導入文件規則

跟上面的 cmake 導入相似,只不過咱們這也能夠經過 utils.install.pkgconfig_importfiles 規則安裝 pkgconfig/.pc 導入文件,這對 autotools 等工具的庫探測很是有用。

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_rules("utils.install.pkgconfig_importfiles")
複製代碼

新增 Git 相關內置配置變量

xmake 一直有提供 config.h 的自動生成特性,能夠經過 add_configfiles 接口來配置,而且它還支持模板變量的替換,用戶能夠本身定義一些變量。

不過,xmake 也提供了一些經常使用的內置變量替換,好比 版本信息,平臺架構等。具體詳情見:xmake.io/#/manual/pr…

模板配置使用方式很簡單,只須要:

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_configfiles("src/config.h.in")
複製代碼

就能根據 config.h.in 自動生成 config.h 文件。

不過咱們這裏要講的新特性是最近新提供的 Git 相關內置變量,來讓用戶在項目編譯時候,快速方便的或者當前 git 項目最近的 tag/branch/commit 信息。

這對於後期排查定位問題很是有用,咱們能夠經過 commit 精肯定位問題庫是基於哪次 commit 提交致使的,這樣,咱們就能 checkout 但對應版原本排查問題。

咱們只須要在 config.h.in 中配置定義如下變量。

#define GIT_COMMIT "${GIT_COMMIT}"
#define GIT_COMMIT_LONG "${GIT_COMMIT_LONG}"
#define GIT_COMMIT_DATE "${GIT_COMMIT_DATE}"
#define GIT_BRANCH "${GIT_BRANCH}"
#define GIT_TAG "${GIT_TAG}"
#define GIT_TAG_LONG "${GIT_TAG_LONG}"
#define GIT_CUSTOM "${GIT_TAG}-${GIT_COMMIT}"
複製代碼

執行 xmake 編譯,就會自動生成以下 config.h 文件。

#define GIT_COMMIT "8c42b2c2"
#define GIT_COMMIT_LONG "8c42b2c251793861eb85ffdf7e7c2307b129c7ae"
#define GIT_COMMIT_DATE "20210121225744"
#define GIT_BRANCH "dev"
#define GIT_TAG "v1.6.6"
#define GIT_TAG_LONG "v1.6.6-0-g8c42b2c2"
#define GIT_CUSTOM "v1.6.6-8c42b2c2"
複製代碼

咱們就能夠在程序用經過宏定義的方式使用它們。

Android NDK r22 支持和遠程拉取

Android NDK 從 r22 以後,結構上作了很是大的改動,移除了一些被廢棄的目錄,好比 頂層的 sysroot 目錄 和 platforms 目錄,致使 xmake 以前的探測方式失效。

所以在新版本中,咱們對 xmake 作了改進來更好的支持全版本 NDK 工具鏈,包括 r22 以上的新版本。

同時 xmae-repo 官方倉庫也增長了對 ndk 包的收錄,使得 xmake 可以遠程拉取 ndk 工具鏈來使用。

add_requires("ndk >=22.x")
set_toolchains("@ndk", {sdkver = "23"})
target("test")
    set_kind("binary")
    add_files("src/*.c")
複製代碼

更新內容

新特性

  • #1259: 支持 add_files("*.def") 添加 def 文件去導出 windows/dll 符號
  • #1267: 添加 find_package("nvtx")
  • #1274: 添加 platform.linux.bpf 規則去構建 linux/bpf 程序
  • #1280: 支持 fetchonly 包去擴展改進 find_package
  • 支持自動拉取遠程 ndk 工具鏈包和集成
  • #1268: 添加 utils.install.pkgconfig_importfiles 規則去安裝 *.pc 文件
  • #1268: 添加 utils.install.cmake_importfiles 規則去安裝 *.cmake 導入文件
  • #348: 添加 platform.longpaths 策略去支持 git longpaths
  • #1314: 支持安裝使用 conda 包
  • #1120: 添加 core.base.cpu 模塊而且改進 os.cpuinfo()
  • #1325: 爲 add_configfiles 添加內建的 git 變量

改進

  • #1275: 改進 vsxmake 生成器,支持條件化編譯 targets
  • #1290: 增長對 Android ndk r22 以上版本支持
  • #1311: 爲 vsxmake 工程添加包 dll 路徑,確保調試運行加載正常

Bugs 修復

  • #1266: 修復在 add_repositories 中的 repo 相對路徑
  • #1288: 修復 vsxmake 插件處理 option 配置問題

tboox.org/cn/2021/04/…

相關文章
相關標籤/搜索