从NDK获取Android C/C++交叉编译工具
我们经常需要将一些C/C++源码编译成本地二进制文件,直接在Android的Linux内核上运行,这就需要进行交叉编译。由于Android的运行环境和普通Linux有区别,所以常规针对ARM进行交叉编译得到的二进制,无法直接在Android环境运行。此时需要基于Android环境进行交叉编译,这是有两种方式:一种是编写Android.mk,在安装源码结构下依靠Android的编译系统搞定;另一种是
我们经常需要将一些C/C++源码编译成本地二进制文件,直接在Android的Linux内核上运行,这就需要进行交叉编译。由于Android的运行环境和普通Linux有区别,所以常规针对ARM进行交叉编译得到的二进制,无法直接在Android环境运行。此时需要基于Android环境进行交叉编译,这是有两种方式:一种是编写Android.mk,在安装源码结构下依靠Android的编译系统搞定;另一种是脱离Android源码体系,利用独立的Android交叉编译工具链,并适当修改Makefile和源码完成交叉编译。第一种适用于目标源码结构比较简单的情况;而当目标源码的Makefile组织非常复杂时,第二种则是更好的选择。本文介绍第二种方式,即搭建Android独立交叉编译环境,编译出可以在Android上运行的二进制程序(ELF).
1、NDK下载
https://developer.android.google.cn/ndk/downloads/index.html
根据宿主机选择NDK版本,对于在Ubuntu下编译,选择 Linux版本的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.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中不支持,对这些函数,将其干掉或者替换,或者自己重写,等等。下面总结下通常要做的几点:
- 将Android工具链中的所有文件设置可读可写可执行
~/android-build: chmod 777 *
如果不设置权限,可能出现err:cannot find crt0.o等各种错误。
- 查看目标源码的Makefile文件,将交叉编译器指定为咱们安装的交叉编译器
通常是修改CC环境变量
CC= /path_to_your_cross_compiler/you_cross_compiler_xxx_gcc
- CFLAGS加上“-pie -fPIE”选项,否则报错:
error: only position independent executables (PIE) are supported
- 一下编译参数不支持,要去掉
#PTHREAD_LIBS= -lpthread -lrt
完成以上步骤,就可以测试一下编译工具链了。
4、新建一个hello.c文件:
#include <stdio.h>
int main(void)
{
printf("Hello,world!\n");
}
编译:/Users/nickyang/android-build/bin/aarch64-linux-android-gcc -pie -fPIE hello.c -o hello
使用64位gcc编译的到64位ELF文件,push都64位的ARM64的Android设备上,正常情况可以顺利执行hello程序。
更多推荐
所有评论(0)