xmake的工程描述檔案xmake.lua雖然基於lua語法,但是為了使得更加方便簡潔得編寫專案構建邏輯,xmake對其進行了一層封裝,使得編寫xmake.lua不會像些makefile那樣繁瑣
基本上寫個簡單的工程構建描述,只需三行就能搞定,例如:
target("test")
set_kind("binary")
add_files("src/*.c")
然後只需要執行編譯並且執行它:
$ xmake run test
這對於想要臨時寫些測試**來講,極大地提公升了開發效率。。
xmake的描述語法是按作用域劃分的,主要分為:
那哪些屬於外部,哪些又屬於內部呢,看看下面的注釋,就知道個大概了:
-- 外部作用域
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
之內的都屬於內部作用域,也就是指令碼作用域,其他地方都是都屬於於外部作用域。。
外部作用域
對於大部分工程來說,並不需要很複雜的工程描述,也不需要自定義指令碼支援,只需要簡單的set_***
或者add_***
就能滿足需求了
那麼根據二八定律,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_***
,before_***
和after_***
介面內的,都屬於自作用域。
例如:
-- 自定義指令碼
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("***x")
set_kind("binary")
add_files("*.c")
-- 包含子模組檔案
add_subdirs("src")
作用域縮排
xmake.lua裡面縮排,只是個編寫規範,用於更加清楚的區分,當前的設定 是針對 那個作用域的,雖然就算不縮排,也一樣ok,但是可讀性上 並不是很好。。
例如:
target("***x")
set_kind("binary")
add_files("*.c")
和
target("***x")
set_kind("binary")
add_files("*.c")
上述兩種方式,效果上都是一樣的,但是理解上,第一種更加直觀,一看就知道 add_files 僅僅只是針對 target 設定的,並不是全域性設定
因此,適當的進行縮排,有助於更好的維護xmake.lua
最後附上,tbox的xmake.lua和src/tbox/xmake.lua描述,僅供參考。。
個人主頁:tboox開源工程
原文出處:
深入理解php函式和php作用域詳解
函式引數預設值,在呼叫函式的引數的時候直接預設資料有乙個內定的值,然後在函式的呼叫中,直接進行預設傳參。方法內的變數只在引數的裡面起作用,全域性變數在整個引數裡面起作用,變數沒有定義的錯誤,所謂作用域就是變數被訪問的範圍或者它可以起作用的範圍,區域性變數不能再函式的外部進行訪問,get以及post變...
Vue中的v slot詳解,作用域插槽和具名插槽
1 具名插槽 有時候我們希望在指定的位置輸出我們的子元素,這時候具名插槽就排上了用場。元件呼叫時 這裡v slot 後邊的值與元件內的slot的name屬性對應,也就是插槽的名稱。list 書寫元件時 這裡name的值就是這個插槽的名稱。最後我們會在我們想要的位置將我們的元素放置。2 作用域插槽 作...
C語言 變數的作用域和生命週期詳解
目錄 定義在 塊外部的是全域性變數 定義在 塊內部的是區域性變數 什麼是 塊?這是 快外部 int main 實際上用int main來演示是不太對的,實際使用的時候我們定義變數是在int main內部定義的 下面這個例子更加清晰明了 int main 塊結束 需要注意的是 同乙個變數a可以在全域性...