Android NDK编程中Application.mk和Android.mk写法

在Android编程中NDK编程是十分重要的一个部分, 利用NDK可以在很大程度上提高效率。由于,Android使用java语言,有时需要用C/C++语言完成一些耗时的工作,这就可以有NDK来完成。NDK编程中最重要的是要写好Makefile文件,这个文件说明了利用C/C++写的程序如何被编译为Android可用的so包。接下来我们就谈一谈Makefile文件的两个重要部分:Application.mk和Android.mk文件的写法。

注意:若使用Android studio进行NDK编程,需要配置的位Makefilet和gradle文件,这里我们主要介绍Eclipse下Application.mk和Android.mk的写法。

  1. Application.mk
  2. Android.mk

Application.mk


Application.mk 文件实际上是定义要编译的多个变量的微小 GNU Makefile 片段。 它通常位于 PROJECT/jni/ 下,其中 PROJECT 指向应用的项目目录。
Application.mk中常用的变量有以下几个:

  • APP_PLATFORM
  • NDK_TOOLCHAIN_VERSION
  • APP_ABI
  • APP_STL

NDK_TOOLCHAIN_VERSION
此变主要是选择 GCC 编译器的版本。 其中,64 位 ABI 默认使用版本 4.9 ,32 位 ABI 默认使用版本 4.8。要选择 Clang 的版本,请将此变量定义为 clang3.4、clang3.5 或 clang。

NDK_TOOLCHAIN_VERSION := 4.9

APP_PLATFORM
此变量主要是说明 Android 平台的名称。例如,android-3 指定 Android 1.5 系统映像。 如下代码则是说明使用Android14作为平台。

APP_PLATFORM := android-14

APP_ABI
默认情况下,NDK 构建系统为 armeabi ABI 生成机器代码。这个变量是为了生成不同架构下使用的so包,此机器代码对应于基于 ARMv5TE、采用软件浮点运算的 CPU, 可以使选用以下不同的 ABI:

armeabi-v7a:基于 ARMv7 的设备上的硬件 FPU 指令
arm64-v8a:ARMv8 AArch64
x86:IA-32
x86_64:Intel64
mips:MIPS32
mips64:MIPS64 (r6)
all:所有支持的指令集

APP_ABI := armeabi-v7a

APP_STL
用于指定在使用C++进行编程时所依赖的标准库,可以使用静态或动态链接库的方式。默认情况下,NDK 构建系统为 Android 系统提供的最小 C++ 运行时库 (system/lib/libstdc++.so) 提供 C++ 标头。可以通过给APP_STL赋值来修改所要依赖的链接库,APP_STL的值参考如下:
Android NDK编程中Application.mk和Android.mk写法_第1张图片
注意:Google官方推荐使用stlport_static库来进行C++链接,但是之前项目里使用这个库的时候依然会出现一些问题,当我们使用第三方静态库来编译动态库时,若静态库中有iostream库中的语句存在,则编译总是出错,找了很多资料之后好像这是一个bug,所以最后使用gnustl_shared动态库来代替静态库了。如果采用动态库时,需要注意目标设备中是否具有该动态库支持文件,如果没有需要将NDK中的改文件一起拷贝。

APP_STL := gnustl_shared

Android.mk


Android.mk也是一个轻量级的Makefile,其将C/C++源码组织到一个个module中,用这样一个个module来编译需要的静态库或动态库。一个Android.mk文件可以有一个,也可以是多个module,modules之间也可以有依赖关系。

Android.mk使用NDK提供的宏、变量以及模块描述变量,这些宏、变量以及变量的赋值共同组成了Android.mk文件,其在NDK编译中各尽其责,指导着NDK的编译。
宏:my-dir、all-subdir-makefiles等,通过‘$(call )’来调用,返回文本信息。
变量:包括CLEAR_VARS、BUILD_SHARED_LIBRARY、TARGET_ARCH等,由NDK编译系统提供,并且在Android.mk文件被解析前就已经存在。Android.mk文件有可能被多次解析,因此每次解析时这些变量的值都有可能不同。

首先,Android.mk一般会有如下语句:

LOCAL_PATH:=$(call my-dir)

这个语句的意思是将LOCAL_PATH变量定义成本文件所在目录路径。
使用如下一个例子来介绍Android.mk中一些宏和变量的含义:

include $(CLEAR_VARS)       //编译静态/动态库的开始,用于去除这之前的编译环境,必须要

LOCAL_SRC_FILES:= \         //需要编译为静态/动态库的源文件
    hello.cpp \
    world.cpp \

LOCAL_SHARED_LIBRARIES := \   //编译静态/动态库需要依赖的第三方库
    lib1 \
    lib2 \
    lib3 \

LOCAL_MODULE:= libhello     //编译出的静态/动态库的名字
include $(BUILD_STATIC_LIBRARY)  //编译成静态库,使用BUILD_SHARED_LIBRARY则是编译成动态库

最后,分享几个个人觉得对Application.mk和Android.mk解释的比较好的:


Google官方指导,最佳无疑https://developer.android.google.cn/ndk/guides/;
掘金blog,不错的参考:https://juejin.im/entry/57b2867f8ac247005f1ce3ce;

你可能感兴趣的:(Android,开发)