1. 程式人生 > >android mk編譯引數

android mk編譯引數

Application.mk file syntax specification

Introduction:

------------------

本文件描述Application.mk檔案的語法,這個編譯檔案描述Android應用需要的本地modules。為了便於理解下面的內容,假設你已經閱讀了OVERVIEW相關內容,瞭解了它們的作用以及用法。

在閱讀以下文件之前,請先閱讀OVERVIEWAndroid.mk相關內容。

Overview

--------------

Application.mk是用來描述你應用程式需要的本地‘modules’(如靜態/共享庫)。

Application.mk通常放在$PROJECT/jni/Application.mk下,

$PROJECT指向你應用程式的工程目錄。

另外,也可以放在$NDK/apps的子目錄下,例如:

   $NDK/apps/<myapp>/Application.mk

<myapp>是用來向NDK編譯系統描述你應用程式的一個簡短名稱(這個名字不會編譯到動態庫和最終的程式包中)。

Application.mk是一個非常輕量級的GNUMakefile指令碼,必須定義一些變數:

APP_PROJECT_PATH

這個變數必須給出你應用程式的工程根目錄的絕對路徑。這個用來拷貝/安裝生成JNI動態庫的stripped版本到一個APK生成工具知道的指定位置。

注意$PROJECT/jni/Application.mk
是可選的,但是對於$NDK/apps/<myapp>/Application.mk卻是強制要求的。

APP_MODULES

這個變數是可選的。如果沒有定義,NDK將會採用預設的方式,編譯在Android.mk宣告的所有modules,同時包含了所有子目錄下的Android.mk檔案。

如果APP_MODULES定義了,它必須是用空格分開的module名稱的列表,這些module的名稱就是在Android.mk檔案中LOCAL_MODULE定義的。注意NDK將會自動計算module的依賴關係。

注意:在NDK r4中變數的預設行為發生了變化。之前的是:
-Application.mk中這個變數是強制要求的
-必須顯示的列出所有需要的modules
APP_OPTIM
這個可選的變數可定義在‘release’或者‘debug’中。當編譯應用程式的modules的時候,這個用來改變優化級別。
預設是‘release’模式,並生成高級別的二進位制檔案。‘debug’模式會生成沒有優化的二進位制檔案,這樣更容易除錯。
注意如果你的應用程式是可除錯的(如manifest<application>設定android:dubuggable為‘true’),這樣預設的就是‘debug’而不是‘release’。這個可以通過設定APP_OPTIM為‘release’來覆蓋它。

注意可以同時設定為‘release’和‘debug’,但是在debuggingsessions過程中‘release’編譯傾向提供比較少的資訊:一些變數進行了優化,不能被檢查,程式碼進行了重新排序使得單步除錯程式碼變得困難,棧的跟蹤將變得不可靠,等等。。。

APP_CFLAGS
當編譯任何modules中的cc++原始檔的時候,會傳遞一個C編譯標誌的集合。這個可以用來改變應用程式需要的module的編譯行為,而不需要修改Android.mk檔案本身。
重要警告:++++++++++++++++++++++++++++++++++++++++++
+
+  所有路徑必須相對於NDK頂級目錄。例如,如果你有下面的設定:
+
+     sources/foo/Android.mk
+     sources/bar/Android.mk
+
+  在編譯的時候,為了在foo/Android.mk中指定你想要新增的‘bar’原始檔的路徑,你應該使用:
+
+     APP_CFLAGS += -Isources/bar
+  或者:
+
+    APP_CFLAGS += -I$(LOCAL_PATH)/../bar
+  使用‘-I../bar’不能工作,因為他等價於‘-I$NDK_ROOT../bar’。
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
注意:在android-ndk-1.5_r1中,只能使用在c原始檔上,c++不行。這個已經修正來滿足整個Android編譯系統的要求。
APP_CXXFLAGS
    APP_CPPFLAGS的別名,在以後的NDK釋出版本中它可能會消失。
APP_CPPFLAGS
只有在編譯C++原始碼的時候,傳遞的C++編譯標誌的集合。
注意:在android-ndk-1.5_r1中,這個可以同時用在cc++原始碼上。這個已經修正來滿足整個Android編譯系統的要求。你現在可以使用APP_CFLAGS標誌應用在cc++原始碼上。
APP_BUILD_SCRIPT
預設情況下,NDK編譯系統會查詢$(APP_PROJECT_PATH)/jni目錄下的Android.mk檔案,例如:

       $(APP_PROJECT_PATH)/jni/Android.mk

