【Android NDK 開發】NDK 交叉編譯 ( NDK 函數庫目錄 | Linux 交叉編譯環境搭建 | 指定頭文件目錄 | 指定函數庫目錄 | 編譯 Android 命令行可執行文件 )



I . NDK platforms 目錄下的 函數庫



platforms 目錄下的函數庫:


1 . Android 版本目錄 : platforms 中存儲了各個 Android 版本編譯時需要的動態庫與靜態庫資源 , 如 android-29 中就是該版本對應的本地庫資源 ;

在這裏插入圖片描述


2 . CPU 架構目錄 :

在版本目錄下存儲的是不同的 CPU 處理器對應的庫版本 , 如 arm , x86 處理器 , 32 位 與 64 位 等不同版本對應的本地庫 ;

CPU 不同 , 其對應的指令集不同 , 相應編譯出的動態庫或靜態庫就不同 ;

在這裏插入圖片描述

3 . 函數庫目錄 :


在對應 CPU 目錄下的 usr\lib 目錄下 , 存儲了該 Android 版本對應的 CPU 版本的動態庫 與 靜態庫 ;

開發高性能音頻時使用的 libOpenSLES.so , 打印日誌使用的 liblog.so 庫 , 就是在該目錄下 ; 引入的 #include <android/log.h> 頭文件對應的方法邏輯實現就在 liblog.so 庫中 ;

在這裏插入圖片描述



II . Ubuntu 配置 NDK 交叉編譯環境



獨立使用 NDK 提供的交叉編譯工具 , 需要在 Ubuntu Linux 下執行 , 因此這裏我們下載 Linux 版本的 NDK ;


1 . NDK 下載地址 : https://developer.android.google.cn/ndk/downloads

歷史版本的 NDK 下載地址 : https://developer.android.google.cn/ndk/downloads/older_releases.html


2 . 下載完畢會後在 Ubuntu 中解壓文件 :
在這裏插入圖片描述


3 . 配置臨時環境變量 :


① 目的 : 該臨時環境變量 就是 NDK 中的交叉編譯工具的路徑 , 目的是方便調用 ;


② 執行指令 : export CC=/home/book/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc


③ CC 環境變量作用 : CC 是變量名 , 調用的時候使用 $CC main.c 即可調用上述路徑中的 arm-linux-androideabi-gcc 工具編譯 main.c 源文件 ;


④ 交叉編譯 : 上述路徑的編譯器就是在 Linux 中編譯 ARM CPU 指令集的函數庫 , 由於是在 X86 芯片上編譯 ARM 芯片的函數庫 , 因此該操作叫做交叉編譯 ;


4 . 嘗試交叉編譯 :

① main.c 源文件 :

#include <stdio.h>

int main(){
	printf("main : test");
	return 0;
}

② 嘗試編譯 : 調用 $CC main.c 命令嘗試編譯 main.c 程序 , 發現如下問題 ;

book@book-virtual-machine:~/NDK$ $CC main.c 
main.c:1:19: fatal error: stdio.h: No such file or directory
 #include <stdio.h>
                   ^
compilation terminated.
book@book-virtual-machine:~/NDK$ 

③ 分析原因 : 此處需要提供 stdio.h 對應的頭文件與函數庫 , 上面連頭文件都沒有找到 , 需要我們來指定 ;


下面開始說明如何指定頭文件與庫文件 ;



III . 同時指定編譯的頭文件和庫文件



1 . 庫文件 : 交叉編譯需要的庫文件就是上述 NDK platforms 目錄下的 函數庫 ;


2 . --sysroot 頭文件與庫文件查找目錄設定 : 使用 --sysroot=XX 參數設置 ;

指定本次編譯的 頭文件 與 庫文件 , 系統會自動到 XX/usr/include 目錄下查找頭文件 , 到 XX/usr/lib 目錄下查找庫文件 ;



IV . 指定編譯的頭文件



1 . -isysroot 頭文件查找目錄設定 : 使用 -isysroot YY 參數設置 ;

指定頭文件查找目錄 , 系統還會自動到 YY/usr/include 目錄下查找頭文件 ;

注意 : 該配置會覆蓋 --sysroot=XX 參數查找頭文件的配置 ;


2 . 同時設置 --sysroot=XX -isysroot=YY 情況 :


如果同時設置了 --sysroot=XX -isysroot=YY 兩個參數 ,

會去 XX/usr/lib 目錄下找庫文件 ,
到 YY/usr/include 目錄下查找頭文件 ;

( 此時不再去 XX/usr/include 目錄下查找頭文件 )


3 . -isystem 設置頭文件查找路徑 : 使用 -isystem ZZ 參數設置 ;

設置後系統會直接去 ZZ 目錄下查找頭文件 ;


4 . -isysroot 與 -isystem 區別 :


兩種參數配置的查找路徑不同 ,

-isysroot 設定會去設定的目錄下的 usr/include 目錄下查找 .

-isystem 會直接到設置的目錄下查找 ;


5 . -I 頭文件查找目錄 : 使用 -isystem KK 參數設置 ;

設置後系統會直接去 KK 目錄下查找頭文件 ;


6 . 頭文件目錄查找優先級 :

優先級從高到底 : -I > -isystem > -isysroot



V . 指定編譯的庫文件



1 . -L 指定庫文件查找目錄 : 使用 -L AA 參數設置 ;

設置該參數後 , 編譯時系統會自動到 AA 目錄下查找函數庫 ;


2 . -l 指定鏈接的庫名稱 : 使用 -l libxxx.so 參數設置 ;

設置該參數後 , 系統會按照該路徑加載該 libxxx.so 函數庫 ;



VI . 指定編譯的頭文件與庫文件 示例



1 . 設置臨時環境變量 :

export CC=/home/book/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc


2 . NDK 頭文件與庫文件的目錄 :
( 這裏以 android-21 版本 ARM CPU 爲例 )


① NDK 庫文件目錄 :

/home/book/NDK/android-ndk-r17c/platforms/android-21/arch-arm/user/lib


② NDK 庫頭文件目錄 :

/home/book/NDK/android-ndk-r17c/sysroot/usr/include

/home/book/NDK/android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi/asm


3 . 最終的指定頭文件與函數庫的編譯指令 :


$CC --sysroot=/home/book/NDK/android-ndk-r17c/platforms/android-21/arch-arm -isystem /home/book/NDK/android-ndk-r17c/sysroot/usr/include -isystem /home/book/NDK/android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi -pie main.c


命令解析 :


$CC : arm-linux-androideabi-gcc 交叉編譯工具的臨時環境變量 , 執行 $CC 相當於執行 /home/book/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc 命令 ;

② 指定函數庫 :

–sysroot=/home/book/NDK/android-ndk-r17c/platforms/android-21/arch-arm

指定函數庫目錄 , 必須這麼寫 , 因爲真正要查找的是下層目錄中的 usr/lib 目錄 ;


③ 指定頭文件 : 這裏使用的是 -isystem , 不是 -isysroot , 因此目錄可以寫的隨意一些 ;


-isystem /home/book/NDK/android-ndk-r17c/sysroot/usr/include

-isystem /home/book/NDK/android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi


isysroot 指定的頭文件必須在 usr/include 中 , -isystem 不必 ;


④ 指定需要在 Android 手機執行配置 : -pie


4 . 編譯結果 :

在這裏插入圖片描述


該編譯出的 a.out 可執行文件 , 可以在 Android 手機中 , 使用命令行執行 ;

手機必須 root 纔可以執行 , 普通手機不能執行 ;

發佈了274 篇原創文章 · 獲贊 1018 · 訪問量 168萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章