10、NDK交叉编译小记

前言:前两天总结了编译、交叉编译,其中交叉编译主要指的是嵌入式中交叉编译,这一篇重点来总结下andriod开发中的交叉编译,方便以后温故知新。

ubuntu:20版本

NDK:r17c和r21b

一、概念

NDK(Native Development Kit缩写)一种基于原生程序接口的软件开发工具包,可以让您在 Android 应用中利用 C 和 C++ 代码的工具。通过此工具开发的程序直接在本地运行,而不是虚拟机。

在Android中,NDK是一系列工具的集合,主要用于扩展Android SDK。NDK提供了一系列的工具可以帮助开发者快速的开发C或C++的动态库,并能自动将so和Java应用一起打包成apk。同时,NDK还集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so文件。

这就是NDK,功能很强大,笔者此篇博客主要记录下NDK交叉编译的功能。

1.1 基础概念

ARM :是嵌入式中的一种架构,全称为Advanced RISC Machine,能够理解为ARM处理器。

ABI(Application Binary Interface):应用程序二进制接口 描述了应用程序和操做系统之间,一个应用和它的库之间,或者应用的组成部分之间的低接口。

ABI和CPU关系:大部分cpu都支持多于一种的ABI。当一个应用安装在设备上,只有该设备支持的CPU架构对应的.so文件会被安装。

CPU架构\ABIarmeabiarmeabi-v7aarm64-v8amipsmips64x86x86_64
ARMV5
ARMV7
ARMV8
MIPS
MIPS64
x86
x86_64

1.2 NDK中交叉编译工具

1.3 版本变迁

从NDK 16 开始,交叉编译器就不再支持GCC了,并会在18版本后移除掉

GCC被移除了,只有Clang了 

NDK R19 独立工具链不需要了,意思是,不用自己去通过NDK提供的make_standalone_toolchain.sh脚本来生成我们想要的工具链,因为,你想要(可用)的NDK中都已经给你提供好了,如果没有你想要的,说明,你想的有点多了。

二、NDK交叉编译工具链

首先明确一点,NDK 已经为我们提供了交叉编译工具链(交叉编译工具见1.2小节),用来编译第三方 C/C++ 库到 Android 中使用,比如 FFmpeg、x264、RTMPDump 等等。

如何使用NDK工具,目前笔者查到资料主要有两种

  • 下载好NDK后,通过指定工具链(NDK中提供的)路径完成。
  • 使用NDK提供的make_standalone_toolchain.py脚本来生成我们想要的工具链。

通过NDK官方的版本变迁可以看到,NDK R19版本,独立工具链不需要了,意思是,不用自己去通过NDK提供的make_standalone_toolchain.sh脚本来生成我们想要的工具链。

2.1 独立工具链

如果还是希望自定义交叉编译工具可以使用NDK r19之前的版本,不建议使用r19之后的版本进行自定义交叉编译工具,除非你准备把编译后的动\静态库用于比较老的cpu架构中,现在比较新的cpu架构下使用ndk交叉编译后的文件还是建议使用较新的ndk版本。

生成独立工具链方法:

NDK 为我们提供了 make_standalone_toolchain.py 脚本来生成编译工具链。它的目录在 build/tools/ 下

使用是比较简单,但是作为小白的我,还是出现了几个问题,并不是命令的问题,而是对于linux的不熟导致的。

第一个问题:

komla@ubuntu:~/NDK$ /android-ndk-r17c/build/tools/make-standalone-toolchain.sh --toolchain=arm-linux-androideabi-4.9 --platform=android-21 --install-dir=my_ndk_toolchain


bash: /android-ndk-r17c/build/tools/make-standalone-toolchain.sh: No such file or directory

看哈,没有这个文件夹,就是路径格式不会写。我在NDK这个文件夹下面打开的命令台,然后/android-ndk-r17c/...,这样是找不到android-ndk-r17c这个文件夹的,需要在最前面加一个"."

