xmake的工程描述文件xmake.lua雖然基於lua語法,可是爲了使得更加方便簡潔得編寫項目構建邏輯,xmake對其進行了一層封裝,使得編寫xmake.lua不會像些makefile那樣繁瑣ios
基本上寫個簡單的工程構建描述,只需三行就能搞定,例如:git
target("test") set_kind("binary") add_files("src/*.c")
而後只須要執行編譯而且運行它:github
$ xmake run test
這對於想要臨時寫些測試代碼來說,極大地提高了開發效率。。編程
xmake的描述語法是按做用域劃分的,主要分爲:api
那哪些屬於外部,哪些又屬於內部呢,看看下面的註釋,就知道個大概了:安全
-- 外部做用域 target("test") -- 外部做用域 set_kind("binary") add_files("src/*.c") on_run(function () -- 內部做用域 end) after_package(function () -- 內部做用域 end) -- 外部做用域 task("hello") -- 外部做用域 on_run(function () -- 內部做用域 end)
簡單的說,就是在自定義腳本function () end
以內的都屬於內部做用域,也就是腳本做用域,其餘地方都是都屬於於外部做用域。。bash
對於大部分工程來講,並不須要很複雜的工程描述,也不須要自定義腳本支持,只須要簡單的 set_xxx
或者 add_xxx
就能知足需求了iphone
那麼根據二八定律,80%的狀況下,咱們只須要這麼寫:函數
target("test") set_kind("static") add_files("src/test/*.c") target("demo") add_deps("test") set_kind("binary") add_links("test") add_files("src/demo/*.c")
不須要複雜的api調用,也不須要各類繁瑣的變量定義,以及 if
判斷 和 for
循環,要的就是簡潔可讀,一眼看過去,就算不懂lua語法也不要緊測試
就當作簡單的描述語法,看上去有點像函數調用而已,會點編程的基本一看就知道怎麼配置。
爲了作到簡潔、安全,在這個做用域內,不少lua 內置api是不開放出來的,尤爲是跟寫文件、修改操做環境相關的,僅僅提供一些基本的只讀接口,和邏輯操做
目前外部做用域開放的lua內置api有:
固然雖然內置lua api提供很少,但xmake還提供了不少擴展api,像描述api就很少說,詳細可參考:工程描述api文檔
還有些輔助api,例如:
還有變量定義、邏輯操做也是可使用的,畢竟是基於lua的,該有的基礎語法,仍是要有的,咱們能夠經過if來切換編譯文件:
target("test") set_kind("static") if is_plat("iphoneos") then add_files("src/test/ios/*.c") else add_files("src/test/*.c") end
咱們也能夠啓用和禁用某個子工程target:
if is_arch("arm*") then target("test1") set_kind("static") add_files("src/*.c") else target("test2") set_kind("static") add_files("src/*.c") end
須要注意的是,變量定義分全局變量和局部變量,局部變量只對當前xmake.lua有效,不影響子xmake.lua
-- 局部變量,只對當前xmake.lua有效 local var1 = 0 -- 全局變量,影響全部以後 add_subfiles(), add_subdirs() 包含的子 xmake.lua var2 = 1 add_subdirs("src")
也稱插件、腳本做用域,提供更加複雜、靈活的腳本支持,通常用於編寫一些自定義腳本、插件開發、自定義task任務、自定義模塊等等
通常經過 function () end
包含,而且被傳入到 on_xxx
, before_xxx
和after_xxx
接口內的,都屬於自做用域。
例如:
-- 自定義腳本 target("hello") after_build(function () -- 內部做用域 end) -- 自定義任務、插件 task("hello") on_run(function () -- 內部做用域 end)
在此做用域中,不只可使用大部分lua的api,還可使用不少xmake提供的擴展模塊,全部擴展模塊,經過import
來導入
具體可參考:插件開發之import類庫
這裏咱們給個簡單的例子,在編譯完成後,對ios目標程序進行ldid簽名:
target("iosdemo") set_kind("binary") add_files("*.m") after_build( function (target) -- 執行簽名,若是失敗,自動中斷,給出高亮錯誤信息 os.run("ldid -S$(projectdir)/entitlements.plist %s", target:targetfile()) end)
須要注意的是,在內部做用域中,全部的調用都是啓用異常捕獲機制的,若是運行出錯,會自動中斷xmake,並給出錯誤提示信息
所以,腳本寫起來,不須要繁瑣的if retval then
判斷,腳本邏輯更加一目瞭然
在外部做用域中的全部描述api設置,自己也是有做用域之分的,在不一樣地方調用,影響範圍也不相同,例如:
-- 全局根做用域,影響全部target,包括 add_subdirs() 中的子工程target設置 add_defines("DEBUG") -- 定義或者進入demo目標做用域(支持屢次進入來追加設置) target("demo") set_kind("shared") add_files("src/*.c") -- 當前target做用域,僅僅影響當前target add_defines("DEBUG2") -- 選項設置,僅支持局部設置,不受全局api設置所影響 option("test") -- 當前選項的局部做用域 set_default(false) -- 其餘target設置,-DDEBUG 也會被設置上 target("demo2") set_kind("binary") add_files("src/*.c") -- 從新進入demo目標做用域 target("demo") -- 追加宏定義,只對當前demo目標有效 add_defines("DEBUG3")
xmake裏面還有些全局api,僅提供全局做用域支持,例如:
等等,這些調用不要放置在 target 或者 option 的局部做用域之間,雖然沒什麼實際區別,可是會影響可讀性,容易被誤導
使用方式,以下:
target("xxxx") set_kind("binary") add_files("*.c") -- 包含子模塊文件 add_subdirs("src")
xmake.lua裏面縮進,只是個編寫規範,用於更加清楚的區分,當前的設置 是針對 那個做用域的,雖然就算不縮進,也同樣ok,可是可讀性上 並非很好。。
例如:
target("xxxx") set_kind("binary") add_files("*.c")
和
target("xxxx") set_kind("binary") add_files("*.c")
上述兩種方式,效果上都是同樣的,可是理解上,第一種更加直觀,一看就知道 add_files 僅僅只是針對 target 設置的,並非全局設置
所以,適當的進行縮進,有助於更好的維護xmake.lua
最後附上,tbox的xmake.lua和src/tbox/xmake.lua描述,僅供參考。。