1、ABI簡介
Android系統(tǒng)支持不同的Android設(shè)備使用不同的CPU,CPU與指令集的每種組合都有其自己的應(yīng)用二進(jìn)制界面(或ABI)。ABI可以非常精確地定義應(yīng)用的機(jī)器代碼在運(yùn)行時(shí)如何與系統(tǒng)交互。開發(fā)者必須為應(yīng)用要使用的每個(gè)CPU架構(gòu)指定ABI。
典型的ABI包含以下信息。
·機(jī)器代碼應(yīng)使用的CPU指令集。
·運(yùn)行時(shí)內(nèi)存存儲(chǔ)和加載的字節(jié)順序。
·可執(zhí)行二進(jìn)制文件(例如程序和共享庫)的格式,以及它們支持的內(nèi)容類型。
·用于解析內(nèi)容與系統(tǒng)之間數(shù)據(jù)的各種約定。這些約定
包括對(duì)齊限制,以及系統(tǒng)如何使用堆棧和在調(diào)用方法時(shí)注冊(cè)。
·運(yùn)行時(shí)可用于機(jī)器代碼的方法符號(hào)列表一—通常來自非常具體的庫集。
2、支持的ABI
每個(gè)ABI支持一個(gè)或多個(gè)指令集。
(1)armeabi
此ABI適用于基于ARM、至少支持ARMv5TE指令集的CPU,不支持硬件輔助的浮點(diǎn)計(jì)算。
此ABI支持ARM的Thumb(亦稱Thumb-1)指令集。NDK默認(rèn)生成Thumb代碼,除非在Android.mk文件中使用LOCAL_ARM_MODE變量指定不同的行為。
(2)armeabi-v7a
此ABI可擴(kuò)展armeabi以包含多個(gè)CPU指令集擴(kuò)展,包括Thumb-2指令集擴(kuò)展,其性能堪比32位ARM指令,簡潔性類似于Thumb-1;VFP硬件FPU指令,更具體一點(diǎn),包括VFPv3-D16,它除了ARM核心中的16個(gè)32位寄存器之外,還包含16個(gè)專用64位浮點(diǎn)寄存器;v7-aARM規(guī)格描述的其他擴(kuò)展,包括高級(jí)SIMD(亦稱NEON)、VFPv3-D32和ThumbEE,都是此ABI可選的。
(3)arm64-v8a
此ABI適用于基于ARMv8、支持AArch64的CPU。它還包含NEON和VFPv4指令集。
(4)x86
此ABI適用于支持通常稱為“x86”或“IA-32”的指令集的CPU。
(5)x8664
此ABI適用于支持通常稱為“x86-64”的指令集的CPU。
(6)mips
此ABI適用于基于MIPS、至少支持MIPS32r1指令集的CPU。
(7)mips64
此ABI適用于MIPS64R6。
3、為特定ABI生成代碼
默認(rèn)情況下,NDK為armeabiABI生成機(jī)器代碼。但可以通過向Application.mk文件添加以下行生成ARMv7-a兼容的機(jī)器代碼。
APP ABI:=armeabi-v7a
要為兩個(gè)或更多不同的ABI構(gòu)建機(jī)器代碼,需要使用空格作為分隔符。示例代碼如下:
APP ABI:=armeabi armeabi-v7a
此設(shè)置指示NDK為機(jī)器代碼構(gòu)建兩個(gè)版本:此行中所列的armeabi和armeabi-v7a。
構(gòu)建多個(gè)機(jī)器代碼版本時(shí),構(gòu)建系統(tǒng)會(huì)將庫復(fù)制到應(yīng)用項(xiàng)目路徑,并最終將它們封裝到APK中,從而創(chuàng)建一個(gè)胖二進(jìn)制文件。胖二進(jìn)制文件大于只包含一個(gè)系統(tǒng)的機(jī)器代碼的二進(jìn)制文件,兼容性更廣,但APK占的存儲(chǔ)空間更大。
在安裝時(shí),軟件包管理器只解析APK中包含的最適合目標(biāo)設(shè)備的機(jī)器代碼。
4、Android系統(tǒng)的ABI管理
Android系統(tǒng)的軟件包管理器預(yù)期在APK中符合以下模式的文件路徑上查找NDK生成的庫。
|/1ib/<abi>/lib<name>.so
這里的<abi>支持的是ABI下面列出的ABI名稱之一,<name〉是為Android.mk文件中的LOCAL_MODULE變量定義庫時(shí)使用的庫名稱。由于APK文件只是zip文件,因此打開它們并確認(rèn)它們屬于哪些原生共享庫是很簡單的。
如果系統(tǒng)在預(yù)期位置找不到原生共享庫,便無法使用它們。在這種情況下,應(yīng)用本身必須復(fù)制這些庫,然后執(zhí)行dlopen()。
在胖二進(jìn)制文件中,每個(gè)庫位于其名稱與相應(yīng)ABI匹配的目錄下。例如,胖二進(jìn)制文件可能包含以下文件。
|/1ib/armeabi/libfoo.so
|/lib/armeabi-v7a/libfoo.so
|/1ib/arm64-v8a/libfoo.so
|/1ib/×86/libfoo.so
|/1ib/x8664/libfoo.so
|/lib/mips/libfoo.so
/1ib/mips64/libfoo.so
5、Android系統(tǒng)ABI支持
Android系統(tǒng)在運(yùn)行時(shí)知道它支持哪些ABI,因?yàn)榘姹咎囟ǖ南到y(tǒng)屬性會(huì)指示。
·設(shè)備的主要ABI,與系統(tǒng)映像本身使用的機(jī)器代碼對(duì)應(yīng)。
·可選的輔助ABI,與系統(tǒng)映像支持的另一個(gè)ABI對(duì)應(yīng)。
此機(jī)制確保系統(tǒng)在安裝時(shí)從軟件包提取最佳機(jī)器代碼。
為實(shí)現(xiàn)最佳性能,應(yīng)直接針對(duì)主要ABI進(jìn)行編譯。例如,基于ARMv5TE的典型設(shè)備只會(huì)定義主要ABI為armeabi。相反,基于ARMv7的典型設(shè)備將主要ABI定義為armeabi-v7a,而將輔助ABI定義為armeabi,因?yàn)樗梢赃\(yùn)行為每個(gè)ABI生成的應(yīng)用原生二進(jìn)制文件。
許多基于x86的設(shè)備也可運(yùn)行armeabi-v7a和armeabi NDK二進(jìn)制文件。對(duì)于這些設(shè)備,主要ABI將是x86,輔助ABI是armeabi-v7a。
基于MIPS的典型設(shè)備只定義主要ABI為mips。
6、安裝時(shí)自動(dòng)解壓縮原生代碼
安裝應(yīng)用時(shí),軟件包管理器服務(wù)將掃描APK,查找以下形式的任何共享庫。
|1ib/<primary-abi>/lib<name>.so
如果未找到,并且已定義輔助ABI,該服務(wù)將掃描以下形式的共享庫。
|1ib/<secondary-abi>/lib<name>.so
找到所需的庫時(shí),軟件包管理器會(huì)將它們復(fù)制到應(yīng)用的data目錄(data/data/<package_name>/1ib/)下的/1ib/1ib<name〉.so。
如果沒有找到所需的庫,會(huì)報(bào)如下錯(cuò)誤。
|Failure [INSTALL FAILED NO MATCHING ABIS:Failed to extra
Ict native libraries,res=-113]