如果你想改變這個預設行為,你可以定義APP_BUILD_SCRIPT指向一個編譯指令碼。一個不是絕對路徑的path總是解釋為相對於NDK的頂級目錄。
APP_ABI
預設情況下,NDK編譯系統將會生成‘armeabiABI的機器碼。這對應使用浮點運算操作的基於ARMv5TECPU。你可以使用APP_ABI選擇一個不同的ABI
例如,為了支援基於ARMv7裝置的硬體FPU指令,使用:
APP_ABI := armeabi-v7a
或者支援IA-32指令集,使用:
       APP_ABI := x86
或者支援MIPS指令集,使用:
       APP_ABI := mpis
或者同時支援所有指令集,使用:
       APP_ABI := armeabi armeabi-v7a x86 mpis
或更好,從NDK r7,你可以使用‘all’,表示這個版本的NDK
持的所有ABIs:
       APP_ABI := all
想要了解所有支援的ABIs和關於它們的使用和限制的細節,請閱讀CPU-ARCH-ABIs相關內容。
APP_PLATFORM
目標android平臺的名稱。例如,‘android-3’對應Android 1.5 系統映象。想要了解完整的平臺名稱和對應的Android系統映象,請檢視STABLE-APIS相關內容。
APP_STL
預設情況下,NDK編譯系統提供最小的C++執行時庫(/system/lib/libstdc++.so)的標頭檔案,這個最小的執行時庫是由android系統提供。
但是,NDK自帶的C++實現,讓你能夠使用或連結到你的運用程式中。定義APP_STL為下面的一個,例如:

APP_STL := stlport_static       --> static STLport library        

APP_STL := stlport_shared      --> shared STLport library        

APP_STL := system             --> default C++ runtime library

想要了解這個主題的資訊,請閱讀CPLUSPLUS-SUPPORT相關內容。
APP_GNUSTL_FORC_CPP_FEATURES
NDK之前的版本中,一個簡單的事實是:執行時使用GNU libstdc++(例如,通過設定APP_STL為‘gunstl_static’或‘gunstl_shared’)會強制在所有生成的機器程式碼中支援異常和RTTI。這可能在特定的情況下會有問題,但是非常罕見,如,會為工程生成不必要的很大的程式碼,而這些程式碼對於這些功能來是不需要的。
這個bugNDK r7已經修復了,但是意味著,如果你的程式碼需要使用異常或RTTI,它必須顯示的指出,要麼在APP_CPPFLAGS,要麼在你的LOCAL_CPPFLAGS / LOCAL_CPP_FEATURES定義中。
NDK r7以及以後的版本中,為了使得對projects的介面更加簡單,一種可選的方法是定義APP_GNUSTL_CPP_FEATURES來包含一個或多個下面的這些值:

    exceptions    -> to enforce exceptions support for allmodules.        

    rtti           ->to enforce rtti support for all modules.

例如,要在NDK r7中得到同樣的行為:

       APP_GNUSTL_FORCE_CPP_FEATURES:= exceptions rtti

重要:在這裡提供這個變數是作為一個便利的工具,使得它轉向新版本的NDK更加簡單。我們鼓勵所有的開發者恰當的修改module的定義,而不要依賴於它。
APP_SHORT_COMMANDS
對於整個工程來說,這個和LOCAL_SHORT_COMMANDS是一樣的。請檢視Android.mk文件中的內容。
NDK_TOOLCHAIN_VERSION
定義這個變數為4.4.34.6來選擇GCC編譯器的版本。4.6是預設值。
APP_PIE
Jelly Bean (4.1)開始,Android的動態連結器支援position-independent executables (PIE),用-fPIE進行編譯,這個標誌會使得通過隨機程式碼的位置來查詢記憶體損壞的bug更加困難。
預設,ndk-build將自動設定這個值為‘true’,如果你的工程targetsAndroid-16或更高。你可以手工的設定它為‘true’或‘false’。
重要:PIE executables不能執行在Android4.1之前的版本上。
注意這個只能運用在可執行程式上。當編譯動態或靜態庫的時候是不起作用的。
一個非常簡單的Application.mk檔案如下:

-------------- 分割線 -------------------------

APP_PROJECT_PATH := <pathto project>

-------------- 分割線-------------------------