xmake v2.5.1 發佈, 支持 Apple Silicon 並改進 C/C++ 包依賴管理

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

這是 xmake 在今年的首個版本,也是徹底適配支持 Apple Silicon (macOS ARM) 設備的首個版本。c++

這個版本,咱們主要改進了對 C/C++ 依賴包的集成支持,更加的穩定,而且可以更加靈活的實現定製化配置編譯。git

另外,咱們還重點改進 vs/vsxmake 兩個vs工程生成器插件,修復了不少細節問題,而且對子工程分組也作了支持,如今能夠生成相似下圖的工程結構。github

關於 Zig 方面,0.7.1 版本修復了不少我以前反饋的問題,如今 xmake 也已經能夠很好的支持對 zig 項目的編譯。web

同時,咱們還新開發了一個 luarocks=build-xmake 插件去用 xmake 替換 luarocks 內置的構建系統。macos

最後,在這個版本中,咱們繼續改進了 xmake f --menu 圖形化配置菜單,徹底支持鼠標操做和滾動支持,也對 utf8 作了支持。windows

新特性介紹

新增 add_requireconfs 改進包配置

儘管以前的版本,咱們能夠經過 add_requires("libpng", {configs = {shared = true}}) 的方式來定義和配置依賴包。xcode

可是,若是用戶項目的工程龐大,依賴包很是多,且每一個包都須要不一樣的編譯配置參數,那麼配置起來仍是會很是繁瑣,而且具備侷限性,好比沒法改寫內部的子依賴包配置。bash

所以,咱們新增了 add_requireconfs 去更靈活方便的配置每一個包的配置以及它的子依賴,下面咱們重點介紹幾種用法:markdown

擴充指定包的配置

這是基本用法,好比咱們已經經過 add_requires("zlib") 聲明瞭一個包,想要在後面對這個 zlib 的配置進行擴展,改爲動態庫編譯,能夠經過下面的方式配置。

add_requires("zlib")
add_requireconfs("zlib", {configs = {shared = true}})
複製代碼

它等價於

add_requires("zlib", {configs = {shared = true}})
複製代碼
設置通用的默認配置

上面的用法,咱們還看不出有什麼實際用處,但若是依賴多了就能看出效果了,好比下面這樣:

add_requires("zlib", {configs = {shared = true}})
add_requires("pcre", {configs = {shared = true}})
add_requires("libpng", {configs = {shared = true}})
add_requires("libwebp", {configs = {shared = true}})
add_requires("libcurl", {configs = {shared = false}})
複製代碼

是否是很是繁瑣,若是咱們用上 add_requireconfs 來設置默認配置,就能夠極大的簡化成下面的配置:

add_requireconfs("*", {configs = {shared = true}})
add_requires("zlib")
add_requires("pcre")
add_requires("libpng")
add_requires("libwebp")
add_requires("libcurl", {configs = {shared = false}})
複製代碼

上面的配置,咱們經過 add_requireconfs("*", {configs = {shared = true}}) 使用模式匹配的方式,設置全部的依賴包默認走動態庫編譯安裝。

可是,咱們又經過 add_requires("libcurl", {configs = {shared = false}}) 將 libcurl 進行了特殊配置,強制走靜態庫編譯安裝。

最終的配置結果爲:zlib/pcre/libpng/libwebp 是 shared 庫,libcurl 是靜態庫。

咱們經過模式匹配的方式,能夠將一些每一個包的經常使用配置都放置到統一的 add_requireconfs 中去預先配置好,極大簡化每一個 add_requires 的定義。

!> 默認狀況下,對於相同的配置,xmake 會優先使用 add_requires 中的配置,而不是 add_requireconfs。

若是 add_requires("zlib 1.2.11") 中設置了版本,就會優先使用 add_requires 的配置,徹底忽略 add_requireconfs 裏面的版本配置,固然咱們也能夠經過 override 來徹底重寫 add_requires 中指定的版本。

add_requires("zlib 1.2.11")
add_requireconfs("zlib", {override = true, version = "1.2.10"})
複製代碼
改寫包依賴配置

其實 add_requireconfs 最大的用處是可讓用戶改寫安裝包的特定依賴包的配置。

什麼意思呢,好比咱們項目中集成使用 libpng 這個包,而且使用了動態庫版本,可是 libpng 內部依賴的 zlib 庫其實仍是靜態庫版本。