"./android-ndk-r17c/...",这样才能找到这个文件夹。

第二个问题:

我是事先创建了一个my_ndk_toolchain文件夹,用于存放生成的交叉编译工具链,

然后执行下面命令

komla@ubuntu:~/NDK$ ./android-ndk-r17c/build/tools/make-standalone-toolchain.sh --toolchain=arm-linux-androideabi-4.9 --platform=android-21 --install-dir=my_ndk_toolchain

 输出结果如下,意思就是,这个交叉编译工具链(其实就是这个文件夹,只是我起的名字有误解,应该按照命名规范去起名)已经已经存在了,没法重新安装,除非使用 --force才行。


HOST_OS=linux
HOST_EXE=
HOST_ARCH=x86_64
HOST_TAG=linux-x86_64
HOST_NUM_CPUS=2
BUILD_NUM_CPUS=4
Auto-config: --arch=arm
Refusing to clobber existing install directory: my_ndk_toolchain.

make-standalone-toolchain.sh used to install a new toolchain into an existing
directory. This is not desirable, as it will not clean up any stale files. If
you wish to remove the install directory before creation, pass --force.

接着改,执行成功了,所以,要么事先创建文件夹,要么就在命令最后加上 --force,建议后者,因为可能会修改命令内容重新生成独立交叉编译工具,这样就避免了反复手动创建文件夹了。

komla@ubuntu:~/NDK$ ./android-ndk-r17c/build/tools/make-standalone-toolchain.sh --toolchain=arm-linux-androideabi-4.9 --platform=android-21 --install-dir=my_ndk_toolchain --force

HOST_OS=linux
HOST_EXE=
HOST_ARCH=x86_64
HOST_TAG=linux-x86_64
HOST_NUM_CPUS=2
BUILD_NUM_CPUS=4
Auto-config: --arch=arm
Toolchain installed to my_ndk_toolchain.

可以看到已经为我们生成了 arm-linux-androideabi, 在 sysroot 下包含了系统提供的库以及头文件。在 bin 目录下包含了交叉编译工具,比如 clang、gcc、ar、as、nm、strip 等等。主要做的工作就是将原先在 ndk 目录下的各目录结构归纳到一个目录。

第三个问题:

不知道出现这个问题的原因是我第一个问题中路径没设置好导致的,还是真的因为没有安装python导致的,这个问题其实是最先出现的,所以我就按这篇博客的建议安装了python,然后下面的问题解决后也没出现这个问题了。 

说明:

1、网上有很多文章的命令是这样的

$NDK/build/tools/make_standalone_toolchain.py ...

他这里的$NDK 是 NDK 的安装根目录。这应该是把下载的NDK配置到环境中了,所以这里的路径要根据自己解压后的NDK路径进行写。

2、命令简析

./android-ndk-r17c/build/tools/make-standalone-toolchain.sh   执行下载的NDK目录下make-standalone-toolchain.sh脚本; 

 --toolchain=arm-linux-androideabi-4.9 指独立出来的工具链哪种用途的编译,arm(arm-linux-androideabi-4.8),X86(x86-4.8)或MIPS(mipsel-linux-android-4.8),可cd toolchains中查看并选择适合的类型,我这里使用的是嵌入式;

--platform=android-21 指工具链将使用哪个版本的Android API,可cd android-ndk-r7c/platform中查看,我这里使用的是Android-21; 

--install-dir=my_ndk_toolchain 生成的编译工具链安装目录;

--force:强制清空安装目录

其实还有一些命令没用到,使用了默认的值,比如 

--arch=arm(默认是arm)

2.2 官方交叉编译工具

在 NDK 19 开始就不需要使用独立工具链了, 在 toolchains/llvm/ 下已经提供好了编译工具, 读者自行去下载进入目录看看,和独立工具链编译出来的结构非常类似,不过它比较全的是针对不同平台版本。

可以看到,llvm和其他工具链位于同一级目录,所以作用是一样的。

 

基本上能满足开发者使用。 

