1.背景
背景一:
為解決Android版本碎片化問題,引入Treble架構,它提供了穩定的新SoC供應商接口,引入HAL 接口定義語言(HIDL/Stable AIDL,技術棧依然是Binder),它指定了 vendor HAL 和system framework的接口, 解耦system Framework 與Vendor HAL, system/vendor元件功能互相獨立,進而使得Vendor Freeze成為可能。
背景二:
經過調查AOSP源碼的vendor元件有30%~40%的倉庫與system元件耦合,耦合倉庫的類型,主要包括:AOSP framework架構倉、prebuilts、external、平台倉、odm自研倉、build倉。
背景三:
緊接着Google對Treble架構進一步演進,增強了system/vendor元件之間的interface化能力,從AndroidR開始設計了VNDK和VSDK的snapshot方案。
system元件通過預編譯形成vendor Snapshot,可提供給不同Android版本的vendor元件使用,這部分也是Treble方案落地的一個重要環節和基礎支撐。
2.VNDK基本概念
在Android的Treble架構中為了規範和限制system/vendor元件之間的耦合關系,對Native庫進行幾大類的劃分,通過定義不同類型的互相耦合程度和使用限制來達到管控system/vendor元件之間子產品的耦合度。
2.1 core library:
隻在系統鏡像,隻被系統子產品使用,不允許被vendor、vendor_available、vndk和vndk-sp的library依賴
其bp中的格式為
cc_library {
name: "libThatIsCore",
...
}
不包含vendor、vendor_available、vndk和vndk-sp屬性
2.2 vendor-only(proprietary) library:
隻給vendor使用,而且二進制位置在vendor鏡像
其bp中的格式為
cc_library {
name: "libThatIsVendorOnly",
proprietary: true,
# or: vendor: true, # (for things in AOSP)
...
}
不包含vndk屬性
2.3 vendor_available library:
被vendor鏡像使用到的libary,同時存在vendor和core變體,打包在vendor和system鏡像中,其bp中的格式為
cc_library {
name: "libThatIsVendorAvailable",
vendor_available: true,
...
}
不包含vndk屬性
2.4 vndk libary:
被vendor子產品使用,但是二進制在system鏡像
其bp中的格式為
cc_library {
name: "libThatIsVndk",
vendor_available: true,
vndk: {
enabled: true,
}
...
}
同時存在vendor_available和vnd.enable屬性
2.5 vndk-sp library:
被vendor直接使用,被system鏡像間接使用的library,其二進制在system鏡像中
其bp中的格式為
cc_library {
name: "libThatIsVndkSp",
vendor_available: true,
vndk: {
enabled: true,
support_system_process: true,
}
...
}
需要配置support_system_process屬性
2.6 llndk library:
由Google維護的被system和vendor鏡像共同使用的library,可double load。其二進制在system鏡像
其bp中的格式為
llndk_library {
name: "libThatIsLlndk",
}
Naive庫劃分與依賴關系
VNDK使能後的編譯依賴關系
3.VSDK基本概念
VSDK其實是包含了VNDK部分,同時也包含Vendor Snapshot。
Vendor Snapshot的範圍是由系統源碼維護的用于Vendor編譯或者內建用到的Native子產品的集合,它主要由下面幾個類型的産物構成
- vendor: true或者vendor_available: true的動态/靜态庫或者是頭檔案庫
- vendor_available: true的靜态VNDK庫
- vendor: true或者vendor_available: true的可執行檔案或者目标檔案
對于vendor_snapshot和vndk裡面到底打包的是哪些子產品,先看下表,對子產品vendor變體的劃分。
vndk :true的子產品全部都安裝在VNDK中,隻有另外帶了vendor_available:true的vndk子產品才可以被vendor子產品直接使用,不帶的private的vndk隻能被VNDK自有子產品使用間接的被vendor子產品使用。
總得來說:VSDK包括VNDK + vendor Snapshot + recoverySnapshot + host Snapshot。
4.Snapshot設計
上面兩章分别給出了VNDK/VSDK的基礎概念,内容劃分和建構支援。回到最初的問題,在面對system和vendor不同時間不同版本編譯的搭配問題上,VNDK/VSDK在工程上的處理流程如何?Snapshot的方案是從system側預建構出vendor所需的内容,使用這部分而不是源碼用于vendor建構。具體内容和實作接下來依次介紹。
4.1Snapshot簡介
VNDK/VSDK的Snapshot(snapshot)是指從目前system側按一定規則生成預建構的一組庫,這些庫将用于後面vendor側的編譯。
上圖中給出了首發項目和vendor freeze項目兩種情況system和vendor的搭配,由于Android大版本更新中vendor是固定的,vendor對應依賴的部分也需要有比對的版本。在工程中我們有兩種實作方法:
1、vendor側manifest檔案中包含system的倉庫,例如framework/av,framework/base,framework/native這些熱點倉庫。然後這些倉庫的使用前一個android版本的代碼。
2、使用google的Snapshot設計,Vendor Image v27依賴的這部分v27版本的vndk/vsdk庫将由System Image v27版本預建構生成,這些庫将獨立用于vendor側的編譯,以此vendor側就能擺脫對system側源碼的依賴。
兩種方法各有優缺點:1的方法簡單直接,但是vendor的代碼量更多,vendor編譯時間更長;2vendor側代碼精簡,編譯時間短,但是工程中落地則需要額外的一套預建構系統進行支援。
4.2 Snapshot生成流程
生成Snapshot實際就是生成VSDK二進制及其編譯配置邏輯,最終引用Snapshot産物的一套流程,可以分為三個階段:
1、Generate Phrase:按照一定的規則,從系統側源代碼中産生出vendor image編譯依賴的預置編譯子產品産物(稱為prebuilt snapshots)的過程。
2、Install Phrase:通過py腳本将Generation階段中生成的prebuilt子產品安裝到制定的源碼目錄,并生成對應的Android.bp檔案的過程。
3、Use Phrase:通過設定BOARD_VNDK_VERSION為具體的某個版本号(如31),觸發編譯系統使用預先生成的Snapshot參與編譯(對應地将屏蔽相關子產品的源碼編譯邏輯)的過程。
4.3 VNDK Snapshot生成流程
以AOSP的裝置為例,對應VNDK Snapshot包為android-vndk-arm64.zip,其内容為:
android-vndk-arm64.zip
├── arch-arm64-armv8-a
│ └── shared
│ ├── vndk-core -> *.so files, *.json files
│ └── vndk-sp -> *.so files, *.json files
├── arch-arm-armv8-a -> (same as arch-arm64-armv8-a)
├── configs -> *.libraries.txt, module_paths.txt, module_names.txt
├── include -> exported header files (*.h, *.hh, etc.)
└── NOTICE_FILES -> license txt files
Generate Phrase:
vndk Snapshot的生成邏輯在檔案soong/cc/vndk.go通過定義VndkSnapshotSingleton來實作。
func init() {
android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
}
func VndkSnapshotSingleton() android.Singleton {
return &vndkSnapshotSingleton{}
}
type vndkSnapshotSingleton struct {
vndkLibrariesFile android.OutputPath
vndkSnapshotZipFile android.OptionalPath
}
其中vndkSnapshotZipFile定義了vndk-snapshot.zip檔案的路徑。在vndkSnapshotSingleton的GenerateBuildActions方法中生成vndkSnapshot
Install Phrase:
VNDK包的安裝是通過/development/vndk/snapshot/update.py實作的,流程為:
最終生成的bp檔案中的
vndk_prebuilt_shared {
name: "android.hardware.wifi.hostapd-V1-ndk",
version: "33",
target_arch: "arm64",
vendor_available: true,
vndk: {
enabled: true,
},
arch: {
arm: {
export_include_dirs: [
"include/frameworks/native/libs/binder/ndk/include_cpp",
...
],
srcs: ["arch-arm-armv8-a/shared/vndk-core/android.hardware.wifi.hostapd-V1-ndk.so"],
},
arm64: {
export_include_dirs: [
"include/frameworks/native/libs/binder/ndk/include_cpp",
...
],
srcs: ["arch-arm64-armv8-a/shared/vndk-core/android.hardware.wifi.hostapd-V1-ndk.so"],
},
},
}
Use Phrase:
通過在device.mk中設定BOARD_VNDK_VERSION變量為具體版本值,然後對vendor側進行編譯。
4.4 VSDK Snapshot生成流程
以AOSP的裝置為例,vsdkSnapshot包内容為:
vendor-$(TARGET_DEVICE).zip
├── arch-arm64-armv8-a
│ ├── binary -> binary files, *.json files
│ ├── header -> *.json files
│ ├── object -> *.o files, *.json files
│ ├── shared -> *.so files, *.json files
│ └── static -> *.a files, *.json files
├── arch-arm-armv8-a -> (arch-arm64-armv8-a)
├── configs -> *.rc files, *.xml files
├── include -> exported header files (*.h, *.hh, etc.)
└── NOTICE_FILES -> license txt files
Generate Phrase:
vsdkSnapshot的生成邏輯在vendor_snapshot.go的GenerateBuildActions中:
Install Phrase:
vsdkSnapshot安裝使用了/development/vendor_snapshot/update.py檔案:
Use Phrase:
通過在device.mk中設定BOARD_VNDK_VERSION變量為具體版本值,然後對vendor側進行編譯。
5.總結
VNDK/VSDK Snapshot可進一步減少system/vendor元件之間的源碼依賴、編譯依賴,更容易形成Treble基線。
收益總結為三點:
- 提高了vendor元件的編譯效率
- 提高了代碼認知管理,解耦後的倉庫,可以删除vendor元件中的耦合倉,隻保留system元件中的源碼
- 更有利于支撐system/vendor元件的獨立開發
參考資料
[1]https://source.android.com/devices/architecture/vndk/snapshot-vendor
[2]https://source.android.com/devices/architecture/vndk/snapshot-generate
[3] Bootcamp 2021 VSDK.pdf
[4]https://source.android.com/devices/architecture/vndk/enabling
[5]https://source.android.com/docs/core/architecture/vndk/build-system
[6]https://source.android.com/docs/core/architecture/vndk/snapshot-design
[7] 深入剖析VNDK/VSDK Snapshot編譯架構
本文首發在“核心工匠”微信公衆号,歡迎關注公衆号擷取最新Linux技術分享。