add_requires("libpng", {configs = {shared = true}})
複製代碼

那若是咱們想讓 libpng 依賴的 zlib 包也改爲動態庫編譯,應該怎麼配置呢?這就須要 add_requireconfs 了。

add_requires("libpng", {configs = {shared = true}})
add_requireconfs("libpng.zlib", {configs = {shared = true}})
複製代碼

經過 libpng.zlib 依賴路徑的寫法,指定內部某個依賴,改寫內部依賴配置。

若是依賴路徑很深,好比 foo -> bar -> xyz 的依賴鏈,咱們能夠寫成:foo.bar.xyz

咱們也能夠改寫 libpng 依賴的內部 zlib 庫版本:

add_requires("libpng")
add_requireconfs("libpng.zlib", {version = "1.2.10"})
複製代碼
級聯依賴的模式匹配

若是一個包的依賴很是多,且依賴層次也很深,怎麼辦呢,好比 libwebp 這個包,它的依賴有:

libwebp
  - libpng
    - zlib
    - cmake
  - libjpeg
  - libtiff
    - zlib
  - giflib
  - cmake
複製代碼

若是我想改寫 libwebp 裏面的全部的依賴庫都加上特定配置,那麼挨個配置,就會很是繁瑣,這個時候就須要 add_requireconfs() 的遞歸依賴模式匹配來支持了。

add_requires("libwebp")
add_requireconfs("libwebp.**|cmake", {configs = {cxflags = "-DTEST"}})
複製代碼

上面的配置,咱們將 libwebp 中因此的庫依賴就額外加上了 -DTEST 來編譯,可是 cmake 依賴屬於構建工具依賴,咱們能夠經過 |xxx 的方式排除它。

這裏的模式匹配寫法,與 add_files() 很是相似。

咱們在給幾個例子,好比這回咱們只改寫 libwebp 下單級的依賴配置,啓用調試庫:

add_requires("libwebp")
add_requireconfs("libwebp.*|cmake", {debug = true})
複製代碼

圖形化配置支持鼠標和滾動操做

咱們升級了 xmake 所使用的 tui 組件庫:LTUI,增長了對鼠標的支持,以及部分組件的滾動支持,咱們能夠再圖形化配置中,更加靈活方便的配置編譯選項。

stdin 重定向輸入支持

以前的版本中,xmake 提供的 os.execv/os.runv 等進程執行接口,僅僅只支持 stdout/stderr 輸出重定向,可是並不支持 stdin 輸入重定向,所以在這個版本中,咱們對其也作了支持。

使用方式以下:

os.execv("foo", {"arg1", "arg2"}, {stdin = "/tmp/a"})
複製代碼

咱們能夠執行進程的時候,將 /tmp/a 文件做爲重定向輸入,固然咱們還能夠傳遞 {stdout = "/tmp/out"} 等做爲重定向輸出。

vs 工程分組支持

咱們新增了一個接口 set_group,來對每一個 target 進行分組支持,此接口目前僅用於 vs/vsxmake 工程生成,對 vs 工程內部子工程目錄樹按指定結構分組展現,不事後續也可能對其餘模塊增長分組支持。

好比對於下面的分組配置:

add_rules("mode.debug", "mode.release")

target("test1")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group1")

target("test2")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group1")

target("test3")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group1/group2")

target("test4")
    set_kind("binary")
    add_files("src/*.cpp")
    set_group("group3/group4")

target("test5")
    set_kind("binary")
    add_files("src/*.cpp")

target("test6")
    set_kind("binary")
    add_files("src/*.cpp")
複製代碼

生成的 vs 工程目錄結構效果以下:

其中 set_group("group1/group2") 能夠將 target 設置到二級分組中去。

vs 工程自動更新規則

若是以爲每次經過 xmake project -k vsxmake 命令來生成和更新 vs 工程很繁瑣,咱們如今能夠經過在 xmake.lua 中配置 plugin.vsxmake.autoupdate 規則來實現自動更新。

用戶能夠在 vs 工程中每次執行構建後,若是文件列表或者 xmake.lua 有改動,vs 工程都會自動更新。

add_rules("plugin.vsxmake.autoupdate")

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

vs/vsxmake 工程插件改進

除了上面提到的分組支持和自動更新,這個版本中,咱們還修復了很多 vs 工程相關的問題,好比:intellisense 提示改進,路徑被截斷的問題修復,全面支持遠程依賴包

