天天看點

Android.mk和Application.mk配置參數詳解

每次看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