1. 簡介
Android.mk 可用來描述要編譯的某個具體模塊的相關信息。比如:指定編譯該模塊時所需要的源文件、編譯該模塊時要鏈接的庫文件、該模塊編譯完成后生成的庫的名字等等。
Application.mk 可用來描述整個應用程序編譯時的相關信息。比如:指定編譯支持的ABI平台(armeabi-V7a, arm64-v8a, all...)、指定NDK編譯時的模塊列表、指定目標Android 平台的名稱等等。
2. 一個簡單的Android.mk文件
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello-jni LOCAL_SRC_FILES := hello-jni.c jnihelp.cpp Calculator.cpp
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH: 必須位於Android.mk文件的開始,用來定義源文件的位置,$(call my-dir)返回當前路徑,即android.mk所在的目錄。my-dir是構建系統提供的宏函數,它將會返回當前目錄的路徑;
include $(CLEAR_VARS): 清除除LOCAL_PATH之外的所有LOCAL_XXX變量。這個清理動作是必須的,因為所有的編譯控制文件都是由同一個GNU Make解析和執行,其變量是全局的,只有清理后才能避免相互影響。
LOCAL_MODULE: 表示Android.mk所在模塊的模塊名,名字必須唯一且不包含空格。構建系統在生成最終的so庫文件時,會參考該模塊名生成最終的so庫,如:libhello-jni.so;
LOCAL_SRC_FILES: 編譯該模塊時所需的C/C++源文件,如果有多個文件需要用空格分離,如果想換行則需要在每個源文件末尾加上反斜杠"\" ,類似於C語言中的多行宏定義;
include ${BUILD_SHARED_LIBRARY}: 確定要構建的內容及其操作方法。BUILD_SHARED_LIBRARY 表示要編譯為動態庫,構建系統會生成后綴名為.so的庫文件;BUILD_STATIC_LIBRARY 表示要編譯為靜態庫,構建系統會生成后綴名為.a 的為文件。
該文件中的一些擴展的變量:
# 指定頭文件所在的目錄 LOCAL_C_INCLUDES := $(LOCAL_PATH) # 指定在構建動態庫或可執行文件時需要鏈接的其它庫列表,如Android系統提供的日志庫,OpenGL ES, EGL等 # 每個鏈接的庫文件都必須加上-l 前綴(注意是小寫英文字母l,不是數字1) # 多個鏈接的庫文件使用空格分隔 LOCAL_LDLIBS += -llog -landroid -lc
3. 一個簡單的Application.mk文件
APP_ABI = armeabi-v7a
APP_MODULES = hello-jni
APP_ABI:指定支持的ABI平台。上面所示為armeabi-v7a, 可選的值有all (代表全平台)、arm64-v8a、x86、x86_64,多個平台用空格隔開。
APP_MODULES:如果指定,那么NDK只會編譯列出的模塊列表,模塊名用空格隔開,如果沒有指定那么NDK會編譯所有的Android.mk聲明的所有的LOCAL_MODULE模塊。
該文件的一些擴展的變量:
# 指定目標Android平台的名稱 APP_PLATFORM = android-26 # 是否支持C++標准庫 APP_STL := stlport_static # 為項目中的所有C++編譯傳遞的標記 APP_CPPFLAGS := -frtti -fexceptions -std=c++11
4. 多個編譯模塊的處理
有時候要編譯的模塊(UDP、FFmpeg、Openssl、libyuv)比較多,如果把所有的C/C++代碼放到同一個目錄下會顯得比較亂,因此可以在每一個模塊下都定義一個Android.mk文件,然后在jni 的根目錄下放置一個Android.mk文件,內容如下:
include $(call all-subdir-makefiles)
比如:
5. 其它注意事項
1. 以LOCAL_、PRIVATE_、NDK_、APP_ 開頭的名稱是NDK編譯系統的保留變量名稱,在自定義變量時不要以以上變量名打頭。如果你想在Android.mk文件中定義自己的變量,建議在名稱前附加 MY_;
2. Makefile中的 := 、?=、+=、= 的區別。= 是最基本的賦值,:= 是覆蓋之前的值,?= 是如果沒有被賦值過就賦予等號后面的值,+= 是添加等號后面的值。
參考鏈接:
1. Google Developers —— NDK Android.mk說明
2. Android.mk中以LOCAL_ 打頭的變量說明
3. Android 中的android.mk 和 application.mk 文件編寫(總結版)
4. Makefile 中:= ?= += =的區別
5. JNI學習——關於Android.mk / Application.mk