android makefile(adroid.mk)分析

转自:http://blog.csdn.net/liuyahui312031/article/details/6039299   作者:liuyahui312031

android是什么就不用说了,android自从开源以来,就受到很多人的追捧。当然,一部人追捧它是因为它

是Google开发的。对一个程序员来说,一个系统值不值得追捧得要拿代码来说话。我这里并不打算分析

android的代码,而是android的makefile,我想通过分析andorid的makefile来告诉大家如何写

makefile。

对于一个程序新手而言,好的IDE是他们追捧的对象。但当他接触的代码多了之后,就会逐渐发现IDE不够

用了,因为有好多东西用IDE是不好做的,例如自动编译,测试,版本控制,编译定制等。这跟政治课上的

一句话有点像:资本主义开始的时候是促进生产力发展的,但到了后来又成了阻碍生产力发展的因素了。如

果一个程序不能摆脱IDE的限制(不是不用,而是要有选择的用),那么他就很难提高。要知道,IDE和

makefile代表了两种不同的思想:IDE根据强调的是简化计算机与用户的交互;而makefile体现的是自动

化。

对于一个一开始就接触linux的人来说,makefile可能是比较容易学的(熟能生巧),对于一个一开始就接

触Windows的人来说,makefile就不太好学,这主要是应该很多时候会不自觉地去用Visual

Studio(Visual Studio是个好东西,特别是它的调试)。不知道大叫有没有这个的感觉:一个人如果先接

触c,再接触java会比较容易点;如果一个人先接触java,再接触c,就会比较反感c。

这个先引用一下百度百科对makefile的一些描述:

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了

一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,

甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操

作系统的命令。

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程

完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile

中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual

C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自

动维护编译工作。而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各

个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。makefile 文件是许多

编译器--包括 Windows NT 下的编译器--维护编译信息的常用方法,只是在集成开发环境中,

用户通过友好的界面修改 makefile 文件而已。

对于android而言,android使用的是GNU的make,因此它的makefile格式也是GNU的makefile格

式。现在网络上关于makefile最好的文档就是陈皓的《跟我一起写makefile》,这份文档对makefile进

