Android NDK 12 交叉編譯

前言

簡(jiǎn)單地說访忿,交叉編譯就是程序的編譯的環(huán)境和它的運(yùn)行的環(huán)境不一樣撵幽,即在一個(gè)平臺(tái)上生成另一個(gè)平臺(tái)上的可執(zhí)行代碼是牢。需要使用交叉編譯的主要原因是由于目標(biāo)環(huán)境中各種資源都相對(duì)有限僵井,所以很難直接進(jìn)行本地編譯。

一驳棱、交叉編譯工具鏈

1.1批什、什么是交叉編譯工具鏈

交叉工具鏈?zhǔn)侵缚梢陨赡繕?biāo)環(huán)境可運(yùn)行代碼的工具集。在 Linux 系統(tǒng)中的編譯工具鏈包括以下一些工具社搅,編譯器 gcc驻债,鏈接器 ld,歸檔工具 ar 等形葬,如果在 Linux 環(huán)境中交叉編譯 Android 系統(tǒng)環(huán)境可運(yùn)行的代碼合呐,是不能直接使用 Linux 下的編譯工具的,而應(yīng)該使用 Android NDK 里的工具鏈笙以,它們對(duì)應(yīng)的名子為 arm-linux-android-gcc合砂,arm-linux-android-ld 等。

1.2源织、交叉編譯工具的命名規(guī)則

交叉編譯工具的命名形式如下所示:

arch-[vendor]-kernel-system-toolname

它由五部分組成翩伪,下面分別解釋一下每部分的含義:

  1. arch,指的是 CPU 架構(gòu)谈息,一般包括如下幾種架構(gòu):
  • arm
  • mips
  • powerpc
  • x86
  • x86_64
  1. verdor缘屹,一般指的是生產(chǎn)廠商,如果沒有生產(chǎn)廠商可以為空侠仇。
  2. kernel轻姿,指的目標(biāo)環(huán)境使用的 kernel,以 android 為例逻炊,它使用的是 linux 內(nèi)核互亮,所以在這部分會(huì)填寫為 linux。
  3. system余素,指的是哪個(gè)系統(tǒng)豹休,如:
  • androideabi
  • android
  1. toolname: 指的是 gcc,ld桨吊,ar 等威根。

所以可以看到 android 的編譯工具的名子會(huì)寫成 arm-linux-andirod-gcc凤巨。

1.3、交叉編譯常用變量說明

在做交叉編譯時(shí)洛搀,常會(huì)在腳本中定義一些環(huán)境變量以方便我們命名用敢茁,常用的環(huán)境變量如下:

  • PREFIX: 指明交叉編譯后輸出的目錄;
  • ARCH: 指明交叉編譯后輸出的 CPU 架構(gòu)留美;
  • CROSS-PREFIX:指明交叉編譯前輟 arch-vender-kernel-system彰檬;
  • SYSROOT: 指明交叉編譯目標(biāo)機(jī)器的頭文件和庫(kù)文件目錄
  • TOOLCHAIN: 指明交叉編譯工具鏈的位置谎砾;
  • PLATFROM:指明交叉編譯時(shí)使用的是哪個(gè)版本的的頭文件和庫(kù)文件僧叉,它是 SYSROOT 的一部分;
  • ANDROID_NDK: 指明 Android NDK 所在目錄棺榔。

二瓶堕、如何進(jìn)行交叉編譯

通過設(shè)置 configure 參數(shù)來生成交叉編譯的 Makefile 文件:

  • arch 指定架構(gòu);
  • cross-prefix 交叉編譯工具鏈前輟症歇;
  • sys root 交叉編譯樹的根郎笆。

例子:

以 ffmpeg 的交叉編譯為例,來看一下如何生成交叉編譯的 Makefile:

./configure --target-os=linux --arch=arm --enable-cross-compile --cross-prefix=arm-linux-androideabi-
--sysroot=~Library/Android/sdk/ndk-bundle/platforms/android-9/arch-arm

執(zhí)行后的結(jié)果如下:

install prefix            /usr/local
source path               .
C compiler                arm-linux-androideabi-gcc
C library                 bionic
host C compiler           gcc
host C library
ARCH                      arm (armv5te)

三忘晤、使用 ndk-build 編譯 NDK 程序

Google 提供了一系列腳本工具宛蚓,以方便大家做 Android NDK 方面的開發(fā),其中最重要的是 ndk-build 腳本设塔。有了這些腳本凄吏,開發(fā)者就不必再定義各種環(huán)境變量,只需要提供兩個(gè) Makefile 片段指明要編譯哪些 C/C++文件闰蛔,生成哪個(gè)目標(biāo)環(huán)境的程序就好了痕钢。ndk-build 腳本工具會(huì)自動(dòng)檢測(cè)各種環(huán)境變量、目標(biāo)環(huán)境編譯器等序六,最終完成交叉編譯任连。

3.1 NDK-BUILD 的工作

