解析Android VNDK/VSDK Snapshot編譯框架
1.背景
背景一:
為解決Android版本碎片化問題,引入Treble架構(gòu),它提供了穩(wěn)定的新SoC供應(yīng)商接口,引入HAL 接口定義語言(HIDL/Stable AIDL,技術(shù)棧依然是Binder),它指定了 vendor HAL 和system framework的接口, 解耦system Framework 與Vendor HAL, system/vendor組件功能互相獨(dú)立,從而使得Vendor Freeze成為可能。

背景二:
經(jīng)過調(diào)查AOSP源碼的vendor組件有30%~40%的倉庫與system組件耦合,耦合倉庫的類型,主要包括:AOSP framework框架倉、prebuilts、external、平臺(tái)倉、odm自研倉、build倉。
背景三:
緊接著Google對(duì)Treble架構(gòu)進(jìn)一步演進(jìn),增強(qiáng)了system/vendor組件之間的interface化能力,從AndroidR開始設(shè)計(jì)了VNDK和VSDK的snapshot方案。
system組件通過預(yù)編譯形成vendor Snapshot,可提供給不同Android版本的vendor組件使用,這部分也是Treble方案落地的一個(gè)重要環(huán)節(jié)和基礎(chǔ)支撐。

2.VNDK基本概念
在Android的Treble架構(gòu)中為了規(guī)范和約束system/vendor組件之間的耦合關(guān)系,對(duì)Native庫進(jìn)行幾大類的劃分,通過定義不同類型的相互耦合程度和使用約束來達(dá)到管控system/vendor組件之間模塊的耦合度。
2.1 core library:
只在系統(tǒng)鏡像,只被系統(tǒng)模塊使用,不允許被vendor、vendor_available、vndk和vndk-sp的library依賴
其bp中的格式為
不包含vendor、vendor_available、vndk和vndk-sp屬性
2.2 vendor-only(proprietary) library:
只給vendor使用,而且二進(jìn)制位置在vendor鏡像
其bp中的格式為
不包含vndk屬性
2.3 vendor_available library:
被vendor鏡像使用到的libary,同時(shí)存在vendor和core變體,打包在vendor和system鏡像中,其bp中的格式為
不包含vndk屬性
2.4 vndk libary:
被vendor模塊使用,但是二進(jìn)制在system鏡像
其bp中的格式為
同時(shí)存在vendor_available和vnd.enable屬性
2.5 vndk-sp library:
被vendor直接使用,被system鏡像間接使用的library,其二進(jìn)制在system鏡像中
其bp中的格式為
需要配置support_system_process屬性
2.6 llndk library:
由Google維護(hù)的被system和vendor鏡像共同使用的library,可double load。其二進(jìn)制在system鏡像
其bp中的格式為

Naive庫劃分與依賴關(guān)系

VNDK使能后的編譯依賴關(guān)系
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)? ?


3.VSDK基本概念

VSDK其實(shí)是包含了VNDK部分,同時(shí)也包含Vendor Snapshot。
Vendor Snapshot的范圍是由系統(tǒng)源碼維護(hù)的用于Vendor編譯或者集成用到的Native模塊的集合,它主要由下面幾個(gè)類型的產(chǎn)物構(gòu)成
vendor: true或者vendor_available: true的動(dòng)態(tài)/靜態(tài)庫或者是頭文件庫
vendor_available: true的靜態(tài)VNDK庫
vendor: true或者vendor_available: true的可執(zhí)行文件或者目標(biāo)文件
對(duì)于vendor_snapshot和vndk里面到底打包的是哪些模塊,先看下表,對(duì)模塊vendor變體的劃分。

vndk :true的模塊全部都安裝在VNDK中,只有另外帶了vendor_available:true的vndk模塊才可以被vendor模塊直接使用,不帶的private的vndk只能被VNDK自有模塊使用間接的被vendor模塊使用。
總得來說:VSDK包括VNDK + vendor Snapshot + recoverySnapshot + host Snapshot。
4.Snapshot設(shè)計(jì)
上面兩章分別給出了VNDK/VSDK的基礎(chǔ)概念,內(nèi)容劃分和構(gòu)建支持?;氐阶畛醯膯栴},在面對(duì)system和vendor不同時(shí)間不同版本編譯的搭配問題上,VNDK/VSDK在工程上的處理流程如何?Snapshot的方案是從system側(cè)預(yù)構(gòu)建出vendor所需的內(nèi)容,使用這部分而不是源碼用于vendor構(gòu)建。具體內(nèi)容和實(shí)現(xiàn)接下來依次介紹。
4.1Snapshot簡(jiǎn)介
VNDK/VSDK的Snapshot(snapshot)是指從當(dāng)前system側(cè)按一定規(guī)則生成預(yù)構(gòu)建的一組庫,這些庫將用于后面vendor側(cè)的編譯。

