xmake的工程描述文件xmake.lua雖然基于lua語(yǔ)法,但是為了使得更加方便簡(jiǎn)潔得編寫項(xiàng)目構(gòu)建邏輯假勿,xmake對(duì)其進(jìn)行了一層封裝忌愚,使得編寫xmake.lua不會(huì)像些makefile那樣繁瑣
基本上寫個(gè)簡(jiǎn)單的工程構(gòu)建描述旬蟋,只需三行就能搞定,例如:
target("test")
set_kind("binary")
add_files("src/*.c")
然后只需要執(zhí)行編譯并且運(yùn)行它:
$ xmake run test
這對(duì)于想要臨時(shí)寫些測(cè)試代碼來(lái)講敬肚,極大地提升了開發(fā)效率毕荐。。
作用域與工程描述語(yǔ)法
xmake的描述語(yǔ)法是按作用域劃分的艳馒,主要分為:
- 外部作用域
- 內(nèi)部作用域
那哪些屬于外部憎亚,哪些又屬于內(nèi)部呢,看看下面的注釋弄慰,就知道個(gè)大概了:
-- 外部作用域
target("test")
-- 外部作用域
set_kind("binary")
add_files("src/*.c")
on_run(function ()
-- 內(nèi)部作用域
end)
after_package(function ()
-- 內(nèi)部作用域
end)
-- 外部作用域
task("hello")
-- 外部作用域
on_run(function ()
-- 內(nèi)部作用域
end)
簡(jiǎn)單的說(shuō)第美,就是在自定義腳本function () end
之內(nèi)的都屬于內(nèi)部作用域,也就是腳本作用域陆爽,其他地方都是都屬于于外部作用域什往。。
外部作用域
對(duì)于大部分工程來(lái)說(shuō)慌闭,并不需要很復(fù)雜的工程描述别威,也不需要自定義腳本支持,只需要簡(jiǎn)單的 set_xxx
或者 add_xxx
就能滿足需求了
那么根據(jù)二八定律驴剔,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")
不需要復(fù)雜的api調(diào)用,也不需要各種繁瑣的變量定義丧失,以及 if
判斷 和 for
循環(huán)豺妓,要的就是簡(jiǎn)潔可讀,一眼看過(guò)去,就算不懂lua語(yǔ)法也沒(méi)關(guān)系
就當(dāng)做簡(jiǎn)單的描述語(yǔ)法琳拭,看上去有點(diǎn)像函數(shù)調(diào)用而已训堆,會(huì)點(diǎn)編程的基本一看就知道怎么配置。
為了做到簡(jiǎn)潔白嘁、安全坑鱼,在這個(gè)作用域內(nèi),很多l(xiāng)ua 內(nèi)置api是不開放出來(lái)的权薯,尤其是跟寫文件姑躲、修改操作環(huán)境相關(guān)的睡扬,僅僅提供一些基本的只讀接口盟蚣,和邏輯操作
目前外部作用域開放的lua內(nèi)置api有:
- table
- string
- pairs
- ipairs
- print:修改版,提供格式化打印支持
- os:僅提供只讀接口卖怜,例如getenv等等
當(dāng)然雖然內(nèi)置lua api提供不多屎开,但xmake還提供了很多擴(kuò)展api,像描述api就不多說(shuō)马靠,詳細(xì)可參考:工程描述api文檔
還有些輔助api奄抽,例如:
- dirs:掃描獲取當(dāng)前指定路徑中的所有目錄
- files:掃描獲取當(dāng)前指定路徑中的所有文件
- format: 格式化字符串,string.format的簡(jiǎn)寫版本
還有變量定義甩鳄、邏輯操作也是可以使用的逞度,畢竟是基于lua的,該有的基礎(chǔ)語(yǔ)法妙啃,還是要有的档泽,我們可以通過(guò)if來(lái)切換編譯文件:
target("test")
set_kind("static")
if is_plat("iphoneos") then
add_files("src/test/ios/*.c")
else
add_files("src/test/*.c")
end
我們也可以啟用和禁用某個(gè)子工程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
需要注意的是,變量定義分全局變量和局部變量揖赴,局部變量只對(duì)當(dāng)前xmake.lua有效馆匿,不影響子xmake.lua
-- 局部變量,只對(duì)當(dāng)前xmake.lua有效
local var1 = 0
-- 全局變量燥滑,影響所有之后 add_subfiles(), add_subdirs() 包含的子 xmake.lua
var2 = 1
add_subdirs("src")
內(nèi)部作用域
也稱插件渐北、腳本作用域,提供更加復(fù)雜铭拧、靈活的腳本支持赃蛛,一般用于編寫一些自定義腳本、插件開發(fā)搀菩、自定義task任務(wù)呕臂、自定義模塊等等
一般通過(guò) function () end
包含,并且被傳入到 on_xxx
, before_xxx
和after_xxx
接口內(nèi)的秕磷,都屬于自作用域诵闭。
例如:
-- 自定義腳本
target("hello")
after_build(function ()
-- 內(nèi)部作用域
end)
-- 自定義任務(wù)、插件
task("hello")
on_run(function ()
-- 內(nèi)部作用域
end)
在此作用域中,不僅可以使用大部分lua的api疏尿,還可以使用很多xmake提供的擴(kuò)展模塊瘟芝,所有擴(kuò)展模塊,通過(guò)import
來(lái)導(dǎo)入
具體可參考:插件開發(fā)之import類庫(kù)
這里我們給個(gè)簡(jiǎn)單的例子褥琐,在編譯完成后锌俱,對(duì)ios目標(biāo)程序進(jìn)行l(wèi)did簽名:
target("iosdemo")
set_kind("binary")
add_files("*.m")
after_build( function (target)
-- 執(zhí)行簽名,如果失敗敌呈,自動(dòng)中斷贸宏,給出高亮錯(cuò)誤信息
os.run("ldid -S$(projectdir)/entitlements.plist %s", target:targetfile())
end)
需要注意的是,在內(nèi)部作用域中磕洪,所有的調(diào)用都是啟用異常捕獲機(jī)制的吭练,如果運(yùn)行出錯(cuò),會(huì)自動(dòng)中斷xmake析显,并給出錯(cuò)誤提示信息
因此鲫咽,腳本寫起來(lái),不需要繁瑣的if retval then
判斷谷异,腳本邏輯更加一目了然
接口作用域
在外部作用域中的所有描述api設(shè)置分尸,本身也是有作用域之分的,在不同地方調(diào)用歹嘹,影響范圍也不相同箩绍,例如:
-- 全局根作用域,影響所有target尺上,包括 add_subdirs() 中的子工程target設(shè)置
add_defines("DEBUG")
-- 定義或者進(jìn)入demo目標(biāo)作用域(支持多次進(jìn)入來(lái)追加設(shè)置)
target("demo")
set_kind("shared")
add_files("src/*.c")
-- 當(dāng)前target作用域材蛛,僅僅影響當(dāng)前target
add_defines("DEBUG2")
-- 選項(xiàng)設(shè)置,僅支持局部設(shè)置尖昏,不受全局api設(shè)置所影響
option("test")
-- 當(dāng)前選項(xiàng)的局部作用域
set_default(false)
-- 其他target設(shè)置仰税,-DDEBUG 也會(huì)被設(shè)置上
target("demo2")
set_kind("binary")
add_files("src/*.c")
-- 重新進(jìn)入demo目標(biāo)作用域
target("demo")
-- 追加宏定義,只對(duì)當(dāng)前demo目標(biāo)有效
add_defines("DEBUG3")
xmake里面還有些全局api抽诉,僅提供全局作用域支持陨簇,例如:
- add_subfiles()
- add_subdirs()
- add_packagedirs()
等等,這些調(diào)用不要放置在 target 或者 option 的局部作用域之間迹淌,雖然沒(méi)什么實(shí)際區(qū)別河绽,但是會(huì)影響可讀性,容易被誤導(dǎo)
使用方式唉窃,如下:
target("xxxx")
set_kind("binary")
add_files("*.c")
-- 包含子模塊文件
add_subdirs("src")
作用域縮進(jìn)
xmake.lua里面縮進(jìn)耙饰,只是個(gè)編寫規(guī)范,用于更加清楚的區(qū)分纹份,當(dāng)前的設(shè)置 是針對(duì) 那個(gè)作用域的苟跪,雖然就算不縮進(jìn)廷痘,也一樣ok,但是可讀性上 并不是很好件已。笋额。
例如:
target("xxxx")
set_kind("binary")
add_files("*.c")
和
target("xxxx")
set_kind("binary")
add_files("*.c")
上述兩種方式,效果上都是一樣的篷扩,但是理解上兄猩,第一種更加直觀,一看就知道 add_files 僅僅只是針對(duì) target 設(shè)置的鉴未,并不是全局設(shè)置
因此枢冤,適當(dāng)?shù)倪M(jìn)行縮進(jìn),有助于更好的維護(hù)xmake.lua
最后附上铜秆,tbox的xmake.lua和src/tbox/xmake.lua描述淹真,僅供參考。羽峰。
個(gè)人主頁(yè):TBOOX開源工程
原文出處:http://tboox.org/cn/2016/10/26/api-scope/