ndk开发-交叉编译

为什么要使用交叉编译:
在linux系统一般使用c c++编译可执行程序或者so库文件。该程序只能在当前linux系统执行,为了将生成文件可以再android平台运行,必须使用交叉编译。ndk中提供了跟多android平台交叉编译链,所以首先下载ndk工具。

ndk旧版本与新版本的编译链工具有改变,所以新版本与旧版本交叉编译的环境配置不同。
NDK 官网:https://developer.android.google.cn/ndk
编译环境:ubuntu linux系统

一、ndk旧版本交叉编译。以android-ndk-r17c版本为例。

下载旧版本地址(后面改成自己想要下载的版本)
https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip
https://developer.android.google.cn/ndk/downloads/older_releases?hl=zh-cn#ndk-17c-downloads

1、在lunux系统搭建环境
下载android-ndk-r17c-linux-x86_64.zip版本
使用unzip android-ndk-r17c-linux-x86_64.zip 对压缩文件解压。
在这里插入图片描述

2、编写程序
1、编写可执行文件
编写一个简单的.c文件testadd.c,对这个文件编译一个可执行文件:

#include <stdio.h>
int main() {
 int a = 2;
 int b = 3;
 int sum = a + b;
 printf("a + b = %d\n",sum);
 return 0;
}

3、编译
命令:gcc testadd.c -o testadd ,编译可执行文件testadd。
gcc :为 linux系统原生的编译环境;
testadd.c: 为待编译的源文件;
-o :表示输出;
testadd: 输出的可执行文件(名字随便取)

4、运行
在linux平台运行程序结果:
在这里插入图片描述
将该可执行程序放到android设备/system/app(注意 需要将android设备root处理,否则没有权限),不能运行,报错如下。
在这里插入图片描述
使用交叉编译链编译。

二、使用android-ndk-r18b交叉编译链进行编译,生成可执行文件。
1、查看设备信息,选择正确编译链。
我的设备cpu平台为arm64,android10 ,api29。所以使用的编译链为aarch64-linux-android-gcc,路径
…/ndk/android-ndk-r17c/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc

2、编译
// 定义GCC 编译链路径
export GCC_NDK_17=/home/lily/ffmpeg/ndk/android-ndk-r17c/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc
![在这里插入图片描述](https://img-blog.csdnimg.cn/5c6413edcf544c67b080aa2c615c50fa.png
使用GCC_NDK_17编译链进行编译 ${GCC_NDK_17} testadd.c -o ndktestadd 报错,找不到头文件:
在这里插入图片描述
// 定义头文件及头文件所在库路径(我的设备是api29,但ndk17版本只有android-28,所以这里先使用android-28平台试一试)
库文件路径:/home/lily/ffmpeg/ndk/android-ndk-r17c/platforms/android-28/arch-arm64
头文件路径:/home/lily/ffmpeg/ndk/android-ndk-r17c/sysroot/usr/include
export FLAG_NDK_17=“–sysroot=/home/lily/ffmpeg/ndk/android-ndk-r17c/platforms/android-28/arch-arm64 -isystem /home/lily/ffmpeg/ndk/android-ndk-r17c/sysroot/usr/include”

再次编译:${GCC_NDK_17} ${FLAG_NDK_17} testadd.c -o ndktestadd 报错:
在这里插入图片描述
找不到ASM。
定义ASM路径:export ASM_NDK_17=/home/lily/ffmpeg/ndk/android-ndk-r17c/sysroot/usr/include/aarch64-linux-android
在这里插入图片描述
添加到FLAG:export FLAG_NDK_17=“–sysroot=/home/lily/ffmpeg/ndk/android-ndk-r17c/platforms/android-28/arch-arm64 -isystem /home/lily/ffmpeg/ndk/android-ndk-r17c/sysroot/usr/include -isystem ${ASM_NDK_17}”
在这里插入图片描述
再次编译:
${GCC_NDK_17} ${FLAG_NDK_17} testadd.c -o ndktestadd 生成可执行文件ndktestadd 。同样push到设备,是否能够执行。
在这里插入图片描述
修改编译命令,再次编译:
${GCC_NDK_17} ${FLAG_NDK_17} -pie testadd.c -o ndktestadd 可以生成可执行文件。同样push到设备,是否能够执行。
在这里插入图片描述
可以执行。交叉编译成功。
注意:本事例中使用ndk-19,ndk-20版本 没有对应gcc编译链,使用ndk-18版本,使用对应gcc编译链报错。因此,使用ndk-17版本验证。

以上命令使用的均为临时环境变量,下面将环境变量配置为全局环境变量。
打开文件:vi /home/lily/.bashrc(注意.bashrc为虚拟文件)在文件最下面添加一下路径:

#ndk-17
export NDK_17_ROOT="/home/lily/ffmpeg/ndk/android-ndk-r17c"
export NDK_17_HEAD="${NDK_17_ROOT}/sysroot/usr/include"
export NDK_17_ASM="${NDK_17_ROOT}/sysroot/usr/include/aarch64-linux-android"
export NDK_17_GCC_ARM64="${NDK_17_ROOT}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc"
export NDK_17_SO_ARM64="${NDK_17_ROOT}/platforms/android-28/arch-arm64"
export NDK_17_FLAG_ARM64="--sysroot=${NDK_17_SO_ARM64} -isystem ${NDK_17_HEAD} -isystem ${NDK_17_ASM}"

在这里插入图片描述
编译:${NDK_17_GCC_ARM64} ${NDK_17_FLAG_ARM64} -pie testadd.c -o ndktestadd

三、ndk-17 编译动/静态库

// testadd.h
#include <stdio.h>
int add();

// testadd.c
#include "testadd.h"
int add() {
 int a = 2;
 int b = 3;
 int sum = a + b;
 printf("a + b = %d\n",sum);
 return sum;
}

使用交叉编译动态库:
${NDK_17_GCC_ARM64} ${NDK_17_FLAG_ARM64} -fPIC -shared testadd.c -o libadd.so

在这里插入图片描述

使用交叉编译静态库
1)生成.o文件
${NDK_17_GCC_ARM64} ${NDK_17_FLAG_ARM64} -fPIC -c testadd.c -o testadd.o

在这里插入图片描述
2)生成.a静态库
全局环境添加编译静态库编译链:
export NDK_17_AR_ARM64=“${NDK_17_ROOT}/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar”
在这里插入图片描述
编译生成libtestadd.a
$NDK_17_AR_ARM64 rcs -o libtestadd.a testadd.o
在这里插入图片描述
以上,使用ndk-17版本交叉编译生成可执行文件、动态库、静态库完成。

四、ndk-25 编译动/静态库
工具目录:
在这里插入图片描述

首先设置环境变量,vi /home/lily/.bashrc ,如下图
在这里插入图片描述
交叉编译生成动态库:
${NDK_25_GCC_ARM64} -fPIC -shared testadd.c -o libadd25arm64.so
在这里插入图片描述
交叉编译生成静态库:
${NDK_25_GCC_ARM64} -fPIC -c testadd.c -o libadd25arm64.a
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值