先來看一下 ndk-build,通過查看 ndk-build 源碼可以看到例诀,它執(zhí)行的是類似于

$GNUMAKE -f <ndk>/build/core/build-local.mk <parameters> 

這樣的命令随抠,實(shí)際就是自動(dòng)檢測(cè)并設(shè)置環(huán)境變量。執(zhí)行 ndk-build NDK_LOG=1 命令繁涂,會(huì)看到下面的信息:

Android NDK: NDK installation path auto-detected:
Android NDK: GNU Make version 3.81 detected
Android NDK: Host OS was auto-detected: darwin
Android NDK: Host operating system detected: darwin
Android NDK: Host CPU was auto-detected: x86
Android NDK: HOST_TAG set to darwin-x86
Android NDK: Host tools prebuilt directory:
#這里檢測(cè)到編譯器地址
~/Library/Android/sdk/ndk-bundle/prebuilt/darwin-x86_64/bin
Android NDK: Found platform root directory:
#這里檢測(cè)到 platforms 目錄地址
~/Library/Android/sdk/ndk-bundle/platforms
#下面列出了所有支持的 platform
Android NDK: Found supported platforms: android-12 android-13 android-14 android-15 android-16 android-17
android-18 android-19 android-21 android-22 android-23 android-24 android-26 android-9
#列出支持的目標(biāo)環(huán)境
Android NDK: PLATFORM android-12 supports: arm mips x86
......
#下面是每個(gè)目標(biāo)環(huán)境的的環(huán)境樹
Android NDK:   ABI arm sysroot is: /Users/lichao/Library/Android/sdk/ndk-bundle/platforms/android-12/arch-arm
Android NDK:   ABI mips sysroot is: /Users/lichao/Library/Android/sdk/ndk-bundle/platforms/android-12/arch-mips
Android NDK:   ABI x86 sysroot is: /Users/lichao/Library/Android/sdk/ndk-bundle/platforms/android-12/arch-x86

通過上面的分析就應(yīng)該清楚 ndk-build 主要作什么事情了拱她。既然 Google 已經(jīng)給我們提供了這么方便的交叉編譯工具,那作為開發(fā)者還需要做下面兩件事兒:

  1. 編寫 C/C++ 代碼扔罪。

  2. 編寫 Android.mk 和 Application.mk 兩個(gè) Makefile 片段秉沼。

3.2、Android.mk 與 Application.mk

下面就來看一下兩個(gè) Makefile 片段 Android.mk 和 Application.mk 是做什么用的。

  • Android.mk:目的是用于向構(gòu)建系統(tǒng)描述源文件和共享庫(kù)氧猬,它位于 $PROJECT/jni/ 目錄中
  • Application.mk:目的是描述在你的應(yīng)用程序中所需要的模塊(即靜態(tài)庫(kù)或動(dòng)態(tài)庫(kù))坏瘩,它也位于 $PROJECT/jni/ 目錄中盅抚。

3.2.1、Android.mk

先來看一下 Android.mk 的例子:

LOCAL_PATH       :=  $(call my-dir)
include              $(CLEAR_VARS)
LOCAL_MODULE     :=  hello_jni
LOCAL_SRC_FILES  :=  hello_jni.c
include              $(BUILD_SHARED_LIBRARY)

每行語(yǔ)句的作用如下:

  • LOCAL_PATH

    在 Android.mk 中必須首先定義 LOCAL_PATH 變量倔矾,此變量表示源文件在開發(fā)樹中的位置妄均。構(gòu)建系統(tǒng)提供的宏函數(shù) my-dir 將返回當(dāng)前目錄(包含 Android.mk 文件本身的目錄)的路徑。

  • CLEAR_VARS

    CLEAR_VARS 變量指向特殊 GNU Makefile哪自,可清除許多 LOCAL_XXX 變量丰包,例如 LOCAL_MODULE、LOCAL_SRC_FILES 和 LOCAL_STATIC_LIBRARIES壤巷。

請(qǐng)注意邑彪,它不會(huì)清除 LOCAL_PATH。此變量必須保留其值胧华,因?yàn)橄到y(tǒng)在單一 GNU Make 執(zhí)行環(huán)境(其中所有變量都是全局的)中解析所有構(gòu)建控制文件寄症。在描述每個(gè)模塊之前,必須聲明(重新聲明)此變量矩动。

  • LOCAL_MODULE

    變量將存儲(chǔ)要構(gòu)建的模塊的名稱有巧。

  • LOCAL_SRC_FILES

    LOCAL_SRC_FILES 枚舉源文件,以空格分隔多個(gè)文件悲没。LOCAL_SRC_FILES 變量必須包含要構(gòu)建到模塊中的 C 和/或 C++ 源文件列表篮迎。

  • BUILD_SHARED_LIBRARY

    這一行幫助系統(tǒng)將所有內(nèi)容連接到一起。

3.2.2示姿、Application.mk

再來看一下 Application.mk 的例子:

