原文地址:https://android.googlesource.com/platform/build/soong/
Soong 是原基于 make 的構(gòu)建系統(tǒng)的替代品蜘澜。它使用 Android.bp 來取代 Android.mk两踏,并使用類似于 JSON 的格式來描述一個模塊的構(gòu)建方案盐碱。
Android.bp 文件格式
Android.bp 的設(shè)計非常簡單,沒有條件判斷或控制流語句蹋嵌。在 Go 語言中編寫的構(gòu)建邏輯沒有任何復(fù)雜度。Android.bp 的語法和語義可能也類似于 Bazel BUILD 文件。
模塊
模塊在 Android.bp 文件中以一個模塊類型開始炫隶,后面跟著一組屬性,以名值對(name: value)表示憔披〉认蓿基本格式為:
cc_binary {
name: "gzip",
srcs: ["src/test/minigzip.c"],
shared_libs: ["libz"],
stl: "none",
}
每個模塊都必須有一個 name 屬性爸吮,name 的值在所有的 Android.bp 文件中都必須是唯一的。
有關(guān)有效模塊類型及其屬性的列表望门,請參閱 $OUT_DIR/soong/.bootstrap/docs/soong_build.html形娇。
變量
Android.bp 文件可以包含頂級變量并賦值:
gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
name: "gzip",
srcs: gzip_srcs,
shared_libs: ["libz"],
stl: "none",
}
變量的范圍被限定為它們聲明的文件的剩余部分,以及任何子 blueprint 文件筹误。變量只能夠被 += 進行附加賦值桐早,而且只有在被引用之前可變。
注釋
Android.bp 文件可以使用 C 風(fēng)格的多行 /* */ 和 C++ 風(fēng)格的單行 // 注釋厨剪。
類型
變量和屬性是強類型的哄酝,基于第一次被賦值的值動態(tài)推定,以及由模塊類型決定的靜態(tài)屬性祷膳。支持的類型有:
布爾值(true 或 false)
字符串(”string”)
字符串列表([“string1”, “string2”])
Map({key1: “value1”, key2:[“value2”]})
Map 可以包含任意類型的值陶衅,包括嵌套的 Map。列表和 Map 允許在最后一個值之后有逗號直晨。
操作符
字符串搀军,字符串列表和 Map 可以使用 + 運算符進行附加。附加 Map 將生成兩個 Map 中的鍵的并集勇皇,并且附加兩個 Map 中存在的所有鍵的值罩句。
默認模塊
默認模塊可以描述在多個模塊中被重復(fù)的相同屬性。例如:
cc_defaults {
name: "gzip_defaults",
shared_libs: ["libz"],
stl: "none",
}
cc_binary {
name: "gzip",
defaults: ["gzip_defaults"],
srcs: ["src/test/minigzip.c"],
}
格式化工具
Soong 包含了一個 blueprint 文件的格式化器敛摘,類似于 gofmt门烂。使用以下命令來遞歸格式化當(dāng)前目錄中的所有 Android.bp 文件:
$ bpfmt -w
標(biāo)準(zhǔn)格式包括 4 個空格的縮進,包含多個元素的列表中兄淫,每個元素之后的換行符屯远,并且始終包括列表和 Map 中的逗號。
轉(zhuǎn)換 Android.mk 文件:
androidmk Android.mk > Android.bp
該工具可以轉(zhuǎn)換變量拖叙,模塊氓润,注釋和一些條件,但任何自定義的 Makefile 規(guī)則薯鳍,復(fù)雜條件或額外的 include 必須手動轉(zhuǎn)換咖气。
Android.mk和Android.bp之間的差異
Android.mk 文件通常包含了擁有相同名稱的多個模塊(例如,對于同時擁有靜態(tài)和動態(tài)版本的庫挖滤,或同時供主機和設(shè)備使用的庫)崩溪。Android.bp 文件要求每個模塊擁有唯一的名稱,但每個模塊可以內(nèi)置多種變化斩松,例如添加 host_supported: true伶唯。 androidmk 轉(zhuǎn)換器將產(chǎn)生多個沖突的模塊,必須手動合并到單個模塊內(nèi)的 target: { android: { }, host: { } } 塊里惧盹。
構(gòu)建邏輯
構(gòu)建邏輯使用 Go 語言編寫乳幸,并使用 blueprint 框架瞪讼。構(gòu)建邏輯接收模塊定義,并利用反射和構(gòu)建規(guī)則解析為 Go 數(shù)據(jù)結(jié)構(gòu)粹断。構(gòu)建規(guī)則由 blueprint 收集并寫入 ninja 構(gòu)建文件符欠。
常見問題
如何寫一個條件判斷?
Soong 故意不支持 Android.bp 文件中的條件瓶埋。作為替代希柿,復(fù)雜的、需要用到條件的構(gòu)建規(guī)則已被 Go 處理养筒,可以使用高級語言特征來跟蹤由條件引入的隱式依賴關(guān)系曾撤。大多數(shù)條件將被轉(zhuǎn)換為 Map 屬性,Map 中的一個值將被選中并附加到頂級屬性晕粪。
例如挤悉,支持特定架構(gòu)的文件:
cc_library {
...
srcs: ["generic.cpp"],
arch: {
arm: {
srcs: ["arm.cpp"],
},
x86: {
srcs: ["x86.cpp"],
},
},
}
有關(guān)產(chǎn)品變量或環(huán)境變量的更復(fù)雜條件的示例,請參閱 art/build/art.go 或 external/llvm/soong/llvm.go兵多。