總結一下Android.mk的寫法,供以後使用。
例子
可以先看一個例子:
LOCAL_PATH:=$(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= \ NmpMediaBase.cpp LOCAL_CPPFLAGS+= -Wall -W -Wno-format \ -Os -O2 -fmessage-length=0 -MMD -MP -DSILENTLOCAL_C_INCLUDES+= \ $(LOCAL_PATH)/3rdpart/3901/include \ /opt/ali_sdk/staging/usr/include/ali/nmp/LOCAL_SHARED_LIBRARIES := -lstdc++ libstlport -lpthread LOCAL_LDLIBS:= -L./ -ljson -lc -ldl -lstdc++ -lm#LOCAL_CXX := arm-linux-gnueabi-g++ #LOCAL_CPP_FEATURES += exceptionsLOCAL_CPPFLAGS += -fexceptions -fpermissiveLOCAL_MODULE:=mediabaseLOCAL_MODULE_TAGS := optionalinclude $(BUILD_EXECUTABLE)
變數解析:
LOCAL_PATH表示此時位於工程目錄的根目錄中,(call my-dir)的功能由編譯器提供,被用來返回目前的目錄的地址(這裡的目前的目錄裡包含Android.mk這個檔案本身)。
CLEAR_VARS這個變數由編譯器提供,並且指明了一個GNU Makefile檔案,這個功能會清理掉所有以LOCAL_開頭的內容(例如 LOCAL_MODULE、LOCAL_FILES、LOCAL_STATIC_LIBRARIES等),除了LOCAL_PATH。這句話是必須的,因為如果所有的變數都是全域的,所有的可控的編譯檔案都需要在一個單獨的GNU中被解析並執行。
變數必須包含一個C、C++或者java源檔案的列表,這些會被編譯並彙總到一個模組中。只要列出要傳遞給編譯器的檔案,因為編譯系統自動計算依賴。注意原始碼檔案名稱都是相對於 LOCAL_PATH的,你可以使用路徑部分,例如:
LOCAL_SRC_FILES := foo.c toto/bar.c\
Hello.c
檔案之間可以用空格或Tab鍵進行分割,換行請用"\",如果是追加原始碼檔案的話,請用LOCAL_SRC_FILES +=。
注意:可以LOCAL_SRC_FILES := $(call all-subdir-java-files)這種形式來包含local_path目錄下的所有java檔案。
變數必須被定義,用來區分android.mk中的每一個模組。檔案名稱必須是唯一的,不能有空格。注意,這裡編譯器會為你自動加上一些首碼和尾碼,來保證檔案是一致的。
這個變數是由系統提供的,並且制定給GNU Makefile的指令碼,它可以收集所有你定義的“include $(CLEAR_VARS)”中以LOCAL_開頭的變數,並且決定哪些要被編譯,哪些應該做的更加準確。表示將編譯產生一個可執行檔。
我們同樣也可以使用:
來產生一個動態庫;
來產生一個靜態庫;
來產生一個APK;
此變數可以使其他的模組不加入編譯,如源碼中DeskClock的android.mk有LOCAL_OVERRIDES_PACKAGES := AlarmClock,使 AlarmClock不會加入到編譯系統中,不會產生 AlarmClock.apk。
: 表示該模組需要使用哪些靜態庫,以便在編譯時間進行連結。
: 表示模組在運行時要依賴的共用庫(動態庫),在連結時就需要,以便在組建檔案時嵌入其相應的資訊。
注意:它不會附加列出的模組到編譯圖,也就是仍然需要在Application.mk 中把它們添加到程式要求的模組中。
: 編譯模組時要使用的附加的連結器選項。這對於使用‘-l’首碼傳遞指定庫的名字是有用的。
例如,LOCAL_LDLIBS := -lz表示告訴連結器產生的模組要在載入時刻連結到/system/lib/libz.so
可查看 docs/STABLE-APIS.TXT 擷取使用 NDK發行版能連結到的開放的系統庫列表。
LOCAL_LDLIBS :連結的庫不產生依賴關係,一般用於不需要重新編譯的庫,如庫不存在,則會報錯找不到。且貌似只能連結那些存在於系統目錄下本模組需要串連的庫。如果某一個庫既有動態庫又有靜態庫,那麼在預設情況下是連結的動態庫而非靜態庫。
如:LOCAL_LDLIBS += -lm –lz –lc -lcutils –lutils –llog
如果需要指定連結庫的路徑則直接在後面寫 -L再加路徑即可
LOCAL_SHARED_LIBRARIES 會產生依賴關係,當庫不存在時會去編譯這個庫。
:這個編譯變數傳遞給連結器一個一些額外的參數,比如想傳遞而外的庫和庫路徑給ld,或者傳遞給ld linker的一些連結參數,-On,-EL{B}(大小端位元組序),那麼就要加到這個上面,如:
LOCAL_LDFLAGS += -L$(LOCAL_PATH)/lib/ -lHWrecog –EB{EL} –O{n} …
或者直接加上絕對路徑庫的全名:
LOCAL_LDFLAGS += $(LOCAL_PATH)/lib/libHWrecog.a –EB{EL} –O{n}
它的作用就是包含所有子目錄中的Android.mk檔案
如果需要編譯的模組比較多,我們可能會將對應的模組放置在相應的目錄中,
這樣,我們可以在每個目錄中定義對應的Android.mk檔案(類似於上面的寫法),
最後,在根目錄放置一個Android.mk檔案,加入include $(call all-subdir-makefiles)
指架構中CPU的名字已經被android開原始碼明確指出了。這裡的ARM包含了任何ARM-獨立結構的架構,以及每個獨立的CPU的版本。
: Android.mk 解析的時候,目標 Android 平台的名字.
android-3 -> Official Android 1.5 system images
android-4 -> Official Android 1.6 system images
android-5 -> Official Android 2.0 system images
: 暫時只支援兩個 value,armeabi 和 armeabi-v7a
: 目標平台和 ABI 的組合
: 可選變數,表示標頭檔的搜尋路徑。預設的標頭檔的搜尋路徑是LOCAL_PATH目錄。
和
在 Android.mk 檔案中, 還可以用LOCAL_MODULE_PATH 和LOCAL_UNSTRIPPED_PATH指定最後的目標安裝路徑.
不同的檔案系統路徑用以下的宏進行選擇:
:表示根檔案系統。
:表示 system檔案系統。
:表示 data檔案系統。
用法如:LOCAL_MODULE_PATH :=$(TARGET_ROOT_OUT)
:定義了要包含的so庫檔案的名字,如果程式沒有採用jni,不需要
LOCAL_JNI_SHARED_LIBRARIES := libxxx 這樣在編譯的時候,NDK自動會把這個libxxx打包進apk; 放在yourapk/lib/目錄下
可選的編譯器選項,在編譯C代碼檔案的時候使用。這可能是有用的,指定一個附加的包含路徑(相對於NDK的頂層目錄),宏定義,或者編譯選項。注意:不要在Android.mk中改變optimization/debugging層級,只要在Application.mk中指定合適的資訊,就會自動地為你處理這個問題,在調試期間,會讓NDK自動產生有用的資料檔案。
與LOCAL_CFLAGS相同,針對C++源檔案。
與LOCAL_CFLAGS相同,但是對C和C++sourcefiles都適用。
NDK提供的函數宏:
:返回當前 Android.mk 所在的目錄的路徑,相對於 NDK 編譯系統的頂層。這是有用的,在 Android.mk 檔案的開頭如此定義:
LOCAL_PATH := $(call my-dir)
: 返回一個位於當前'my-dir'路徑的子目錄中的所有Android.mk的列表。
: 返回當前Makefile 的路徑(即這個函數調用的地方)
: 返回調用樹中父 Makefile 路徑。即包含當前Makefile的Makefile 路徑。
:返回調用樹中父Makefile的父Makefile的路徑
在Android.mk中,“:=”是賦值的意思;“+=”是追加的意思;“$”表示引用某變數的值。
Android.mk給變數賦值,同時用的“:=”和“=”,他們分別代表什麼意思呢?
“:=” 的意思是,它右邊賦得值如果是變數,只能使用在這條語句之前定義好的,而不能使用本條語句之後定義的變數;
“=”,當它的右邊賦值是變數時,這個變數的定義在本條語句之前或之後都可以;
常見錯誤及解決辦法:
解決辦法:增加Application.mk 寫 APP_STL :=gnustl_static
在Application.mk中添加改寫application.mk檔案,把版本改成9或更高,APP_PLATFORM := android-9 //對應2.3.1;
在Android API < 9時,採用android NDK編譯代碼是不支援pthread_rwlock_t結構體的。
Ndk編譯curl:下載源碼:http://curl.haxx.se/download.html
./configure --host=arm-linux CC=arm-linux-gnueabi-gcc --prefix=//home/usrhome/johnny.he/androidworkspace/curl_install
make; make install