上圖中給出了首發(fā)項(xiàng)目和vendor freeze項(xiàng)目?jī)煞N情況system和vendor的搭配,由于Android大版本升級(jí)中vendor是固定的,vendor對(duì)應(yīng)依賴的部分也需要有匹配的版本。在工程中我們有兩種實(shí)現(xiàn)方法:
1、vendor側(cè)manifest文件中包含system的倉庫,例如framework/av,framework/base,framework/native這些熱點(diǎn)倉庫。然后這些倉庫的使用前一個(gè)android版本的代碼。
2、使用google的Snapshot設(shè)計(jì),Vendor Image v27依賴的這部分v27版本的vndk/vsdk庫將由System Image v27版本預(yù)構(gòu)建生成,這些庫將獨(dú)立用于vendor側(cè)的編譯,以此vendor側(cè)就能擺脫對(duì)system側(cè)源碼的依賴。
兩種方法各有優(yōu)缺點(diǎn):1的方法簡(jiǎn)單直接,但是vendor的代碼量更多,vendor編譯時(shí)間更長(zhǎng);2vendor側(cè)代碼精簡(jiǎn),編譯時(shí)間短,但是工程中落地則需要額外的一套預(yù)構(gòu)建系統(tǒng)進(jìn)行支持。
4.2 Snapshot生成流程
生成Snapshot實(shí)際就是生成VSDK二進(jìn)制及其編譯配置邏輯,最終引用Snapshot產(chǎn)物的一套流程,可以分為三個(gè)階段:

1、Generate Phrase:按照一定的規(guī)則,從系統(tǒng)側(cè)源代碼中產(chǎn)生出vendor image編譯依賴的預(yù)置編譯模塊產(chǎn)物(稱為prebuilt snapshots)的過程。
2、Install Phrase:通過py腳本將Generation階段中生成的prebuilt模塊安裝到制定的源碼目錄,并生成對(duì)應(yīng)的Android.bp文件的過程。
3、Use Phrase:通過設(shè)置BOARD_VNDK_VERSION為具體的某個(gè)版本號(hào)(如31),觸發(fā)編譯系統(tǒng)使用預(yù)先生成的Snapshot參與編譯(對(duì)應(yīng)地將屏蔽相關(guān)模塊的源碼編譯邏輯)的過程。
4.3 VNDK Snapshot生成流程
以AOSP的設(shè)備為例,對(duì)應(yīng)VNDK Snapshot包為android-vndk-arm64.zip,其內(nèi)容為:
Generate Phrase:
vndk Snapshot的生成邏輯在文件soong/cc/vndk.go通過定義VndkSnapshotSingleton來實(shí)現(xiàn)。
其中vndkSnapshotZipFile定義了vndk-snapshot.zip文件的路徑。在vndkSnapshotSingleton的GenerateBuildActions方法中生成vndkSnapshot

Install Phrase:
VNDK包的安裝是通過/development/vndk/snapshot/update.py實(shí)現(xiàn)的,流程為:

最終生成的bp文件中的
Use Phrase:
通過在device.mk中設(shè)置BOARD_VNDK_VERSION變量為具體版本值,然后對(duì)vendor側(cè)進(jìn)行編譯。
4.4 VSDK Snapshot生成流程
以AOSP的設(shè)備為例,vsdkSnapshot包內(nèi)容為:
Generate Phrase:
vsdkSnapshot的生成邏輯在vendor_snapshot.go的GenerateBuildActions中:

Install Phrase:
vsdkSnapshot安裝使用了/development/vendor_snapshot/update.py文件:

Use Phrase:
通過在device.mk中設(shè)置BOARD_VNDK_VERSION變量為具體版本值,然后對(duì)vendor側(cè)進(jìn)行編譯。
5.總結(jié)
VNDK/VSDK Snapshot可進(jìn)一步減少system/vendor組件之間的源碼依賴、編譯依賴,更容易形成Treble基線。
收益總結(jié)為三點(diǎn):
提高了vendor組件的編譯效率
提高了代碼認(rèn)知管理,解耦后的倉庫,可以刪除vendor組件中的耦合倉,只保留system組件中的源碼
更有利于支撐system/vendor組件的獨(dú)立開發(fā)
原文作者:內(nèi)核工匠
