理解 Android Build 系統

來源:互聯網
上載者:User

標籤:

在配置了以上的檔案之後,便可以編譯出我們新添加的裝置的系統鏡像了。

首先,調用“source build/envsetup.sh”該命令的輸出中會看到 Build 系統已經引入了剛剛添加的 vendorsetup.sh 檔案。

然後再調用“lunch”函數,該函數輸出的列表中將包含新添加的 vendorsetup.sh 中添加的條目。然後通過編號或名稱選擇即可。

最後,調用“make -j8”來執行編譯即可。

添加新的模組

關於“模組”的說明在上文中已經提到過,這裡不再贅述。

在 源碼樹中,一個模組的所有檔案通常都位於同一個檔案夾中。為了將當前模組添加到整個 Build 系統中,每個模組都需要一個專門的 Make 檔案,該檔案的名稱為“Android.mk”。Build 系統會掃描名稱為“Android.mk”的檔案,並根據該檔案中內容編譯出相應的產物。

需 要注意的是:在 Android Build 系統中,編譯是以模組(而不是檔案)作為單位的,每個模組都有一個唯一的名稱,一個模組的依賴對象只能是另外一個模組,而不能是其他類型的對象。對於已經 編譯好的二進位庫,如果要用來被當作是依賴對象,那麼應當將這些已經編譯好的庫作為單獨的模組。對於這些已經編譯好的庫使用 BUILD_PREBUILT 或 BUILD_MULTI_PREBUILT。例如:當編譯某個 Java 庫需要依賴一些 Jar 包時,並不能直接指定 Jar 包的路徑作為依賴,而必須首先將這些 Jar 包定義為一個模組,然後在編譯 Java 庫的時候通過模組的名稱來依賴這些 Jar 包。

下面,我們就來講解 Android.mk 檔案的編寫:

Android.mk 檔案通常以以下兩行代碼作為開頭:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)


這兩行代碼的作用是:

   設定當前模組的編譯路徑為當前檔案夾路徑。
   清理(可能由其他模組設定過的)編譯環境中用到的變數。

為了方便模組的編譯,Build 系統設定了很多的編譯環境變數。要編譯一個模組,只要在編譯之前根據需要設定這些變數然後執行編譯即可。它們包括:

   LOCAL_SRC_FILES:當前模組包含的所有原始碼檔案。
   LOCAL_MODULE:當前模組的名稱,這個名稱應當是唯一的,模組間的依賴關係就是通過這個名稱來引用的。
   LOCAL_C_INCLUDES:C 或 C++ 語言需要的標頭檔的路徑。
   LOCAL_STATIC_LIBRARIES:當前模組在靜態連結時需要的庫的名稱。
   LOCAL_SHARED_LIBRARIES:當前模組在運行時依賴的動態庫的名稱。
   LOCAL_CFLAGS:提供給 C/C++ 編譯器的額外編譯參數。
   LOCAL_JAVA_LIBRARIES:當前模組依賴的 Java 共用庫。
   LOCAL_STATIC_JAVA_LIBRARIES:當前模組依賴的 Java 靜態庫。
   LOCAL_PACKAGE_NAME:當前 APK 應用的名稱。
   LOCAL_CERTIFICATE:簽署當前應用的認證名稱。
   LOCAL_MODULE_TAGS:當前模組所包含的標籤,一個模組可以包含多個標籤。標籤的值可能是 debug, eng, user,development 或者 optional。其中,optional 是預設標籤。標籤是提供給編譯類型使用的。不同的編譯類型會安裝包含不同標籤的模組,關於編譯類型的說明如表 7 所示:

表 3 中的檔案已經定義好了各種類型模組的編譯方式。所以要執行編譯,只需要引入表 3 中對應的 Make 檔案即可(通過常量的方式)。例如,要編譯一個 APK 檔案,只需要在 Android.mk 檔案中,加入“include $(BUILD_PACKAGE)

除此以外,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 輸出的目標檔案夾路徑。

清單 2 和清單 3 分別是編譯 APK 檔案和編譯 Java 靜態庫的 Make 檔案樣本:


清單 2. 編譯一個 APK 檔案

雙擊代碼全選
12345678910 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # 擷取所有子目錄中的 Java 檔案LOCAL_SRC_FILES := $(call all-subdir-java-files)          # 當前模組依賴的靜態 Java 庫,如果有多個以空格分隔LOCAL_STATIC_JAVA_LIBRARIES := static-library # 當前模組的名稱LOCAL_PACKAGE_NAME := LocalPackage # 編譯 APK 檔案include $(BUILD_PACKAGE)

清單 3. 編譯一個 Java 的靜態庫

雙擊代碼全選
1234567891011121314 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)       # 擷取所有子目錄中的 Java 檔案LOCAL_SRC_FILES := $(call all-subdir-java-files)       # 當前模組依賴的動態 Java 庫名稱LOCAL_JAVA_LIBRARIES := android.test.runner       # 當前模組的名稱LOCAL_MODULE := sample       # 將當前模組編譯成一個靜態 Java 庫include $(BUILD_STATIC_JAVA_LIBRARY)

結束語

整個 Build 系統包含了非常多的內容,由於篇幅所限,本文只能介紹其中最主要內容。

由於 Build 系統本身也是在隨著 Android 平台不斷的開發過程中,所以不同的版本其中的內容和定義可能會發生變化。網路上關於該部分的資料很零碎,並且很多資料中的一些內容已經過時不再適用,再加上缺少官方文檔,所以該部分的學習存在一定的難度。

這就要求我們要有很強的代碼閱讀能力,畢竟代碼是不會說謊的。要知道,對於我們這些開發人員來說,原始碼就是我們最忠實的朋友。 Use the Source,Luke!

理解 Android Build 系統

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.