Android獨立交叉編譯環境搭建

我們經常需將一些C/C++源碼編譯成本地二進制,直接在android的linux內核上運行,這是就需要進行交叉編譯。由於Android的運行環境核普通Linux又區別,所以常規方式針對ARM進行交叉編譯得到的二進制,無法直接運行在Android環境上。我們需要機遇Android環境進行交叉編譯,這時有兩種方式:一種是編寫Android.mk,在安卓源碼結構下依靠安卓的編譯系統搞定;另一種方式是脫離android源碼體系,利用獨立的android交叉編譯工具鏈,並適當修改目標代碼的Makefile(必要時還要修改源碼)完成交叉編譯。第一種方式適用於編譯目標源碼結構簡單的情況;當目標源碼的Makefile組織非常複雜的時候,第二種方式則是更好的選擇。本文介紹第二種方式,即搭建Android獨立交叉編譯環境,編譯出可以在Android(默認基於ARM64)上運行的二進制(ELF)程序。

 

1、NDK下載

https://developer.android.google.cn/ndk/downloads/index.html

https://developer.android.google.cn/ndk/downloads/

 

本文以宿主機系統MacOS爲例,所以下載MacOSX版本的ndk包

 

2、利用NDK安裝android交叉編譯工具鏈

解壓NDK後,進入buildtools目錄

NickPro:android-ndk-r14b nickyang$ cd build/tools/

NickPro:tools nickyang$ pwd

/Users/nickyang/android-ndk-r14b/build/tools

 

NDK提供了兩個腳步用於一鍵化構建gcc工具鏈:

make-standalone-toolchain.sh

make_standalone_toolchain.py

 

我們使用py版本的,按照官方說明,sh版本將被淘汰

./make_standalone_toolchain.py --arch arm64 --api 24 --unified-headers --install-dir ~/android-build

 

參數解釋:

—arch : 交叉編譯目標平臺

--unified-header: 使用libc頭文件,相關解釋可參考:

Https://android.googlesource.com/platform/ndk.git/+/ndk-r14-release/docs/UnifiedHearders.md

—api: Android系統版本

--install-dir:生成的交叉編譯工具鏈輸出位置,可自行設置

 

3、編譯方法

通常類Unix系統下,C/C++源碼都是通過Makefile組織的(或者通過一個configure腳本生成Makefile),所以我們要閱讀其Makefile(或configure腳步),將其編譯器指定爲我們的android交叉編譯器,然後在編譯過程中會遇到一下函數爲定義等錯誤,這是因爲andorid的bionic C庫和純Linux的C庫差別導致的,比如某些函數在bionic中不支持,對這些函數,將其幹掉或者替換,或者自己重寫,等等。下面總結下通常要做的幾點:

1)查看目標源碼的Makefile文件,將交叉編譯器指定爲咱們安裝的交叉編譯器

通常是修改CC環境變量

CC= /path_to_your_cross_compiler/you_cross_compiler_xxx_gcc

 

2)CFLAGS加上“-pie -fPIE”選項,否則報錯:

error: only position independent executables (PIE) are supported

 

3) 一下編譯參數不支持,要去掉

#PTHREAD_LIBS= -lpthread -lrt

 

4、小試牛刀

新建一個hello.c文件:

複製代碼

#include <stdio.h>

int main(void)
{
    printf("Hello, this is a program compiled by ndk-cross-compiler!\n");
}

複製代碼

 編譯:

/Users/nickyang/android-build/bin/aarch64-linux-android-gcc -pie -fPIE hello.c -o hello

推送到android設備並執行(默認是ARM64架構):

複製代碼

NickPro:tmp nickyang$ adb push hello /data
hello: 1 file pushed. 0.1 MB/s (7808 bytes in 0.112s)
NickPro:tmp nickyang$ adb shell
generic_arm64:/ # cd data
generic_arm64:/data # ls -l | grep hello
-rwxrwxrwx  1 root     root     7808 2018-02-18 16:20 hello
generic_arm64:/data # ./hello
Hello, this is a program compiled by ndk-cross-compiler!
10|generic_arm64:/data #

複製代碼

執行成功,順利輸出打印!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章