每次看Android.mk或者Application.mk檔案的時候,都會被其中的變量搞得頭暈,本文專門針對這種情況盡量全面地介紹一下Android.mk和Application.mk中各種變量的含義。
Android.mk介紹
TARGET_ARCH:CUP架構,比如,ARM
TARGET_PLATFORM:目标Android SDK版本的名字,比如android-3
TARGET_ARCH_ABI:CPU架構名字和其對應的ABI(Application binary interface:應用程式二進制接口),例如armeabi-v7a
TARGET_ABI:Android SDK版本和ABI名字,比如:amdroid-3-armeabi-v7a
LOCAL_MODULE_FILENAME:定義目标檔案的名字,預設使用的變量是LOCAL_MODULE,但是可以使用LOCAL_MODULE_FILENAME這個名字來代替
LOCAL_CPP_EXTENSION: 預設的C++擴充名是.cpp,這個變量可以定義一個或多個C++檔案擴充名。
[html] view plain copy
…
LOCAL_CPP_EXTENSION: =.cpp .cxx
…
LOCAL_CPP_FEATURES: 定義子產品依賴的C++功能,比如rtti,exception等
[html] view plain copy
…
LOCAL_CPP_FEATURES:=rtti
…
LOCAL_C_INCLUDES:除了NDK安裝目錄,項目所依賴的其他頭檔案路徑
[html] view plain copy
…
LOCAL_C_INCLUDES := sources/shared-module
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
…
LOCAL_CFLAGS: 為編譯器定義額外的标志(如宏定義等),編譯C和C++檔案時傳給編譯器的标志,例如:
[html] view plain copy
...
LOCAL_CFLAGS :=−DNDEBUG –DPORT=1234
...
LOCAL_CPP_FLAGS: 隻為C++檔案定義額外标志
LOCAL_WHOLE_STATIC_LIBRARIES: 程式中所有的變量和函數都編譯到靜态庫中,包含沒有用到的變量和函數。(注:當靜态庫中形成環形依賴的時候,這個變量将非常有用)
LOCAL_LDLIBS: 指定程式所依賴的連結庫,比如,連結Android NDK的日志庫
[html] view plain copy
LOCAL_LDFLAGS := − llog
LOCAL_ALLOW_UNDEFINED_SYMBOLS:使檢查缺失符号的功能喪失,如果不定義的話,連結器報錯訓示符号缺失。
LOCAL_ARM_MODE: 訓示編譯目标檔案的指令集,arm指令使用兩種模式,一種是Thumb(每條指令兩個位元組),一種是arm指令(每條指令4個位元組)
[html] view plain copy
LOCAL_ARM_MODE := arm
以.arm為擴充名的檔案也可以作為源檔案編譯成固定指令集的目标檔案
[html] view plain copy
LOCAL_SRC_FILES := file1.c file2.c.arm
LOCAL_ARM_NEON:在module中定義LOCAL_ARM_NEON為‘true’,這樣NDK編譯的檔案将支援NEON指令。這是非常有用的,如果你編譯的靜态或動态庫包含NEON代碼路徑的話,使用.neon字尾。
[html] view plain copy
LOCAL_ARM_NEON := true
LOCAL_SRC_FILES := file1.c file2.c.neon
LOCAL_DISABLE_NO_EXECUTE: 去除NX Bit安全功能(注:NX Bit安全是一種應用在CPU中的安全技術,表示never execute,把記憶體分為存儲和代碼執行兩部分,這樣可以防止惡意應用在記憶體的存儲部分插入惡意代碼控制程式)
[html] view plain copy
LOCAL_DISABLE_NO_EXECUTE := true
LOCAL_EXPORT_CFLAGS: 和LOCAL_CFLAGS一樣指定标志(如宏定義),同時還可以作為另外module的依賴标志,如:
[html] view plain copy
LOCAL_MODULE := avilib
...
LOCAL_EXPORT_CFLAGS := − DENABLE_AUDIO
...
LOCAL_MODULE := module1
LOCAL_CFLAGS :=−DDEBUG
...
LOCAL_SHARED_LIBRARIES := avilib
編譯器在編譯module1的時候可以得到兩個宏定義–DENABLE_AUDIO 和–DDEBUG
LOCAL_EXPORT_CPPFLAGS:同上
LOCAL_EXPORT_LDFLAGS: 同上
LOCAL_EXPORT_C_INCLUDES: 同上
LOCAL_SHORT_COMMANDS:Windows的CMD指令行支援最多8191個字元,當一個module需要依賴很多庫檔案時,這個變量可以設定為true。
LOCAL_FILTER_ASM:從LOCAL_SRC_FILES檔案中過濾彙編檔案。
all-subdir-makefiles: 傳回目前目錄下包括子目錄下所有的Android.mk檔案
this-makefile: 傳回目前Android.mk檔案的路徑
parent-makefile: 傳回目前Android.mk的父Android.mk的路徑。
grand-parent-makefile: 傳回目前Android.mk的爺爺Android.mk的路徑。
定義新變量,例如:
[html] view plain copy
...
MY_SRC_FILES := avilib.c platform_posix.c
LOCAL_SRC_FILES := $(addprefix avilib/, $(MY_SRC_FILES))
...
條件操作符,例如:
[html] view plain copy
...
ifeq ($(TARGET_ARCH),arm)
LOCAL_SRC_FILES + = armonly.c
else
LOCAL_SRC_FILES + = generic.c
endif
...
Application.mk介紹
APP_MODULES: 可選項,如果沒有定義,則NDK編譯所有Android.mk中的modules.如果定義了,則隻編譯Android.mk中被APP_MODULES指定的子產品以及他們所依賴的子產品。
APP_OPTIM: 可選項。設定為:’release’ or ‘debug’。系統根據此選項決定優化等級
APP_CLAGS:這個CFLAGS将取代Android.mk中module中指定的
APP_CPPFLAGS: 隻對C++代碼有效的CPPFLAGS
APP_BUILD_SCRIPT:通常情況下,NDK Build 系統會查找Android.mk從 (APPPROJECTPATH)/jni/,即: (APP_PROJECT_PATH)/jni/Android.mk,如果想改變這個行為,則修改:APP_BUILD_SCRIPT.例如:
[html] view plain copy
APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/Android.mk
APP_ABI:預設情況下,NDK build system會産生’armeabi’,要想支援arm-v7,x86,mips,則修改為:
[html] view plain copy
APP_ABI := armeabi armeabi-v7a x86 mips
APP_STL:預設情況下,NDK會尋找系統的STL庫,這個參數可以指定另外的庫,例如:
[html] view plain copy
APP_STL := stlport_shared
APP_GNUSTL_FORCE_CPP_FEATURES:類似LOCAL_CPP_EXTENSIONS
APP_SHORT_COMMANDS: 類似LOCAL_SHORT_COMMANDS
如何使用ndk-build腳本
預設情況下,ndk-build腳本會編譯本目錄下的工程,我們也可以加-C來指定工程目錄,有了這個,工程可以放到任何目錄下
[html] view plain copy
ndk-build –C /path/to/the/project
預設情況下,ndk-build腳本不會重新編譯沒有經過修改的檔案,如果強行使其重新編譯的話,需要加-B參數
[html] view plain copy
ndk-build -B
為了clean編譯的中間檔案以及目标檔案,執行以下指令:
[html] view plain copy
ndk-build clean
另外,NDK依賴的GNU make來編譯module,預設情況下,編譯器會按照順序執行,必須等待前者執行完畢才會編譯後者,如果想要節省時間,可以同時開幾個線程執行編譯,類似編譯Android作業系統。
[html] view plain copy
ndk-build –j 4
如果執行ndk-build的時候想要看到更多日志的話
[html] view plain copy
ndk-build NDK_LOG=1