改進 windows 註冊表支持

xmake 改進了內部的 winos 模塊,新增了一些接口來更加方便的訪問註冊表,獲取 windows 上的註冊表配置。

winos.registry_keys

  • 獲取註冊表建列表

支持經過模式匹配的方式,遍歷獲取註冊表鍵路徑列表,* 爲單級路徑匹配,** 爲遞歸路徑匹配。

local keypaths = winos.registry_keys("HKEY_LOCAL_MACHINE\\SOFTWARE\\*\\Windows NT\\*\\CurrentVersion\\AeDebug")
for _, keypath in ipairs(keypaths) do
    print(winos.registry_query(keypath .. ";Debugger"))
end
複製代碼

winos.registry_values

  • 獲取註冊表值名列表

支持經過模式匹配的方式,獲取指定鍵路徑的值名列表,; 以後的就是指定的鍵名模式匹配字符串。

local valuepaths = winos.registry_values("HKEY_LOCAL_MACHINE\\SOFTWARE\\xx\\AeDebug;Debug*")
for _, valuepath in ipairs(valuepaths) do
    print(winos.registry_query(valuepath))
end
複製代碼

winos.registry_query

  • 獲取註冊表建值

獲取指定註冊表建路徑下的值,若是沒有指定值名,那麼獲取鍵路徑默認值

local value, errors = winos.registry_query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug")
local value, errors = winos.registry_query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger")
複製代碼

Zig 項目構建支持

在上個版本中,xmake 已經對 zig 進行了實驗性支持,可是期間也躺了很多坑,尤爲是 windows/macos 上構建中遇到了很多問題。

而後在最新的 zig 0.7.1 中,已經將我遇到的大部分問題都修復了,如今 xmake 已經能夠很好的支持 zig 項目編譯。

咱們能夠經過下面的命令,快速建立一個 Zig 空工程:

$ xmake create -l zig console
複製代碼

xmake.lua 內容以下:

add_rules("mode.debug", "mode.release")

target("console")
    set_kind("binary")
    add_files("src/*.zig")
複製代碼

能夠看到,其實配置方式跟 C/C++ 並無什麼不一樣,因爲 Zig 和 C 有很好的二進制兼容,所以咱們也可使用 add_requires 來給 zig 項目添加 C/C++ 包的遠程依賴支持。

而後執行 xmake 就能夠完成編譯了。

$ xmake
複製代碼

而後繼續運行 run 命令,就能夠直接執行 zig 程序,輸出運行結果。

$ xmake run
Hello world!
複製代碼

咱們還能夠很方便的實現 C 和 Zig 的混合編譯支持,只須要添加上對應的 C 代碼文件就能夠了。

add_rules("mode.debug", "mode.release")

target("console")
    set_kind("binary")
    add_files("src/*.zig", "src/*.c")
複製代碼

完整代碼例子見:Zig with C

Luarocks 插件

luarocks 是 lua 的一個包管理工具,提供了各類 lua 模塊的安裝集成,不過它自己在對 lua c 模塊進行構建是採用的內建的構建機制。

好比在它的 rockspec 文件中經過 builtin 構建類型來描述經常使用 lua c 模塊的構建:

build = {
    type = "builtin",
    modules = {
        ["module.hello"] = {
            sources = "src/test.c"
        }
    },
    copy_directories = {}
}
複製代碼

這對於小模塊而言,並無什麼問題,但若是模塊的 c 代碼結構比較複雜,它內置的構建規則仍是有不少的侷限性,並不靈活,另外切換 msvc / mingw 工具鏈以及參數配置什麼的都不夠靈活。

所以,xmake 提供了 luarocks=build-xmake 插件去替換 luarocks 內置的構建系統,替換方式也很簡單,只須要將 builtin 構建類型改爲 xmake,並加上 luarocks-build-xmake 依賴就好了。

dependencies = {
    "lua >= 5.1",
    "luarocks-build-xmake"
}
build = {
    type = "xmake",
    modules = {
        ["module.hello"] = {
            sources = "src/test.c"
        }
    },
    copy_directories = {}
}
複製代碼

可是這樣仍是很繁瑣,仍是要基於 rockspec 文件中 modules 中的源文件列表來描述規則,而後 luarocks-build-xmake 會自動根據配置生成 xmake.lua 來完成構建。