APP_PLATFORM := android-9
APP_STL := gnustl_static
APP_CFLAGS := -Wno-error=format-security
APP_ABI := armeabi armeabi-v7a arm64-v8a
APP_OPTION := release

每行的作用如下:

  • APP_PLATFORM

此變量包含目標(biāo) Android 平臺(tái)的名稱甜橱。NDK API 級(jí)別與 Android 版本對(duì)照表如下:

NDK 支持的 API 級(jí)別 Android 版本
9 2.3 到 3.0.x
12 3.1.x
13 3.2
14 4.0 到 4.0.2
15 4.0.3 和 4.0.4
16 4.1 和 4.1.1
17 4.2 和 4.2.2
18 4.3
19 4.4
21 4.4W 和 5.0
  • APP_STL

    默認(rèn)情況下,NDK 構(gòu)建系統(tǒng)為 Android 系統(tǒng)提供的最小 C++ 運(yùn)行時(shí)庫(kù)(system/lib/libstdc++.so) 栈戳。該指令可以讓您在自己的應(yīng)用中使用或鏈接的替代 C++ 實(shí)現(xiàn)渗鬼。

  • APP_CFLAGS

    構(gòu)建系統(tǒng)在僅構(gòu)建 C++ 源文件時(shí)傳遞到編譯器的一組 C++ 編譯器標(biāo)志。

  • APP_ABI

    您可以使用 APP_ABI 選擇編譯出不同的 ABI 目標(biāo)環(huán)境代碼荧琼。

  • APP_OPTION

    可定義變量為 release 或 debug譬胎。在構(gòu)建應(yīng)用的模塊時(shí)可使用它來更改優(yōu)化級(jí)別。

通過上面的分析命锄,我們可以知道 Google 為了開發(fā)者更容易的開發(fā) NDK 程序堰乔,給我們提供了一套交叉編譯的工具,大大降低了開發(fā) NDK 程序的難度脐恩。

原文連接:Linux/Mac 交叉編譯 Android 程序 & 深入理解使用ndk-build編譯NDK程序

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末镐侯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌苟翻,老刑警劉巖韵卤,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異崇猫,居然都是意外死亡沈条,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門诅炉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜡歹,“玉大人,你說我怎么就攤上這事涕烧≡露” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵议纯,是天一觀的道長(zhǎng)父款。 經(jīng)常有香客問我,道長(zhǎng)瞻凤,這世上最難降的妖魔是什么铛漓? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮鲫构,結(jié)果婚禮上浓恶,老公的妹妹穿的比我還像新娘。我一直安慰自己结笨,他們只是感情好包晰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炕吸,像睡著了一般伐憾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赫模,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天树肃,我揣著相機(jī)與錄音,去河邊找鬼瀑罗。 笑死胸嘴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的斩祭。 我是一名探鬼主播劣像,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼摧玫!你這毒婦竟也來了耳奕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎屋群,沒想到半個(gè)月后闸婴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芍躏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年邪乍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纸肉。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡溺欧,死狀恐怖喊熟,靈堂內(nèi)的尸體忽然破棺而出柏肪,到底是詐尸還是另有隱情,我是刑警寧澤芥牌,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布烦味,位于F島的核電站,受9級(jí)特大地震影響壁拉,放射性物質(zhì)發(fā)生泄漏谬俄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一弃理、第九天 我趴在偏房一處隱蔽的房頂上張望溃论。 院中可真熱鬧,春花似錦痘昌、人聲如沸钥勋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)算灸。三九已至,卻和暖如春驻啤,著一層夾襖步出監(jiān)牢的瞬間菲驴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工骑冗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赊瞬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓贼涩,卻偏偏與公主長(zhǎng)得像森逮,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子磁携,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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

  • Android游戲開發(fā)實(shí)踐(1)之NDK與JNI開發(fā)02 承接上篇Android游戲開發(fā)實(shí)踐(1)之NDK與JNI...
    AlphaGL閱讀 3,750評(píng)論 0 24
  • 一褒侧、NDK產(chǎn)生的背景 Android平臺(tái)從誕生起,就已經(jīng)支持C、C++開發(fā)闷供。眾所周知烟央,Android的SDK基于J...
    Ten_Minutes閱讀 3,499評(píng)論 1 27
  • 翻譯自docs/ANDROID-MK.html Indroduction 本篇文檔描述Andrid.mk編譯文件的...
    記得柒叁貳閱讀 17,355評(píng)論 0 15
  • 在我們傳統(tǒng)看來,孕期有很多忌諱歪脏,很多事情都不能做疑俭,一些場(chǎng)合更是不待見孕婦。近日婿失,臺(tái)灣一位準(zhǔn)媽媽就遭遇了這么一件事:...
    瞧那一家子閱讀 774評(píng)論 0 0
  • 默日钞艇,末日,這是每一個(gè)人都不希望出現(xiàn)的日子豪硅。 自從默日出生哩照,家里就開始死人,他的名字也定了下來懒浮。默日飘弧,默字與末同...
    沐玥卿閱讀 456評(píng)論 1 2