Xmake v2.8.7 發佈,新增 cosmocc 工具鏈支持,一次編譯到處運行

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 工具鏈支持

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

C++ Modules 改進

非常感謝 @Arthapz 對 C++ Modules 做了大量的改進工作,使得 xmake 更好地支持 C++ Modules 構建,也修復了很多已知的問題,例如 msys2/mingw 下對 C++ Modules 編譯支持等問題。

改進 xmake test

2.8.5 版本開始,我們增加了內置的測試命令:xmake test,我們只需要在需要測試的 target 上通過 add_tests 配置一些測試用例,就可以自動執行測試。

執行的效果如下:

ruki-2:test ruki$ xmake test
running tests ...
[  2%]: test_1/args        .................................... passed 7.000s
[  5%]: test_1/default     .................................... passed 5.000s
[  8%]: test_1/fail_output .................................... passed 5.000s
[ 11%]: test_1/pass_output .................................... passed 6.000s
[ 13%]: test_2/args        .................................... passed 7.000s
[ 16%]: test_2/default     .................................... passed 6.000s
[ 19%]: test_2/fail_output .................................... passed 6.000s
[ 22%]: test_2/pass_output .................................... passed 6.000s
[ 25%]: test_3/args        .................................... passed 7.000s
...
[ 77%]: test_7/pass_output .................................... failed 5.000s
[ 80%]: test_8/args        .................................... passed 7.000s
[ 83%]: test_8/default     .................................... passed 6.000s
[ 86%]: test_8/fail_output .................................... passed 6.000s
[ 88%]: test_8/pass_output .................................... failed 5.000s
[ 91%]: test_9/args        .................................... passed 6.000s
[ 94%]: test_9/default     .................................... passed 6.000s
[ 97%]: test_9/fail_output .................................... passed 6.000s
[100%]: test_9/pass_output .................................... passed 6.000s

80% tests passed, 7 tests failed out of 36, spent 0.242s

而新版本中,我們新增了對超時運行的測試支持。

如果一些測試程序長時間運行不退出,就會卡住,我們可以通過配置超時時間,強制退出,並返回失敗。

target("test_timeout")
    set_kind("binary")
    set_default(false)
    add_files("src/run_timeout.cpp")
    add_tests("run_timeout", {run_timeout = 1000})

上面的配置中,我們通過 {run_timeout = 1000} 可以配置指定的測試程序運行的超時時間,如果運行超時,就會作爲測試失敗。

$ xmake test
[100%]: test_timeout/run_timeout .................................... failed 1.006s
run failed, exit code: -1, exit error: wait process timeout

支持 Android NDK r26b

自從 Android NDK r26b 之後,NDK 對內部構建工具鏈的結構做了很大的改動,完全採用 llvm clang 來構建程序,因此新版本 xmake 對它做了一些適配,使得能夠繼續很好地支持新的 NDK。

改進運行時配置

另外,我們還改進了 set_runtimes 接口,除了先前已經支持的 MT/MD/MTd/MDd 等 windows msvc 的運行時庫配置,還新增了 c++_static, c++_shared, stdc++_static, stdc++_shared 等庫配置,

它們用於 clang/gcc 的 c++ 運行時庫配置。而對於 Android 平臺編譯, 我們也將已有的 xmake f --ndk_cxxstl= 等配置,也合併統一到 xmake f --runtimes= 中,與 set_runtimes 相對應。

除了設置,我們也可以在 target 中,通過 target:runtimes()target:has_runtime() 等接口去獲取和判斷當前的 runtimes 庫,在 package 中,也有一樣的接口可用。

例如:

target("test")
    add_files("src/*.cpp")
    on_load(function (target)
        if target:has_runtime("c++_shared", "c++_static") then
            -- TODO
        end
    end)

如果 c++_static 配置生效,在 Clang 編譯的時候,就會被自動添加 -stdlib=libc++ -static-libstdc++ 等 flags,而如果 stdc++_static 則對應 -stdlib=slibtdc++

改進腳本匹配模式