不過既然用了 xmake,那麼本身的 lua 模塊,徹底能夠用 xmake.lua 來維護,這樣構建配置就更加靈活了,所以咱們只須要下面這樣就好了。

dependencies = {
    "lua >= 5.1",
    "luarocks-build-xmake"
}
build = {
    type = "xmake",
    copy_directories = {}
}
複製代碼

只須要設置當前切換到 xmake 編譯,徹底使用 lua 模塊項目內置的 xmake.lua 規則文件。

支持在 windows 安裝部署 Qt 程序

很是感謝 @SirLynix 的貢獻,xmake 已經能夠支持在 windows 上部署安裝 Qt 應用程序。

咱們只須要正常維護一個 Qt 程序,例如:

add_rules("mode.debug", "mode.release")

target("demo")
    add_rules("qt.quickapp")
    add_headerfiles("src/*.h")
    add_files("src/*.cpp")
    add_files("src/qml.qrc")
複製代碼

而後,咱們只須要執行下面的編譯安裝命令,xmake 就會自動調用 windeployqt.exe 程序去安裝部署咱們的 Qt 應用。

$ xmake
$ xmake install -o d:\installdir
複製代碼

相關補丁:#1145

另外,在以前的版本中,xmake 也已經支持對 macOS 和 android 版本的 Qt 程序進行部署打包,每次只須要正常的編譯命令,就能夠生成 QT .app/.apk 安裝包。

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

一些問題修復

咱們還修復了很多用戶反饋的問題,這裏咱們介紹一些比較重要的 bug 修復,例如:

咱們修復了 add_defines("TEST=\"hello world\"") 中內部帶有空的雙引號問題,以前編譯會出錯。

另外咱們改進了 vstudio 環境的查找和支持,解決了用戶 home 目錄和環境變量中帶有中文致使的編譯失敗問題。

咱們也改進了 llvm 工具鏈,解決了 macOS 下若是沒有安裝 xcode 的狀況下,使用 llvm 工具鏈缺乏 isysroot 配置問題,以及 msvc 下頭文件依賴編譯偶爾失效問題。

更新內容

新特性

  • #1035: 圖形配置菜單完整支持鼠標事件,而且新增滾動欄
  • #1098: 支持傳遞 stdin 到 os.execv 進行輸入重定向
  • #1079: 爲 vsxmake 插件添加工程自動更新插件,add_rules("plugin.vsxmake.autoupdate")
  • 添加 xmake f --vs_runtime=MTset_runtimes("MT") 去更方便的對 target 和 package 進行設置
  • #1032: 支持枚舉註冊表 keys 和 values
  • #1026: 支持對 vs/vsmake 工程增長分組設置
  • #1178: 添加 add_requireconfs() 接口去重寫依賴包的配置
  • #1043: 爲 luarocks 模塊添加 luarocks.module 構建規則
  • #1190: 添加對 Apple Silicon (macOS ARM) 設備的支持
  • #1145: 支持在 windows 上安裝部署 Qt 程序, 感謝 @SirLynix

改進

  • #1072: 修復並改進 cl 編譯器頭文件依賴信息
  • 針對 ui 模塊和 xmake f --menu 增長 utf8 支持
  • 改進 zig 語言在 macOS 上的支持
  • #1135: 針對特定 target 改進多平臺多工具鏈同時配置支持
  • #1153: 改進 llvm 工具鏈,針對 macos 上編譯增長 isysroot 支持
  • #1071: 改進 vs/vsxmake 生成插件去支持遠程依賴包
  • 改進 vs/vsxmake 工程生成插件去支持全局的 set_arch() 設置
  • #1164: 改進 vsxmake 插件調試加載 console 程序
  • #1179: 改進 llvm 工具鏈,添加 isysroot

Bugs 修復

  • #1091: 修復不正確的繼承連接依賴
  • #1105: 修復 vsxmake 插件 c++ 語言標準智能提示錯誤
  • #1132: 修復 vsxmake 插件中配置路徑被截斷問題
  • #1142: 修復安裝包的時候,出現git找不到問題
  • 修復在 macOS Big Sur 上 macos.version 問題
  • #1084: 修復 add_defines() 中帶有雙引號和空格致使沒法正確處理宏定義的問題
  • #1195: 修復 unicode 編碼問題,改進 vs 環境查找和進程執行
相關文章
相關標籤/搜索