android NDK 简介
Android NDK是一个复杂的集合,包括: API 、交叉编译器、连接器 、调试器、构建工具、文档和例程。其中最重要的是构建系统。
Android NDK 构建系统
使用Android NDK构建工具,用户需要编写两个文件:Android.mk 和 Application.mk。NDK以模块为单位进行构建。
Android.mk 是Android NDK 构建所必须的文件。
- 一个简单的例子:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY) ```
- *LOCAL_PATH := $(call my-dir)*
应该是所有Android.mk 文件中第一句执行的语句。该语句向构建系统指明,工程在文件所在路径下。
- *include $(CLEAR_VARS)*
其中变量 “CLEAR_VARS” 指向构建系统中的clear-vars.mk. 执行该文件会清空名为LOCAL_xx的变量。需要执行清空动作是因为在多个构建文件中以及多模块构建时会共享这些变量,清空这些变量可以防止冲突。
- *LOCAL_MODULE := hello-jni*
以唯一的名称*hello-jni*命名当前模块, 该名称用于生成构建文件。例如,以上例子将生成 *libhello-jni.so* 文件
- *LOCAL_SRC_FILES := hello-jni.c*
该语句指明本模块用于构建和汇编的源代码文件列表。
- *include $(BUILD_SHARED_LIBRARY)*
其中*BUILD_SHARED_LIBRARY*指向构建系统的*build-shard-library.mk*文件。该文件用以生成动态库 .so 文件
当需要生成多个动态库文件时,只需定义多个模块即可:
LOCAL_PATH := $(call my-dir)
Module 1
include $(CLEAR_VARS)
LOCAL_MODULE := module1
LOCAL_SRC_FILES := module1.c
include $(BUILD_SHARED_LIBRARY)
Module 2#include $(CLEAR_VARS)
LOCAL_MODULE := module2
LOCAL_SRC_FILES := module2.c
include $(BUILD_SHARED_LIBRARY) ```
- 模块共享
- 静态库共享
Android NDK 也可以构建静态库文件 ,只需要将* include $(BUILD_SHARED_LIBRARY)* 替换成 * include $(BUILD_STATIC_LIBRARY)* 即可。不过静态库不能用于Android应用程序,只可以用于构建其他动态库。当用于其他动态库构建时,需要设置变量LOCAL_STATIC_LIBRARY。 - 动态库共享
动态库也可以用于其他模块的构建,代码如下:
## Native module 1
#include $(CLEAR_VARS)
LOCAL_MODULE := module1
LOCAL_SRC_FILES := module1.c
LOCAL_SHARED_LIBRARIES := avilib
include $(BUILD_SHARED_LIBRARY)
## Native module 2
#include $(CLEAR_VARS)
LOCAL_MODULE := module2
LOCAL_SRC_FILES := module2.c
LOCAL_SHARED_LIBRARIES := avilib
include $(BUILD_SHARED_LIBRARY) ```
3. 多个NDK工程中共享模块
使用其他NDK工程的模块需要指定模块位置,具体代码如下:
# Native module
include $(CLEAR_VARS)
LOCAL_MODULE := module
LOCAL_SRC_FILES := module.c
LOCAL_SHARED_LIBRARIES := avilib
include $(BUILD_SHARED_LIBRARY)
$(call import-module,transcode/avilib)
注:NDK构架系统默认搜索*<Android NDK>/sources director* 路径,可以设置环境变量*NDK_MODULE_PATH*增加搜索路径。
4. 预建共享模块 ( prebuild Shared Module)
可以使用已编译的库作为共享模块的源文件,代码如下:
LOCAL_PATH := $(call my-dir)
3rd party prebuilt AVI library
include $(CLEAR_VARS)
LOCAL_MODULE := avilib
LOCAL_SRC_FILES := libavilib.so
include $(PREBUILT_SHARED_LIBRARY)```
LOCAL_SRC_FILES 赋值为编译后的库文件列表。
- 构建可执行的文件
Android平台上本地开发的推荐方式是构建共享库,然后将其打包到APK文件中进行使用。 但是为了满足某些需求(如测试或原型开发),也可以使用NDK构建可执行文件。NDK构建的可运行文件是标准的Linux 应用。不需要打包到APK文件,直接拷贝到手机就可以运行。代码如下:
## Native module standlone executable
#include $(CLEAR_VARS)
LOCAL_MODULE := module
LOCAL_SRC_FILES := module.c
LOCAL_STATIC_LIBRARIES := avilib
include $(BUILD_EXECUTABLE) ```
该程序生成的不会被打包到APK中去。
##### Application.mk 是可选的,如果没有该文件,NDK 构建系统使用默认值对工程进行构建。该文件包换的变量如下:
- APP_MODULE : 默认情况下,构建系统会构建Android.mk 文件中的所有模块。对该变量进行赋值则只会构建该变量值中的模块。
- APP_OPTIM: 该变量只可赋值*release* 和*debug*。该值会改变编译时优化的级别。默认使用 *release*模式进行编译。
- APP_CLAGS: 该变量用于设置C和C++编译器参数。
- APP_CPPFLAGS: 该变量用于设置C++编译器参数。
- APP_BUILD_SCRIPT : 默认情况下,NDK系统会在当前目录下寻找Android.mk 。设置该变量则可以改变用于构建的Android.mk 文件位置。
- APP_ABI: 默认情况下,NDK 只会为armeabi.ABI 生成二进制文件,设置该变量可以生成不同ABI的二进制文件。
- APP_STL: 默认情况下,Android NDK 构建系统会使用最小的*STL runtime library* , 该变量可以指定不同版本的STL。
---
PS. 以上内容摘抄、翻译自《Pro Android C++ with the NDK》
网友评论