Android平台交叉编译流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhou12314/article/details/74275838

一: 当我们在Android平台上开发一些软件的时候,有时不可避免的要用到一些用c/c++所编写的库。有些库有大神们已经封装好了在特定平台上对应的api,我们直接调用就可以,但是更多的库需要我们自己根据自己所需的特定的平台去进行编译。


二: 不同的目标平台都有明确的编译器,所以说在一个平台上编译另一个平台上所运行的程序就叫做交叉编译。常见的ARM平台的交叉编译工具链有:  arm-linux-gcc 这个主要用于编译linux内核,  arm-linux-androideabi-gcc 则是我们android平台的交叉编译链,意思就是如果我们安卓的应用程序想要使用c语言编写的第三方库,就必须用这个交叉编译工具链进行编译。


三: 获取交叉编译链

         一般获取交叉工具链我们可以通过android 官网中的ndk进行获取,地址:https://developer.android.google.cn/ndk/downloads/index.html  ,下载下来以后我们可以解压目录的 android-ndk-r14b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin  看到我们的arm处理所对应的交叉编译工具链,当然,其他处理器例如X86也有对应的处理器。


四: 交叉编译工具链的使用

       一般在我们有两种方式进行android平台上软件的移植,第一种方式就是直接用ndk中的ndk-build脚本进行编译,第二种则是利用ndk生成交叉编译工具链,然后我们用这个交叉编译工具链去编译我们的目标文件。

       

       a.ndk-build方式:

                 一般我们在android项目中作ndk开发是绝大多数都会用这种方式,这种方式需要我们在项目中创建 Android.mk  Application.mk文件,这里的Android.mk文件类似于我们一般常用的makefile,只是格式不同罢了。下面贴出来一个写好的makefile文件:   

Android.mk      

LOCAL_PATH:= $(call my-dir)    # 返回当前路径  
include $(CLEAR_VARS)          # 清除定义的变量
LOCAL_MODULE := JniDemo        # 生成模块的名字
LOCAL_SRC_FILES := test.cpp    # 需要编译的源文件
LOCAL_LDLIBS := -llog          # 编译所需要的库
LOCAL_SHARED_LIBRARIES := myadd#编译所需要的静态库
include $(BUILD_SHARED_LIBRARY)  #编译为静态库
Application.mk

APP_PLATFORM := android-19  #指定对于Android系统版本
APP_BUILD_SCRIPT := Android.mk #指定对应mk文件
APP_ABI := armeabi-v7a x86  #指定对于平台

上面列出的只是一些最基本最常用的用法, 由于本文不侧重mk语法的讲解,想要深入了解可以百度,资料很多。

                当根据自己的 情况写好自己的mk文件后(部分情况都是第三方库自带mk文件)我们通常创建一个jni目录,在这些文件及源文件放在该目录中,然后在该目录下执行ndk-build.sh 这个脚本,它会自动在我们jni的同级目录创建lib目录,生成的库文件都会放在这个库中。我们可以直接通过jni进行调用,关于jni调用第三方库的详细流程我会专门去讲。



        b.生成交叉编译工具链的方式:

                 这种方式一般适用于一些没有提供安卓版本的第三方库,我更多的情况也是使用的这种方式,需要我们自己去修改cmake或makefile或者configure 等一些编译或配置文件去实现Android版本的编译,那么如何生成交叉编译工具链呢?

                 一般我们的做法是: 

在我们所装的ndk的目录下执行:

./build/tools/make-standalone-toolchain.sh --platform=android-21

其中--platform是我们所对应的Android平台,更多的选项可以使用 --help进行查看,生成的压缩包会在终端提示,直接过去解压加入环境变量就可以使用了,使用方式基本与gcc 及 arm-linux-gcc 类似,(切记不要直接使用/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin 下面的编译链)


五:当我们编译类库的时候,我们如果是在studio下面用java开发的应用程序,需要使用jni去调用我们的so库中的c/c++函数。因为我目前使用的qt下面c++开发的android程序,所以把so库放在lib下面,直接就可以调用。


今天主要针对一些编译环境的搭建及编译的使用进行一些简单的讲解,原理其实并不难。我个人感觉在编译一些第三方库的过程中所出现的问题稍微麻烦一点,这方面好多错误在网上也查不到资料,一定要沉的住气,多分析提示的错误,多思考。 有这方面的问题可以加q交流: 553096041




猜你喜欢

转载自blog.csdn.net/zhou12314/article/details/74275838