xmake 中的所有 on_xxx, before_xxxafter_xxx 等腳本配置接口,都可以在第一個參數中,設置腳本能夠被運行的平臺架構模式。

如果指定的模式和當前架構模式匹配,配置的腳本才能夠被執行,它的完整的過濾語法如下:plat|arch1,arch2@host|arch1,arch2

看上去非常的複雜,其實很簡單,其中每個階段都是可選的,可部分省略,對應:編譯平臺|編譯架構@主機平臺|主機架構

如果不設置任何平臺過濾條件,那麼默認全平臺支持,裏面的腳本對所有平臺生效,例如:

on_install(function (package)
    -- TODO
end)

如果安裝腳本對特定平臺生效,那麼直接指定對應的編譯平臺,可以同時指定多個:

on_install("linux", "macosx", function (package)
    -- TODO
end)

如果還要細分到指定架構才能生效,可以這麼寫:

on_install("linux|x86_64", "iphoneos|arm64", function (package)
    -- TODO
end)

如果還要限制執行的主機環境平臺和架構,可以在後面追加@host|arch,例如:

on_install("mingw@windows", function (package)
    -- TODO
end)

意思就是僅對windows下編譯mingw平臺生效。

我們也可以不指定比那一平臺和架構,僅設置主機平臺和架構,這通常用於描述一些跟編譯工具相關的依賴包,只能在主機環境運行。

例如,我們編譯的包,依賴了cmake,需要添加cmake的包描述,那麼裏面編譯安裝環境,只能是主機平臺:

on_install("@windows", "@linux", "@macosx", function (package)
    -- TODO
end)

其他一些例子:

-- `@linux`
-- `@linux|x86_64`
-- `@macosx,linux`
-- `android@macosx,linux`
-- `android|armeabi-v7a@macosx,linux`
-- `android|armeabi-v7a@macosx,linux|x86_64`
-- `android|armeabi-v7a@linux|x86_64`

而在 2.8.7 中,我們改進了模式匹配支持,新增排除指定平臺和架構,例如:

!plat|!arch@!subhost|!subarch
@!linux
@!linux|x86_64
@!macosx,!linux
!android@macosx,!linux
android|!armeabi-v7a@macosx,!linux
android|armeabi-v7a,!iphoneos@macosx,!linux|x86_64
!android|armeabi-v7a@!linux|!x86_64
!linux|*

同時,還提供了一個內置的 native 架構,用於匹配當前平臺的本地架構,主要用於指定或者排除交叉編譯平臺。

on_install("macosx|native", ...)

上面的配置,如果在 macOS x86_64 的設備上,它僅僅只會匹配 xmake f -a x86_64 的本地架構編譯。

如果是 xmake f -a arm64 交叉編譯,就不會被匹配到。

同理,如果只想匹配交叉編譯,可以使用 macosx|!native 進行取反排除就行了。

這個模式改進,其實主要用於倉庫包配置的簡化,更好的處理不同平臺下包安裝腳本的配置支持。

更新日誌

新特性

  • #4544: 改進 xmake test,支持等待進程超時
  • #4606: 爲 package 添加 add_versionfiles 接口
  • #4709: 添加 cosmocc 工具鏈支持
  • #4715: 在描述域添加 is_cross() 接口
  • #4747: 添加 build.always_update_configfiles 策略

改進

  • #4575: 檢測無效的域參數
  • 添加更多的 loong64 支持
  • 改進 dlang/dmd 對 frameworks 的支持
  • #4571: 改進 xmake test 的輸出支持
  • #4609: 改進探測 vs 構建工具環境
  • #4614: 改進支持 android ndk 26b
  • #4473: 默認啓用警告輸出
  • #4477: 改進 runtimes 去支持 libc++/libstdc++
  • #4657: 改進腳本的模式匹配
  • #4673: 重構模塊支持
  • #4746: 爲 cmake generator 添加原生 c++ modules 支持

Bugs 修復

  • #4596: 修復遠程構建緩存
  • #4689: 修復目標依賴繼承
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章