三、使用

3.1 ndk环境配置

环境配置挺简单,但依然配置了小半天,原因还是这个路径问题,哎,有时间得好好整整这个linux的路径问题。

使用命令:

  1. sudo gedit  /etc/profile 
  2. sudo gedit ~/.bashrc
  3. 上面两个命令都可以,都是通过gedit进行编辑,只是一个编辑的是/etc/profile,另一个是.bashrc,根据自己的习惯选择其中一个就可以

上面命令执行完,不出意外就会跳出来一个可编辑的文档,然后根据网上提供的信息,加上对应信息,点击保存,然后叉掉就可以。

保存,叉掉后回到控制台,然后输入

1、source /etc/profile 你如果打开时候使用sudo gedit  /etc/profile 命令就用这个,

2、source ~/.bashrc  你如果打开时候使用sudo gedit ~/.bashrc 命令就用这个,

3、说白了,就是你打开的哪个文件,就在这里soruce 哪个文件

正常,上面配置完就配置好了环境了,下面就验证了,

ndk-build -v

哎,找了好多资料都没找到原因,后来发现,在打开的文档中添加路径时候错了,ndk的路径应该是下面的这个,多一个komla级

/home/komla/NDK/android-ndk-r21b

 可是我通过目录看就是不带komla啊

 可是通过pwd命令看,确实是,就这个命令,哎有时间好好看看linux命令

既然,问题原因找到了,下面改下

3.2 使用 

说明下,按照官网的去敲命令即可,只是要注意几点

  • "\"这是个换行符,可有可不有;
  • "$NDK",其中"$"是linux系统下的标识符,"NDK"是前面配置的环境变量名称,$和NDK是一起使用的,代表取环境变量中NDK代表的东西
  • 因为不同人不同需求,所以在下载ndk的时候有些是下载的window版本的,有些是linux的,有些是mac下的,所以这里官网没有写哪个,而是用HOST_TAG代表了,可根据自己的实际情况改下。

我两种方式都试了下,都可以生成,只是生成的位置,默认是主目录下,然后是一个a.out的二进制文件,并不是我想象中的.so或者.a文件,这里应该是我没有设置成输出.so或.a文件,希望懂得大佬给点建议。

踩坑:

这里有个疑惑,我从bin目录下打开终端,然后执行clang的命令,提示我找不到这个命令,按理说,就是指定clang的路径啊,但是找不到,不知道什么原因,希望懂的大佬指点迷津。

三、引用文献:

1、关于Android arm64-v8a、armeabi-v7a、armeabi、x86等CPU下的so文件兼容问题_晚安08的博客-CSDN博客_arm64-v8a

2、关于Android arm64-v8a、armeabi-v7a、armeabi、x86等CPU下的so文件兼容问题_晚安08的博客-CSDN博客_arm64-v8a

3、C++学习(一九九)aarch64-linux-android-4.9 arm-linux-androideabi-4.9 llvm关系_hankern的博客-CSDN博客_aarch64-linux-android-4.9

4、交叉编译-如何编译Android平台的可执行程序 - 简书

5、Android 编译 ffmpeg-4.2.2 + libx264 (NDK17以后使用的是Clang)_张雨zy的博客-CSDN博客6、NDK r21编译FFmpeg 4.2.2+x264及使用ffmpeg转换视频文件_来来走走的博客-CSDN博客

7、android交叉编译工具链,NDK 交叉编译工具链使用_神秘墓后煮shi者的博客-CSDN博客

8、独立工具链(已弃用)  |  Android NDK  |  Android Developers

 10、NDK toolchain 交叉编译配置 - 简书

11、NDK Clang 编译 FFmpeg 4.4.1 + fdk-aac 2.0.2 + x264 20191217_TYYJ-洪伟的博客-CSDN博客_ndk编译器

12、ubuntu-20.04.4环境下ndk-r21e 编译libiconv_awa2004的博客-CSDN博客_ubuntu 安装libiconv

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值