Android.bp入門教程

Soong 編譯系統(tǒng)

在 Android 7.0 發(fā)布之前偷霉,Android 僅使用 GNU Make 描述和執(zhí)行其構(gòu)建規(guī)則沸移。Make 構(gòu)建系統(tǒng)得到了廣泛的支持和使用婉烟,但在 Android 層面變得緩慢、容易出錯沪伙、無法擴展且難以測試户辞。Soong 構(gòu)建系統(tǒng)正好提供了 Android build 所需的靈活性翔横。

Soong 構(gòu)建系統(tǒng)是在 Android 7.0 (Nougat) 中引入的,旨在取代 Make啊掏。它利用 Kati GNU Make 克隆工具和 Ninja 構(gòu)建系統(tǒng)組件來加速 Android 的構(gòu)建蠢络。

Android.bp文件格式

Android.bp的語法在設(shè)計上要比Android.mk簡單一些,主要是因為Android.bp沒有條件或控制流語句迟蜜。

注意:Android.bp不支持條件語句刹孔!在實際項目中,如果構(gòu)建的腳本必須包含條件語句娜睛,建議使用Android.mk或使用Go語言

模塊與示例

Android.bp 文件中的模塊以模塊類型開頭髓霞,然后是一組格式屬性:name: value卦睹,在一點上Android.bp的語法結(jié)構(gòu)與JSON的語法結(jié)構(gòu)相似,都是以鍵值對的形式編寫方库。下面是一個簡單示例:

android_app {
    name: "Provision",
    srcs: ["**/*.java"],
    platform_apis: true,
    product_specific: true,
    certificate: "platform",
}

每個模塊都必須具有 name 屬性结序,并且相應(yīng)值在所有 name 文件中必須是唯一的,僅有兩個例外情況是命名空間和預(yù)構(gòu)建模塊中的 Android.bp 屬性值纵潦,這兩個值可能會重復(fù)徐鹤。
srcs 屬性以字符串列表的形式指定用于構(gòu)建模塊的源文件±掖可以使用模塊引用語法 ":<module-name>" 來引用生成源文件的其他模塊的輸出凳干,如 genrulefilegroup

android_app{}

表示該模塊用于構(gòu)建一個apk

name: "Provision",

如果指定了 android_app 模塊類型(在代碼塊的開頭)被济,就需要設(shè)定該模塊的name 救赐。此設(shè)置會為模塊命名,生成的 APK 將與模塊名稱相同只磷,不過帶有 .apk 后綴经磅。例如,在本例中钮追,生成的 APK 將命名為 Provision.apk

srcs: ["**/*.java"],

srcs用于指定當(dāng)前的模塊編譯的源碼位置预厌,*表示通配符

platform_apis: true,

設(shè)置該標(biāo)記后會使用sdk的hide的api來編譯。編譯的APK中使用了系統(tǒng)級API元媚,必須設(shè)定該值轧叽。和Android.mk中的LOCAL_PRIVATE_PLATFORM_APIS的作用相同

product_specific: true,

設(shè)置該標(biāo)記后,生成的apk會被安裝在Android系統(tǒng)的product分區(qū)刊棕,和Android.mk中LOCAL_PRODUCT_MODULE作用相同

certificate: "platform",

certificate 用于指定APK的簽名方式炭晒。如果不指定,默認(rèn)使用testkey簽名甥角。與LOCAL_CERTIFICATE作用相同网严。

Android中共有四中簽名方式:

  • testkey:普通APK,默認(rèn)使用該簽名嗤无。
  • platform:該APK完成一些系統(tǒng)的核心功能震束。經(jīng)過對系統(tǒng)中存在的文件夾的訪問測試,這種方式編譯出來的APK所在進程的UID為system当犯。
  • shared:該APK需要和home/contacts進程共享數(shù)據(jù)垢村。
  • media:該APK是media/download系統(tǒng)中的一環(huán)。

常見模塊類型

在Android.bp中我們會基于模塊類型來構(gòu)建我們所需要的東西嚎卫,常用的有以下幾種類型

android_app

用于構(gòu)建Android 應(yīng)用程序安裝包肝断,是Android系統(tǒng)應(yīng)用開發(fā)中常用的模塊類型,與Android.mk中的BUILD_PACKAGE作用相同。

android_app_certificate

android_app_certificate模塊可由android_app模塊的證書屬性certificate引用以選擇簽名密鑰胸懈。

java_library

java_library用于將源代碼構(gòu)建并鏈接到設(shè)備的.jar文件中担扑。默認(rèn)情況下,java_library只有一個變量趣钱,它生成一個包含根據(jù)設(shè)備引導(dǎo)類路徑編譯的.class文件的.jar包涌献。生成的jar不適合直接安裝在設(shè)備上,通過會用作另一個模塊的static_libs依賴項首有。

如果指定“installable:true”將生成一個包含“classes.dex”文件的“.jar”文件燕垃,適合在設(shè)備上安裝。指定'host_supported:true'將產(chǎn)生兩個變量井联,一個根據(jù)device的bootclasspath編譯卜壕,另一個根據(jù)host的bootclasspath編譯。

