天天看點

xmake 描述文法和作用域詳解

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_xxx

或者

add_xxx

就能滿足需求了

那麼根據二八定律,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有:

  • table
  • string
  • pairs
  • ipairs
  • print:修改版,提供格式化列印支援
  • os:僅提供隻讀接口,例如getenv等等

當然雖然内置lua api提供不多,但xmake還提供了很多擴充api,像描述api就不多說,詳細可參考:

工程描述api文檔

還有些輔助api,例如:

  • dirs:掃描擷取目前指定路徑中的所有目錄
  • files:掃描擷取目前指定路徑中的所有檔案
  • format: 格式化字元串,string.format的簡寫版本

還有變量定義、邏輯操作也是可以使用的,畢竟是基于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,僅提供全局作用域支援,例如:

  • add_subfiles()
  • add_subdirs()
  • add_packagedirs()

等等,這些調用不要放置在 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

描述,僅供參考。。

個人首頁:

TBOOX開源工程

原文出處:

http://tboox.org/cn/2016/10/26/api-scope/

繼續閱讀