Android Building System 總結

來源:互聯網
上載者:User

轉自:http://blog.csdn.net/yili_xie/article/details/5004205

花了一個月的時間來看Android Make,在網上總是看到某某大蝦說一天就把Android Make overview了一下,不得不感歎現在大蝦的強大和咱那連蝸牛都可以鄙視一下的進度。不過總算是徹底看清的Android make這個系統,不得不當初架構出這套機制的神人頂禮膜拜一下,虔誠地燒三柱高香,驚歎於神人的偉大的時候也越感自己的滄海一粟,苦海無邊,回頭無岸, 就加油滑水吧。
      閑話就不多說了,來瞅瞅這套機制,Android以模組的形式來組織各個系統中的組件,Eng專業點的詞彙就是Module,就是各位在幾乎每個目錄下都能看到的Android.mk。可以簡單地把Android所有的Make檔案分為4種:
      1、For config
      這類檔案主要來配置product,board,以及根據你的Host和Target選擇相應的工具以及設定相應的通用編譯選項:
      build/core/config.mk         summary of config
      build/core/envsetup.mk    generate dir config and so on
      build/target/product         product config
      build/target/board            board config
      build/core/combo              build flags config
      這裡解釋下這裡的board和product。borad主要是設計到硬體晶片的配置,比如是否提供硬體的某些功能,比如說GPU等等,或者晶片支援浮 點運算等等。product是指標對當前的晶片配置定義你將要生產產品的個性配置,主要是指APK方面的配置,哪些APK會包含在哪個product中, 哪些APK在當前product中是不提供的。
      config.mk是一個總括性的東西,它裡面定義了各種module編譯所需要使用的HOST工具以及如何來編譯各種模組,比如說 BUILT_PREBUILT就定義了如何來編譯先行編譯模組。envsetup.mk主要會讀取由envsetup.sh寫入環境變數中的一些變數來配置 編譯過程中的輸出目錄,combo裡面主要定義了各種Host和Target結合的編譯器和編譯選項。
      2、 Module Compile
      這類檔案主要定義了如何來處理Module的Android.mk,以及採用何種方式來產生目標模組,這些模組建置規則都定義在config.mk裡面,我們可以看看:
      CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk
      BUILD_HOST_STATIC_LIBRARY:= $(BUILD_SYSTEM)/host_static_library.mk
      BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk
      BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk
      BUILD_RAW_STATIC_LIBRARY := $(BUILD_SYSTEM)/raw_static_library.mk
      BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk
      BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk
      BUILD_RAW_EXECUTABLE:= $(BUILD_SYSTEM)/raw_executable.mk
      BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk
      BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk
      BUILD_HOST_PREBUILT:= $(BUILD_SYSTEM)/host_prebuilt.mk
      BUILD_PREBUILT:= $(BUILD_SYSTEM)/prebuilt.mk
      BUILD_MULTI_PREBUILT:= $(BUILD_SYSTEM)/multi_prebuilt.mk
      BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk
      BUILD_STATIC_JAVA_LIBRARY:= $(BUILD_SYSTEM)/static_java_library.mk
      BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk
      BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk
      BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk
      BUILD_KEY_CHAR_MAP := $(BUILD_SYSTEM)/key_char_map.mk
      除了CLEAR_VARS是清楚本地變數之外,其他所有的都對應了一種模組的建置規則,每一個本地模組最後都會include其中的一種來產生目標模 塊。大部分上面的.mk都會包含base_rules.mk,這是對模組進行處理的基礎檔案,建議要寫本地模組的都去看看,看明白了為什麼 Android.mk要這麼寫就會大致明白了。
      3、Local Module
      本地模組的Makefile檔案就是我們在Android裡面幾乎上隨處可見的Android.mk。Android進行編譯的時候會通過下面的函數來 遍曆所有子目錄中的Android.mk,一旦找到就不會再往層子目錄繼續尋找(所有你的模組定義的頂層Android.mk必須包含自己定義的子目錄中 的Android.mk)。
      subdir_makefiles += /
          $(shell build/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
       不同類型的本地模組具有不同的文法,但基本上是相通的,只有個別變數的不同,如何添加模組在前面的文章已經說過了,大家可以參考。
       Android通過LOCAL_MODULE_TAGS來決定哪些本地模組會不會編譯進系統,通過PRODUCT和LOCAL_MODULE_TAGS來 決定哪些應用程式套件會編譯進系統,如果使用者不指定LOCAL_MODULE_TAGS,預設它的值是user。此外使用者可以通過buildspec.mk來指 定你需要編譯進系統的模組。
       使用者也可以通過mm來編譯指定模組,或者通過make clean-module_name來刪除指定模組。
       4、Package
       這主要指的是build/core/Makefile這個檔案,它定義了產生各種img的方式,包括ramdisk.img   userdata.img  system.img  update.zip  recover.img等。我們可以看看這些img都是如何產生的,對應著我們常用的幾個make goals:

在實際的過程中,我們也可以自己編輯out目錄下的組建檔案,然後手工打包相應產生相應的img,最常用的是加入一些需要整合進的prebuilt file。
      
       所有的Makefile都通過build/core/main.mk這個檔案組織在一起,它定義了一個預設goals:droid,當我們在TOP目錄下 敲Make實際上就等同於我們執行make droid。當Make include所有的檔案,完成對所有make我檔案的解析以後就會尋找產生droid的規則,依次產生它的依賴,直到所有滿足的模組被編譯好,然後使用 相應的工具打包成相應的img。

       基本上Android building system就是以這樣一種方式組織在一起的了,下面說一點閑散的東西。首先是如何來加快Android的編譯過程,因為每次Android都要遍曆所有 的Android.mk,不管是編譯整個工程還是只編譯某個模組。所以可以將遍曆的結果儲存下來,下次直接從檔案讀就好了,但是這裡容易出錯,所以一定要 確認是否正確包含了所有的.mk,當新加入檔案的時候確認將原來儲存的檔案刪除。下面是我寫的加快編譯的一個makefile,將下面的語句替換掉 main.mk中的相應部分就可以了:
       FROM:
       subdir_makefiles += /
           $(shell build/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
       TO:
       ifneq ($(ONE_SHOT_MAKEFILE),)
       else
       ifneq ($(CASH_MK),true)
       subdir_makefiles += /
           $(shell build/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
      else
     subdir-makefiles-cash := $(shell cat build/subdir_mk_cash)
     ifeq ($(subdir-makefiles-cash),)
     $(warning No .mk cash ,create now !)
     subdir_makefiles += /
           $(shell build/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
     mk-to-file := $(shell echo $(subdir_makefiles) > build/subdir_mk_cash)
     else
    $(warning Using cash mk !)
    subdir_makefiles := $(shell cat build/subdir_mk_cash)
    endif
    endif
    endif
       通過CASH_MK=true來開啟快速編譯的功能,因為沒有對錯誤進行檢測的操作,所以使用的時候一定要特別小心。

       最後一個是擴充SDK API的問題,Android可以編譯出自己的SDK,並擴充相應的SDK API,現在沒有仔細的研究,只瞭解一個粗暴的方法就是在frameworks/base/core/java中添加相應的類。將來有時間的話再仔細研究 下~~

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.