java_library_static

java_library_static作用等同于java_library烙常,但是java_library_static已經(jīng)過時轴捎,不推薦使用

android_library

android_library將源代碼與android資源文件一起構(gòu)建并鏈接到設(shè)備的“.jar”文件中。android_library有一個單獨的變體蚕脏,它生成一個包含根據(jù)device的bootclasspath編譯的.class文件的.jar文件侦副,以及一個包含使用aapt2編譯的android資源的.package-res.apk文件。生成的apk文件不能直接安裝在設(shè)備上驼鞭,但可以用作android_app模塊的static_libs依賴項秦驯。

cc_library

cc_library為device或host創(chuàng)建靜態(tài)庫或共享庫。默認(rèn)情況下挣棕,cc_library具有針對設(shè)備的單一變體译隘。指定'host_supported:true'還會創(chuàng)建一個以主機為目標(biāo)的庫。與cc_library相關(guān)的模塊類型還有cc_library_shared洛心、cc_library_headers固耘、cc_library_static等。

Android.bp中涉及到的模塊類型非常的多皂甘,我們可以在Soong模塊和屬性列表中查看其它的模塊類型以及用法。

設(shè)置變量

在bp中可以通過=號來設(shè)定一個全局變量

src_path = ["**/*.java"]
android_app {
    name: "Provision",
    srcs: src_path,
    platform_apis: true,
    product_specific: true,
    certificate: "platform",
}

默認(rèn)模塊

soong提供了一系列xx_defaults模塊類型悼凑,例如:cc_defaults, java_defaults, doc_defaults, stubs_defaults等等偿枕。

xx_defaults的模塊提供了一組可由其它模塊繼承的屬性。其它模塊可以通過defaults:["<:default_module_name>"]來繼承xx_defaults類型模塊中定義的屬性户辫。xxx_defaults類型的模塊可以被多個模塊繼承渐夸,減少我們在bp中書寫重復(fù)的屬性。

cc_defaults {
    name: "gzip_defaults",
    shared_libs: ["libz"],
    stl: "none",
}

cc_binary {
    name: "gzip",
    defaults: ["gzip_defaults"],
    srcs: ["src/test/minigzip.c"],
}

數(shù)據(jù)類型

