学习Android NDK MakeFile

MakeFile介绍

NDK中的MakeFile有Application.mk和Android.mk两个文件组成,
Application.mk是对整个项目的全局性描述,比如编译的平台,编译的优化选项等;Android.mk是项目中某一个模块的编译脚本,在其中指定Module的名称,需要编译的代码文件,以及需要包含的头文件等。

Application.mk

Application.mk 相对较少,我们一般只需要关注以下几个常用的选项

  • APP_ABI
    用来指定需要编译的平台,如果我们的so就是在手机上使用,armeabi-v7a基本上可以适配大部分手机了,部分x86平台的手机内部有个转化器,会自动把arm的指令转化到x86平台,当然这有一定的性能损耗。
APP_ABI := armeabi-v7a 
  • APP_PLATFORM
    用来指定Android 平台的版本,不同的版本差异主要是有些系统库不能在低版本使用,比如opengles v2版本需要在Android 2.0以上使用,如果需要使用opengles v2,需要设置APP_PLATFORM为android-5:
APP_PLATFORM := android-5
  • APP_STL
    用来指定C++标准库的不同实现,默认值是libstdc++,是最基本版本的C++标准库实现,可能我们的代码中用到了libstdc++不支持的函数,我们需要指定其他实现:
APP_STL := gnustl_static

- APP_PROJECT_PATH
指定项目的路径,一般我们的项目是放在jni目录下的,可以不用指定。

- APP_BUILD_SCRIPT
指定NDK编译脚本的文件名称,如果编译脚本名称为Android.mk, 可以不用指定。

Android.mk

基础结构

Android.mk编写我们一般有一些固定的顺序, 以下是最简单的Android.mk结构

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
 
LOCAL_MODULE    := test
LOCAL_SRC_FILES := test.c
 
include $(BUILD_SHARED_LIBRARY)
  • LOCAL_PATH := $(call my-dir)
    设置当前的代码路径,LOCAL_PATH指向Android.mk所在的目录

  • include $(CLEAR_VARS)
    清除LOCAL_xxx指定的变量,清理后才能避免多个模块相互影响

  • LOCAL_MODULE := test
    指定当前模块的名称为test,生成后的文件为libtest.so

  • LOCAL_SRC_FILES := test.c
    指定需要编译的源码文件,不需要列出头文件

  • include $(BUILD_SHARED_LIBRARY)
    编译生成动态链接库

引用外部动态链接库

首先中Android.mk文件中将共享库声明为一个独立的模块

include $(CLEAR_VARS)
LOCAL_MODULE := avcodec 
LOCAL_SRC_FILES := prebuilt/ffmpeg/libavcodec.so    
include $(PREBUILT_SHARED_LIBRARY) 

在自己的模块中再使用以下代码引用这个模块

LOCAL_C_INCLUDES :=  prebuilt/ffmpeg/include/
LOCAL_SHARED_LIBRARIES:=avcodec
  • LOCAL_C_INCLUDES := prebuilt/ffmpeg/include/
    使用外部动态库,编译需要用到外部库的头文件

  • LOCAL_SHARED_LIBRARIES:=avcodec
    指定当前模块需要引用的共享链接库模块

使用系统库

如果我们在代码中需要使用系统库,比如LOG库,我们需要加入以下代码, 就可以引用系统的/system/lib/liblog.so了。

LOCAL_LDLIBS := -llog

推荐阅读更多精彩内容