行了详细的介绍,因此推荐大家先看这份文档(电子版可以到http://pipi.googlecode.com/files/How

%20to%20Write%20makefile.pdf下载,陈皓的blog在http://blog.csdn.net/haoel)。

android最顶层的目录结构如下:

.

|-- Makefile (全局的Makefile)

|-- bionic (Bionic含义为仿生,这里面是一些基础的库的源代码)

|-- bootloader (引导加载器)

|-- build (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具)

|-- dalvik (JAVA虚拟机)

|-- development (程序开发所需要的模板和工具)

|-- external (目标机器使用的一些库)

|-- frameworks (应用程序的框架层)

|-- hardware (与硬件相关的库)

|-- kernel (Linux2.6的源代码)

|-- packages (Android的各种应用程序)

|-- prebuilt (Android在各种平台下编译的预置脚本)

|-- recovery (与目标的恢复功能相关)

`-- system (Android的底层的一些库)

本文将要分析的是build目录下的makefile和shell文件,android的代码是1.5的版本。

主要的目录结构如下:

1.makefile入门

1.1 makefile helloworld

1.2 用makefile构建交叉编译环境

1.3 makefile里面的一些技巧

2.android makefile分析

2.1 android shell分析

2.2 android build下的各个makefile分析

3. android其他目录的android.mk分析

由于最近研究生要毕业了,得找工作了,所以可能分析有时候会间断一两天,望大家能够谅解。

作为序的最后,大家先通过网络的一些文章来了解一下andoroid的makefile。

1.Android build system

2.Android Building System 分析

3.Android Build System(介绍使用)

Android Building System 分析

by thinker

2 Columns

關鍵字:

Androi d coding

想要了解一個系統,我常會從 makefile 或是 building system 下手, 以了解系統組成元素

為何? 目錄結構為何? 對於 Android ,我也不例外。 透過了解 building system ,我們能知

道如何新增、修改、刪除程式, 並保有完整性,順利編譯出結果。

設定檔

Android building system 包括幾種重要的設定檔,

· Androi d.mk

· AndroidProducts.mk

· target_<os>-

· BoardConfig.mk

· buildspec.mk

Android.mk 是 module 和 package 的設定檔,每個 module/package 的目錄下都會有一個

Android.mk。 所謂的 module 是指系統的 native code ,相對於用 Java 寫成

的 Androidapplication 稱為 package。

AndroidProducts.mk 則設定 product 配置。 product 即特定 系統版本,透過編譯不同

product ,產生不同軟體配置內容,安裝不同的 application。 Product 可視為特定專案,產

生特定規格系統。

BoardConfig.mk 是為 product 主板做設定,像是 driver 選擇、 設定。*

buildspec.mk 是位於 source 根目錄下,為進行編譯者所做之額外設定。 例如,可在此選擇

要產生的 product 、平台、額外的 module/package 等。

參數

build/envsetup.sh 實作一個 mm 指令,以編譯單一 module,不需編譯整個 source

tree。ONE_SHOT_MAKEFILE 這個 makefile 變數/參數就是用以實作這個功能。使用 方法是在

執行 make 時,將該變數指定為 module 的 Android.mk。

· make ONE_SHOT_MAKEFILE=

透過定義 CREATE_MODULE_INFO_FILE , building system 會將所有 module 資訊 列在 $

(PRODUCT_OUT)/module-info.txt 檔案裡。

· make CREATE_MODULE_INFO_FILE=true

設定 BUILD_TINY_ANDROID=true , building system 產生一個簡單的 image , 以測試硬體

的可用度。此功能用於移植的早期階段,以快速 bring up 。

HOST_BUILD_TYPE 和 TARGET_BUILD_TYPE 指定 building system 產生 binary 的目的為

debug 或 release 。透過設定此二變數,能產生包含 debug information 的 binry 。

· debug

· release

這些參數,也可設於 buildspec.mk 裡,以避免開發過程不斷的重新指定。

Goals

一般編輯整個 Android 系統,就是使用 droid 這個 goal。 droid 會產生一個 完整的系統,

包括 bootloader、kernel、系統程式、模組和應用程式。

showcommands 和 droid 功能相同,但 droid 在編譯過程不顯示所使用的指令。 透過

showcommands 這個 goal, building system 顯示過程中每一個步驟的詳細 指令。

Makefile 的流程

· 初始化相關變數

· 偵測編譯環境和目標環境

· 決定目標 product

· 讀取 product 的設定

· 讀取 product 所指定之目標平台架構設定

· 選擇 toolchain

· 指定編譯參數 (*

· 清除輸出目錄

· 設定/檢查版本編號

· 讀取所有 BoardConfig.mk 檔案

· 讀取所有 module 的設定

· 根據設定,產生必需的 rule

· 產生 image

以上的主要流程都是由 build/core/main.mk 所安排。

初始化和偵測

由 build/core/config.mk 所進行。 build/core/envsetup.mk 檢查 developer 的設定

(buildspec.mk) , 並檢查執行環境,以決定輸出目錄、項目。

build/core/config.mk 本身還依據參數,決定解譯時的相關參數。像是 compiler 的路徑、

flags, lex 、yacc 的路徑參數等。

關於 product 的相關設定,則是由 build/core/product_config.mk 所處理, 使用

build/core/product.mk 提供之 macro 載入。根據 AndroidProduct.mk 的內容,

product_config.mk 決定了

· PRODUCT_TAGS

· OTA_PUBLIC_KEYS

· PRODUCT_POLICY

· ......

Product 設定的讀取

Android product 的設定來自於 build/target/product/AndroidProduct.mk 和 vendor 子目

錄下的 AndroidProduct.mk 。 building system 透過 find 指令, 找出所有可能的

AndroidProduct.mk。 AndroidProduct.mk 裡定義 PRODUCT_MAKEFILES 變數,列舉所有實際定

義 product 的 makefile。 這些 makefile 各自定義獨立的 product 。product 相關參數,

存成 PRODUCTS.

Module 設定的讀取

Module 是指 native code 的軟體元件,而 Java application 則被稱為 package。

build/core/definitions.mk 定義 module/package 相關 macro ,讀取、檢查

module/package 定義檔;分散 source tree 各處的 Android.mk 檔案。 build/core/main.mk

使用 find 指令,在這些子目錄下找出所有 Android.mk , 並將路徑存在 subdir_makefiles

變數裡。最後,include 這些檔案。

這些 Android.mk 會 include 定義成變數 BUILD_SHARED_LIBRARY 、BUILD_PACKAGE 等, 和

其目的相配的 makefile。這些 makefile 會變 Android.mk 定義之內容,存成 ALL_MODULES.

Search Android.mk 的路徑,基本上會是整個 source tree 。但會依特定的 goal , 選擇性

只找尋特定目錄。例如 SDK 只需特定目錄下的 Android.mk 。

Board Level 設定

和目標平台主板相關之設定,例如使用了什麼裝置、driver 等,或是是否需要編譯

bootloader 、 kernel 等,都是在 BoardConfig.mk 裡設定。同樣,每張主板 可以有不同設

定,存在不同目錄下的 BoardConfig.mk ,以 find 尋找如下檔案:

· build/target/board/$(TARGET_DEVICE)/BoardConfig.mk

· vendor/*/$(TARGET_DEVICE)/BoardConfig.mk

TARGET_DEVICE 是 product 所定義,因此同一個 BoardConfig.mk 可被多個 product 所使用。

一個 TARGET_DEVICE ,通常只有一個 BoardConfig.mk 。 BoardConfig.mk 會被直接 include

到 building system 的 name space 裡。 因此,一些 module 的 enable/disable ,可以在

BoardConfig.mk 以對映不同的 主板。

Rules

在 module 的定義檔 Android.mk 裡,可定義 module 的 tag, LOCAL_MODULE_TAGS, 以分類

這些 module。 每一個 product 可以指定需要的 tag (PRODUCT_TAGS),使 building system

只編譯標示這些 tag 的 module。在 build/core/main.mk 裡,所有標示特定 tag 的 module

收集為 ALL_DEFAULT_INSTALLED_MODULES ,並 include build/core/Makefile 處理。

build/core/Makefile 為這些 module 產生 rule ,並使產生 image 的 goal depend on 這些

rule ,使這些 module 被編譯。

結論

Android 的 building system 其實不是那麼複雜。在了解之後,也不是那麼難修改。 但,

GNU make 的一些語法,所 building system 使用一些不是那麼直覺的用法, 使的 building

system 較難了解。但,花點心思就能克服。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值