Android.bp中變量和屬性是強類型渔欢,變量根據(jù)第一項賦值動態(tài)變化墓塌,屬性由模塊類型靜態(tài)設(shè)置。支持的類型為:

  • 布爾值(truefalse

  • 整數(shù) (int

  • 字符串("string"

  • 字符串列表 (["string1", "string2"])

  • 映射 ({key1: "value1", key2: ["value2"]})

映射可以包含任何類型的值,包括嵌套映射苫幢。

條件語句

Soong 不支持 Android.bp 文件中的條件語句访诱。編譯規(guī)則中需要條件語句的復(fù)雜問題將在 Go(在這種語言中,您可以使用高級語言功能韩肝,并且可以跟蹤條件語句引入的隱式依賴項)中處理触菜。大多數(shù)條件語句都會轉(zhuǎn)換為映射屬性,其中選擇了映射中的某個值并將其附加到頂級屬性哀峻。

例如涡相,要支持特定于架構(gòu)的文件,可以使用以下命令:

cc_library {
  ...
  srcs: ["generic.cpp"],
  arch: {
    arm: {
      srcs: ["arm.cpp"],
    },
    x86: {
      srcs: ["x86.cpp"],
    },
  },
}

注意:Android.bp不支持條件語句剩蟀!在實際項目中催蝗,如果構(gòu)建的腳本必須包含條件語句,建議使用Android.mk

運算符

可以使用 + 運算符附加字符串育特、字符串列表和映射丙号。可以使用 + 運算符對整數(shù)求和且预。附加映射會生成兩個映射中鍵的并集槽袄,并附加在兩個映射中都存在的所有鍵的值。

注釋

Android.bp文件可以和C/C++的注釋類似锋谐,可以包含多行注釋和單行注釋遍尺。

  1. 多行注釋:/ * 注釋 * /
  2. 單行注釋://注釋。

關(guān)于Android.bp還有一些其它的基礎(chǔ)知識涮拗,請繼續(xù)參閱Soong 編譯系統(tǒng)

使用示例

關(guān)于Android.bp如何使用乾戏,我們可以參考系統(tǒng)中已有模塊的是如何編寫的。

該Android.bp位于Android 10 : packages/apps/Car/Notification 下

// 構(gòu)建可執(zhí)行程序
android_app {
    // 設(shè)定可執(zhí)行的程序的名稱三热,編譯后會生成一個 CarNotification.apk
    name: "CarNotification",
    // 指定java源碼的位置
    srcs: ["src/**/*.java"],
    // 指定資源文件的位置
    resource_dirs: ["res"],
    // 允許使用系統(tǒng)hide api
    platform_apis: true,
    // 設(shè)定apk簽名為 platform
    certificate: "platform",
    // 設(shè)定apk安裝路徑為priv-app
    privileged: true,
    // 是否啟用代碼優(yōu)化鼓择,android_app中默認(rèn)為true,java_library中默認(rèn)為false
    optimize: {
        enabled: false,
    },
    // 是否預(yù)先生成dex文件就漾,默認(rèn)為true呐能。該屬性會影響應(yīng)用的首次啟動速度以及Android系統(tǒng)的啟動速度
    dex_preopt: {
        enabled: false,
    },
    // 引入java靜態(tài)庫
    static_libs: [
        "androidx.cardview_cardview",
        "androidx.recyclerview_recyclerview",
        "androidx.palette_palette",
        "car-assist-client-lib",
        "android.car.userlib",
        "androidx-constraintlayout_constraintlayout"
    ],
    // 引入java庫
    libs: ["android.car"],
    product_variables: {
        pdk: {
            enabled: false,
        },
    },
    // 設(shè)定依賴模塊。如果安裝了此模塊抑堡,則要還需要安裝的其他模塊的名稱
    required: ["privapp_whitelist_com.android.car.notification"]
}
// As Lib
android_library {
    name: "CarNotificationLib",
    srcs: ["src/**/*.java"],
    resource_dirs: ["res"],
    manifest: "AndroidManifest-withoutActivity.xml",
    platform_apis: true,
    optimize: {
        enabled: false,
    },
    dex_preopt: {
        enabled: false,
    },
    static_libs: [
        "androidx.cardview_cardview",
        "androidx.recyclerview_recyclerview",
        "androidx.palette_palette",
        "car-assist-client-lib",
        "android.car.userlib",
        "androidx-constraintlayout_constraintlayout"
    ],
    libs: ["android.car"],
    product_variables: {
        pdk: {
            enabled: false,
        },
    },
}

常見疑問

Android.bp引用Android.mk編譯的模塊

Android.bp編譯的模塊無法訪問到Android.mk編譯的模塊摆出!相反,Android.mk可以引用Android.bp編譯的模塊首妖。

引入第三方j(luò)ar

在實際開發(fā)中偎漫,我們經(jīng)常需要在app中引入第三方的jar,在Android.bp中有缆,可以按照下面的方式引入象踊。在項目的根目錄新建 libs文件夾温亲,放入要導(dǎo)入的jar包,比如 CarServicelib.jar杯矩,然后在Android.bp中引入該jar

java_import {
  name: "CarServicelib.jar",
  jars: ["libs/CarServicelib.jar"],
}
android_app {
    // 省去其它屬性
    // 引入AndroidX庫下的lib
    static_libs: [
        "CarServicelib.jar"
    ],
}

引入AndroidX庫

開發(fā)過程如果想要引入AndroidX的類庫可以參考下面的方式編寫栈虚。

android_app {
    // 省去其它屬性
    // 引入AndroidX庫下的lib
    static_libs: [
        "androidx.cardview_cardview",
        "androidx.recyclerview_recyclerview",
        "androidx-constraintlayout_constraintlayout"
    ],
}

參考資料

Soong 編譯系統(tǒng) | Android 開源項目 | Android Open Source Project (google.cn)

Soong (googlesource.com)

簡單的 build 配置 | Android 開源項目 | Android Open Source Project

Android 編譯之a(chǎn)ndroid.bp

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市菊碟,隨后出現(xiàn)的幾起案子节芥,更是在濱河造成了極大的恐慌,老刑警劉巖逆害,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件头镊,死亡現(xiàn)場離奇詭異,居然都是意外死亡魄幕,警方通過查閱死者的電腦和手機相艇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纯陨,“玉大人坛芽,你說我怎么就攤上這事∫砜伲” “怎么了咙轩?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長阴颖。 經(jīng)常有香客問我活喊,道長,這世上最難降的妖魔是什么量愧? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任钾菊,我火速辦了婚禮,結(jié)果婚禮上偎肃,老公的妹妹穿的比我還像新娘煞烫。我一直安慰自己,他們只是感情好累颂,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布滞详。 她就那樣靜靜地躺著,像睡著了一般紊馏。 火紅的嫁衣襯著肌膚如雪料饥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天瘦棋,我揣著相機與錄音稀火,去河邊找鬼暖哨。 笑死赌朋,一個胖子當(dāng)著我的面吹牛凰狞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播沛慢,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼赡若,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了团甲?” 一聲冷哼從身側(cè)響起逾冬,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎躺苦,沒想到半個月后身腻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡匹厘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年嘀趟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愈诚。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡她按,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出炕柔,到底是詐尸還是另有隱情酌泰,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布匕累,位于F島的核電站陵刹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏哩罪。R本人自食惡果不足惜授霸,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望际插。 院中可真熱鬧松蒜,春花似錦攻走、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至祖乳,卻和暖如春砸西,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背慷妙。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工僻焚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人膝擂。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓虑啤,卻偏偏與公主長得像隙弛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子狞山,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容