Android.mk中那些編譯參數學習

Android.mk中那些編譯參數學習

參考網址:https://www.jianshu.com/p/aaf44b513c63

 

Android新編譯一個模塊:

# cd $(YOUR_ANDROID) && make helloworld

注意make helloworld中的目標名helloworld就是上面Android.mk文件中由LOCAL_MODULE指定的模塊名。編譯結果如下:

 

Android.mk中那些變量的含義,一直沒有做過總結,此次又涉及到修改mk,便做了一下總結.

AOSP

Android系統源碼編譯命令

Android源碼下開發肯定涉及到Android.mk. Android源碼是在linux系統下開發的, 其實說到底是一個大的工程, 裏面涉及到龐大的編譯系統, 這個額編譯系統的核心是build/目錄, 就好比我們在終端第一次編譯時需要初始化編譯環境,都是敲:

source build/envsetup.sh

envsetup.sh裏面還幫我們動態增加了以下命令:

croot 切換到源碼樹的根目錄
m 在源碼樹的根目錄執行 make
mm Build 當前目錄下的模塊
mmm Build 指定目錄下的模塊
cgrep 在所有 C/C++ 文件上執行 grep
jgrep 在所有 Java 文件上執行 grep
resgrep 在所有 res/*.xml 文件上執行 grep
godir 轉到包含某個文件的目錄路徑
printconfig 顯示當前 Build 的配置信息
add_lunch_combo 在 lunch 函數的菜單中添加一個條目

我們指定編譯目標則是:

lunch

lunch後我們自己選擇編譯的target即可.我們也可以在lunch後面追加指定參數, 比如 lunch 16就是第16個target

最後就是編譯命令:

make -j8

其實與普通的linux工程的編譯一樣, make, -j指的是job, -j8指的是8線程編譯.渣渣電腦的可以弄-j4

這樣最後我們的img都會被編出來, 結果位於 /out目錄下

  • /out/host/:該目錄下包含了針對主機的 Android 開發工具的產物。即 SDK 中的各種工具,例如:emulator,adb,aapt 等。
  • /out/target/common/:該目錄下包含了針對設備的共通的編譯產物,主要是 Java 應用代碼和 Java 庫.
  • /out/target/product/<product_name>/:包含了針對特定設備的編譯結果以及平臺相關的 C/C++ 庫和二進制文件。其中,<product_name>是具體目標設備的名稱。 system.img也是在這下面

上面只是編譯簡介, 本篇文章主總結Android.mk中每個參數的含義.

Android.mk

每個Android.mk中都有下面這兩行:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

這兩行代碼的作用是:

  1. 將LOCAL_PATH變量定義成本文件所在目錄路徑。
  2. 清理(可能由其他模塊設置過的)編譯環境中用到的變量。

當然,Build 系統中還定義了一些便捷的函數以便在 Android.mk 中使用,包括:

  • $(call my-dir):獲取當前文件夾路徑。
  • $(call all-java-files-under, <src>):獲取指定目錄下的所有 Java 文件。
  • $(call all-c-files-under, <src>):獲取指定目錄下的所有 C 語言文件。
  • $(call all-Iaidl-files-under, <src>) :獲取指定目錄下的所有 AIDL 文件。
  • $(call all-makefiles-under, <folder>):獲取指定目錄下的所有 Make 文件。
  • $(call intermediates-dir-for, <class>, <app_name>, <host or target>, <common?> ):獲取 Build 輸出的目標文件夾路徑。

Android.mk中其他的一些環境變量配置:

變量名 意義
LOCAL_MODULE LOCAL_MODULE變量必須定義,以標識你在Android.mk文件中描述的每個模塊。名稱必須是唯一的,而且不包含任何空格。注意編譯系統會自動產生合適的前綴和後綴,換句話說,一個被命名爲'foo'的共享庫模塊,將會生成'libfoo.so'文件。
LOCAL_SRC_FILES 當前模塊包含的所有源碼文件, 我們可以這麼寫LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE_TAGS 當前模塊所包含的標籤,一個模塊可以包含多個標籤。標籤的值可能是 debug, eng, user,development 或者 optional。其中,optional 是默認標籤。標籤是提供給編譯類型使用的。不同的編譯類型會安裝包含不同標籤的模塊,建議寫成LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_JAVA_LIBRARIES 當前模塊依賴的Java靜態庫,所謂靜態庫,即編譯完會存在於你的module裏面,成爲其一部分
LOCAL_SHARED_LIBRARIES 當前模塊在運行時依賴的動態庫名, 即編譯完不會存在於你的module裏面
LOCAL_CERTIFICATE 簽署當前應用的證書名稱,比如platform, 如下LOCAL_CERTIFICATE := platforms
LOCAL_SHARED_LIBRARIE 當前模塊在運行時依賴的動態庫名
LOCAL_PRELINK_MODULE 是否需要預連接處理(默認需要,用來做動態庫優化)
LOCAL_REQUIRED_MODULES 指定模塊運行所依賴的模塊(模塊安裝時將會同步安裝它所依賴的模塊)
LOCAL_PROGUARD_ENABLED enabled或者disabled 指定是否啓動混淆
LOCAL_PROGUARD_FLAG_FILES 指定混淆配置 proguard.config
LOCAL_PACKAGE_NAM 當前 APK 應用的名稱。
LOCAL_CFLAGS 提供給 C/C++ 編譯器的額外編譯參數, 比如指定所有warning成error, 指定優化等級這些, 比如: LOCAL_CFLAGS := -Werror
LOCAL_C_INCLUDES C/C++所需的頭文件路徑,比如:LOCAL_C_INCLUDES += $(JNI_H_INCLUDE) \ $(LOCAL_PATH) \ system/core/include \ frameworks/base/include \ libnativehelper/include \
LOCAL_JAVA_LIBRARIES 編譯java應用程序和庫的時候指定包含的java類庫,目前有core和framework兩種, 多數情況下定義成LOCAL_JAVA_LIBRARIES := core framework注意LOCAL_JAVA_LIBRARIES不是必須的,而且編譯APK時不允許定義(系統會自動添加)
LOCAL_REQUIRED_MODULES 指定模塊運行所依賴的模塊(模塊安裝時將會同步安裝它所依賴的模塊)
LOCAL_PREBUILT_LIBS 需要預編譯的lib, 類似PREBUILT的還有很多,比如LOCAL_PREBUILT_JAVA_LIBRARIES, LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES
include $(BUILD_STATIC_LIBRARY) 表示編譯成靜態庫
include $(BUILD_SHARED_LIBRARY) 表示編譯成動態庫。
include $(BUILD_EXECUTABLE) 表示編譯成可執行程序
include $(BUILD_PACKAGE) 編譯成APK
include $(BUILD_STATIC_JAVA_LIBRARY) 編譯成Java靜態庫
include $(BUILD_MULTI_PREBUILT) 其實是會將prebuild的那些,還有required那些庫拷到本地來編譯

以上是一些常看到的配置項,其實其他的還有很多, 尤其寫native的,那makefile更加複雜, 還有framework/base下的Android.mk也很複雜, 都是一些不常見的定義.以後遇到不懂的本文還會繼續補充.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章