LOCAL_PATH ,Android.mk文件的路径,它不会被$(CLEAR_VARS)清除
LOCAL_MODULE ,编译后的模块名,唯一
LOCAL_MODULE_FILENAME ,模块文件名,可选,用来重新定义生成的输出文件名称,可以覆盖LOCAL_MODULE的值
LOCAL_LDLIBS ,链接标志的可选列表,常用来添加系统库,党对目标文件进行链接以生成输出文件时该标志将被传送给链接器,如-llog 引入NDK提供的动态库
LOCAL_CPPFLAGS ,如-DEBUG 为cpp源文件定义了一个宏,打开log开关
LOCAL_CPP_EXTENSION ,C++源文件的默认扩展名是.cpp,这个变量可以用来为C++源码指定一个或多个文件扩展名
LOCAL_CPP_EXTENSION := .cpp .cxx
LOCAL_CPP_FEATURES ,可选变量,用来指明模块所依赖的具体C++特性,如RTTI、execptions等
LOCAL_CPP_FEATURES := rtti
LOCAL_C_INCLUDES ,可选目录列表,默认NDK安装目录的相对路径,用来搜索头文件。
LOCAL_C_INCLUDES := sources/shared-module
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_CFLAGS ,一组可选的编辑器标志,在编译C和C++源文件的时候会被传送给编译器
LOCAL_CFLAGS := -DNDEBUG -DPORT=1234
LOCAL_CFLAGS := -l //指定include目录,这个方法比使用LOCAL_C_INCLUDES好
LOCAL_SRC_FILES ,
LOCAL_ARM_MODE ,ARM机器体系结构特有变量,用于指定要生成的ARM二进制类型,默认情况下,构建系统的拇指模式下用16位指令,可以改为arm来指定使用32位指令
LOCAL_ARM_NEON ,可选参数,设置为true时,会将浮点编译成neon指令,极大加快浮点运算(前提硬件支持,只有target为armeabi-v7a才可以)
LOCAL_STATIC_LIBRARIES ,在将第三方代码模块生成静态库之后,其他模块就可以通过将它的模块名添加到该变量中来使用该静态库
LOCAL_WHOLE_STATIC_LIBRARIES ,用来指明应该被包含在生成的共享库中的所有静态库内容,用在当几个静态库之间循环依赖时
LOCAL_SHARED_LIBRARIES ,在将第三方代码模块生成共享库之后,其他模块就可以通过它的模块名添加到该变量中来使用该共享库
LOCAL_EXPORT_CFLAGS ,该变量记录一组编译器标志,这些编译器标志会被添加到通过变量LOCAL_STATIC_LIBRARIES或LOCAL_SHARED_LIBRARIES使用本模块的其他模块的LOCAL_CFLAGS定义中
LOCAL_EXPORT_CPPFLAGS ,和LOCAL_EXPORT_CFLAGS一样
LOCAL_EXPORT_LDFLAGS ,和LOCAL_EXPORT_CFLAGS一样,用作链接器标志
TARGET_ARCH ,目标Cpu体系结构的名称,如arm
TARGET_PLATFORM ,目标Android平台的名称,如android-3
TARGET_ARCH_ABI ,目标Cpu体系结构和ABI的名称,如armeabi-v7a
TARGET_ABI ,目标平台和ABI的串联,如android-3-armeabi-v7a
NDK系统保留以下变量名:
需要注意的地方:
$(call import-module, 目录)
import-module函数宏需要先定位共享模块,然后再将它导入NDK项目中,默认情况下,该宏只搜索
目录,为了搜索其他目录,可以定义一个名为 NDK_MODULE_PATH 的环境变量,并将它设置为共享模块的根目录。
include $(call all-subdir-makefiles)
例子:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := native-activity
LOCAL_SRC_FILES := main.c
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM
LOCAL_STATIC_LIBRARIES := android_native_app_glue
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue)
每个android子项目中都会存在一个或多个mk文件,如果需要编译整个工程,只需要在根目录放置一个Android.mk文件,加上如下内容
this-makefile
返回当前Android.mk构建文件的路径
parent-makefile
返回包含当前构建文件的父Android.mk构建文件的路径
grand-parent-makefile
用于祖父目录
构建共享库
include $(BUILD_SHARED_LIBRARY)
构建多个共享库
一个单独的Android.mk文档可以产生多个共享库模块
LOCAL_PATH := $(call my-dir)
##模块1
include $(CLEAR_VARS)
...
include $(BUILD_SHARED_LIBRARY)
##模块2
include $(CLEAR_VARS)
...
include $(BUILD_SHARED_LIBRARY)
构建静态库
在将第三方代码添加到自己NDK项目中时,不用直接将第三方源代码包括在NDK项目,而是将第三方代码编译成静态库然后并入共享库
LOCAL_PATH := $(call my-dir)
#第三方库
...
include $(BUILD_STATIC_LIBRARY)
#原生模块
...
LOCAL_STATIC_LIBRARIES := moduleName
include $(BUILD_SHARED_LIBRARY)
用共享库共享通用模块
LOCAL_PATH := $(call my-dir)
#第三方库
...
include $(BUILD_SHARED_LIBRARY)
#原生模块
...
LOCAL_SHARED_LIBRARIES := moduleName
include $(BUILD_SHARED_LIBRARY)
在多个NDK项目间共享模块
首先将第三方源码移动到NDK项目以外的位置,作为共享模块,需要为它提供自己的Android.mk文件。为了在自己的NDK项目中使用它,将以下函数宏添加至构建文档的末尾。
#原生模块
include $(CLEAR_VARS)
...
include $(BUILD_SHARED_LIBRARY)
$(call import-module, 目录名(相对于NDK_MODULE_PATH变量))
Prebuilt库
想在不发布源码的情况下将你的模块发布给他人,想使用共享模块的预建版来加速构建过程,可以使用Prebuilt库
尽管已经被编译好了,但预建仍需要一个Android.mk文件,如下:
LOCAL_PATH := $(call my-dir)
#第三方预建库
include $(CLEAR_VARS)
LOCAL_MODULE := avilib
LOCAL_SRC_FILES := libavilib.so (实际Prebuilt库相对于LOCAL_PATH的位置)
include $(PREBUILT_SHARED_LIBRARY)
**注意:**Prebuilt库定义不包含任何关于该库所构建的实际机器体系结构的信息,我们需要确保Prebuilt库是为与NDK项目相同的机器体系而构建的。
构建独立的可执行文件
独立可执行文件是不用打包成Apk文件就可以复制到Android设备上的常规Linux应用程序,而且它们可以直接执行,不用通过Java应用程序加载。生成独立可执行文件需要在Android.mk文件中导入BUILD_EXECUTABLE变量。
它的目的是描述应用程序需要哪些模块,它也定义所有模块的通用变量,以下是它所支持的变量:
APP_MODULES ,默认情况下,NDK构建系统构建Android.mk文件声明的所有模块,该变量可以覆盖上述行为并提供一个用空格分开的、需要被构建的所有模块
APP_OPTIM ,该变量可以被设置为release或debug以改变生成的二进制文件的优化级别,默认情况下使用release模式,并且此时生成的二进制文件被高度优化
APP_CLAGS ,该变量列出了一些编译器标志,在编译任何模块的C和C++源文件时这些标志都会被传给编译器
APP_CPPFLAGS ,同上,只针对C++源码
APP_BUILD_SCRIPT ,默认情况下,NDK系统构建在项目的jni子目录下查找.mk文件,该变量可以改变上述行为
APP_ABI ,默认NDK构建系统为armeabi,可以修改,如
APP_ABI := armeabi mips
APP_STL ,NDK构建系统使用最小STL运行库,也被称为system库,可以用该变量选择不同的STL实现
APP_STL := stlport_shared
APP_STL := stlport_static
NDK_TOOLCHAIN_VERSION ,编译器版本,xcode使用clang(支持c++11特性,如auto), android ndk默认使用gcc
NDK_TOOLCHAIN_VERSION := clang
-C 参数可以用于指定命令行中NDK项目的位置
-B 强制重构建源代码
ndk-build clean
ndk-build -j 4 并行构建命令
ndk-build NDK_LOG=1 启用NDK构建系统内部状态日志功能
ndk-build V=1 只显示构建命令
原生库只能运行在指定的最小Android平台版本
原生代码使用的CPU架构 | 兼容的Android平台 |
---|---|
ARM, ARM-NEON | Android1.5 (API 3) |
x86 | Android2.3 (API 9) |
MIPS | Android2.3 (API 9) |
如果NDK项目使用了OpenGL ES API,则需要Android2.0以上(API 5以上),并且可以在
标签下,添加最小的OpenGL ES 版本,
首先是Application.mk
文件:
APP_OPTIM := release
APP_PLATFORM := android-19
APP_STL := gnustl_static
APP_CPPFLAGS += -frtti
APP_CPPFLAGS += -fexceptions
APP_CPPFLAGS += -DANDROID
APP_ABI := armeabi-v7a-hard
APP_MODULES := NAtiveLib
NDK_TOOLCHAIN_VERSION := clang
接着是Android.mk
文件:
TARGET_PLATFORM := android-19
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := NativeLib
LOCAL_SRC_FILES += Wrappers.cpp
LOCAL_ARM_MODE := arm
COMMON_CFLAGS := -Werror -DANDROID -DDISABLE_IMPORTGL
ifeq($(TARGET_ARCH),x86)
LOCAL_CFLAGS :=$(COMMON_CFLAGS)
else
LOCAL_CFLAGS := -mfpu=vfp -mfloat-abi=hard -mhard-float -fno-short-enums
-D_NDK_MATH_NO_SOFTFP=1 $(COMMON_CFLAGS)
endif
LOCAL_LDLIBS := -llog -lGLESv2 -Wl, -s
LOCAL_CPPFLAGS += -std=gnu++11
include $(BUILD_SHARED_LIBRARY)