Android編譯系統分析

轉自 http://blog.csdn.net/yili_xie/archive/2009/11/30/4906865.aspx

 

編譯腳本及系統變量
build/envsetup.sh腳本分析
在編譯源代碼之前通常需要在android源代碼頂層目錄執行 . ./build/envsetup.sh 目的是爲了使用
腳本 envsetup.sh 裏面定義了一些函數:
function help()
function get_abs_build_var()
function get_build_var()
function check_product()
function check_variant()
function setpaths()
function printconfig()
function set_stuff_for_environment()
function set_sequence_number()
function settitle()
function choosetype()
function chooseproduct()
function choosevariant()
function tapas()
function choosecombo()
function print_lunch_menu()
function lunch()
function gettop
function m()
function findmakefile()
function mm()
function mmm()
function croot()
function pid()
function gdbclient()
function jgrep()
function cgrep()
function resgrep()
function getprebuilt
function tracedmdump()
function runhat()
function getbugreports()
function startviewserver()
function stopviewserver()
function isviewserverstarted()
function smoketest()
function runtest()
function runtest_py()
function godir ()

choosecombo 命令分析:
function choosecombo()
{
choosesim $1
echo
echo
choosetype $2

echo
echo
chooseproduct $3

echo
echo
choosevariant $4

echo
set_stuff_for_environment
printconfig
}
會依次進行如下選擇:
Build for the simulator or the device?
1. Device
2. Simulator
Which would you like? [1]

Build type choices are:
1. release
2. debug
Which would you like? [1]

Product choices are:
1. emulator
2. generic
3. sim
4. littleton
You can also type the name of a product if you know it.
Which would you like? [littleton]

Variant choices are:
1. user
2. userdebug
3. eng
Which would you like? [eng] user
默認選擇以後會出現:
TARGET_PRODUCT=littleton
TARGET_BUILD_VARIANT=user
TARGET_SIMULATOR=false
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=
==========
function chooseproduct()函數分析:
choices=(`/bin/ls build/target/board/*/BoardConfig.mk vendor/*/*/BoardConfig.mk 2> /dev/null`)
讀取 build/target/board/* 目錄下的板配置文件:BoardConfig.mk
讀取 vendor/*/*/目錄下的板配置文件:BoardConfig.mk
choices 的值爲:
build/target/board/emulator/BoardConfig.mk
build/target/board/generic/BoardConfig.mk
build/target/board/sim/BoardConfig.mk
vendor/marvell/littleton/BoardConfig.mk
經過:
for choice in ${choices[@]}
do
# The product name is the name of the directory containing
# the makefile we found, above.
prodlist=(${prodlist[@]} `dirname ${choice} | xargs basename`)
done
的處理,prodlist的值爲:
emulator generic sim littleton
所以選擇菜單爲:
Product choices are:
1. emulator
2. generic
3. sim
4. littleton
如果選擇 4,那麼 TARGET_PRODUCT 被賦值爲: littleton。


board_config_mk := /
$(strip $(wildcard /
$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk /
vendor/*/$(TARGET_DEVICE)/BoardConfig.mk /
))



怎樣添加一個模塊
LOCAL_PATH:= $(call my-dir)
#編譯靜態庫
include $(CLEAR_VARS)
LOCAL_MODULE = libhellos
LOCAL_CFLAGS = $(L_CFLAGS)
LOCAL_SRC_FILES = hellos.c
LOCAL_C_INCLUDES = $(INCLUDES)
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_COPY_HEADERS_TO := libhellos
LOCAL_COPY_HEADERS := hellos.h
include $(BUILD_STATIC_LIBRARY)

#編譯動態庫
include $(CLEAR_VARS)
LOCAL_MODULE = libhellod
LOCAL_CFLAGS = $(L_CFLAGS)
LOCAL_SRC_FILES = hellod.c
LOCAL_C_INCLUDES = $(INCLUDES)
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_COPY_HEADERS_TO := libhellod
LOCAL_COPY_HEADERS := hellod.h
include $(BUILD_SHARED_LIBRARY)

BUILD_TEST=true
ifeq ($(BUILD_TEST),true)
#使用靜態庫
include $(CLEAR_VARS)
LOCAL_MODULE := hellos
LOCAL_STATIC_LIBRARIES := libhellos
LOCAL_SHARED_LIBRARIES :=
LOCAL_LDLIBS += -ldl
LOCAL_CFLAGS := $(L_CFLAGS)
LOCAL_SRC_FILES := mains.c
LOCAL_C_INCLUDES := $(INCLUDES)
include $(BUILD_EXECUTABLE)

#使用動態庫
include $(CLEAR_VARS)
LOCAL_MODULE := hellod
LOCAL_MODULE_TAGS := debug
LOCAL_SHARED_LIBRARIES := libc libcutils libhellod
LOCAL_LDLIBS += -ldl
LOCAL_CFLAGS := $(L_CFLAGS)
LOCAL_SRC_FILES := maind.c
LOCAL_C_INCLUDES := $(INCLUDES)
include $(BUILD_EXECUTABLE)
endif # ifeq ($(WPA_BUILD_SUPPLICANT),true)

########################
#local_target_dir := $(TARGET_OUT)/etc/wifi
#include $(CLEAR_VARS)
#LOCAL_MODULE := wpa_supplicant.conf
#LOCAL_MODULE_TAGS := user
#LOCAL_MODULE_CLASS := ETC
#LOCAL_MODULE_PATH := $(local_target_dir)
#LOCAL_SRC_FILES := $(LOCAL_MODULE)
#include $(BUILD_PREBUILT)
########################
系統變量解析
LOCAL_MODULE - 編譯的目標對象
LOCAL_SRC_FILES - 編譯的源文件
LOCAL_C_INCLUDES - 需要包含的頭文件目錄
LOCAL_SHARED_LIBRARIES - 鏈接時需要的外部庫
LOCAL_PRELINK_MODULE - 是否需要prelink處理
BUILD_SHARED_LIBRARY - 指明要編譯成動態庫


LOCAL_PATH - 編譯時的目錄
$(call 目錄,目錄….) 目錄引入操作符
如該目錄下有個文件夾名稱 src,則可以這樣寫 $(call src),那麼就會得到 src 目錄的完整路徑

include $(CLEAR_VARS) -清除之前的一些系統變量
CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk
在 build/core/config.mk 定義 CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk
通過include 包含自定義的.mk文件(即是自定義編譯規則)或是引用系統其他的.mk文件(系統定義的編譯規則)。

LOCAL_SRC_FILES - 編譯的源文件
可以是.c, .cpp, .java, .S(彙編文件)或是.aidl等格式
不同的文件用空格隔開。如果編譯目錄子目錄,採用相對路徑,如子目錄/文件名。也可以通過$(call 目錄),指明編譯某目錄
下所有.c/.cpp/.java/.S/ .aidl文件.追加文件 LOCAL_SRC_FILES += 文件

LOCAL_C_INCLUDES - 需要包含的頭文件目錄
可以是系統定義路徑,也可以是相對路徑. 如該編譯目錄下有個include目錄,寫法是include/*.h

LOCAL_SHARED_LIBRARIES - 鏈接時需要的外部共享庫
LOCAL_STATIC_LIBRA RIES - 鏈接時需要的外部外部靜態
LOCAL_JAVA_LIBRARIES 加入jar包

LOCAL_MODULE - 編譯的目標對象
module 是指系統的 native code,通常針對c,c++代碼
./system/core/sh/Android.mk:32:LOCAL_MODULE:= sh
./system/core/libcutils/Android.mk:71:LOCAL_MODULE := libcutils
./system/core/cpio/Android.mk:9:LOCAL_MODULE := mkbootfs
./system/core/mkbootimg/Android.mk:8:LOCAL_MODULE := mkbootimg
./system/core/toolbox/Android.mk:61:LOCAL_MODULE:= toolbox
./system/core/logcat/Android.mk:10:LOCAL_MODULE:= logcat
./system/core/adb/Android.mk:65:LOCAL_MODULE := adb
./system/core/adb/Android.mk:125:LOCAL_MODULE := adbd
./system/core/init/Android.mk:20:LOCAL_MODULE:= init
./system/core/vold/Android.mk:24:LOCAL_MODULE:= vold
./system/core/mountd/Android.mk:13:LOCAL_MODULE:= mountd

LOCAL_PACKAGE_NAME
Java 應用程序的名字用該變量定義
./packages/apps/Music/Android.mk:9:LOCAL_PACKAGE_NAME := Music
./packages/apps/Browser/Android.mk:14:LOCAL_PACKAGE_NAME := Browser
./packages/apps/Settings/Android.mk:8:LOCAL_PACKAGE_NAME := Settings
./packages/apps/Stk/Android.mk:10:LOCAL_PACKAGE_NAME := Stk
./packages/apps/Contacts/Android.mk:10:LOCAL_PACKAGE_NAME := Contacts
./packages/apps/Mms/Android.mk:8:LOCAL_PACKAGE_NAME := Mms
./packages/apps/Camera/Android.mk:8:LOCAL_PACKAGE_NAME := Camera
./packages/apps/Phone/Android.mk:11:LOCAL_PACKAGE_NAME := Phone
./packages/apps/VoiceDialer/Android.mk:8:LOCAL_PACKAGE_NAME := VoiceDialer


BUILD_SHARED_LIBRARY - 指明要編譯成動態庫。
編譯的目標,用include 操作符
UILD_STATIC_LIBRARY來指明要編譯成靜態庫。
如果是java文件的話,會用到系統的編譯腳本host_java_library.mk,用BUILD_PACKAGE來指明。三個編譯
-------------------
include $(BUILD_STATIC_LIBRARY)
BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk
-------------------
include $(BUILD_SHARED_LIBRARY)
./build/core/config.mk:50:BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk
-------------------
include $(BUILD_HOST_SHARED_LIBRARY)
BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk
-------------------
include $(BUILD_EXECUTABLE)
build/core/config.mk:51:BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk
-------------------
include $(BUILD_HOST_EXECUTABLE)
./build/core/config.mk:53:BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk
-------------------
BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk
-------------------
BUILD_JAVA_LIBRARY
./build/core/config.mk:58:BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk
------------------
BUILD_STATIC_JAVA_LIBRARY 編譯靜態JAVA庫
./build/core/config.mk:59:BUILD_STATIC_JAVA_LIBRARY:= $(BUILD_SYSTEM)/static_java_library.mk
------------------
BUILD_HOST_JAVA_LIBRARY 編譯本機用的JAVA庫
./build/core/config.mk:60:BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.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

============
LOCAL_PRELINK_MODULE
Prelink利用事先鏈接代替運行時鏈接的方法來加速共享庫的加載,它不僅可以加快起動速度,還可以減少部分內存開銷,
是各種Linux架構上用於減少程序加載時間、縮短系統啓動時間和加快應用程序啓動的很受歡迎的一個工具。程序運行時的
動態鏈接尤其是重定位(relocation)的開銷對於大型系統來說是很大的。
動態鏈接和加載的過程開銷很大,並且在大多數的系統上, 函數庫並不會常常被更動, 每次程序被執行時所進行的鏈接
動作都是完全相同的,對於嵌入式系統來說尤其如此。因此,這一過程可以改在運行時之前就可以預先處理好,即花一些時間
利用Prelink工具對動態共享庫和可執行文件進行處理,修改這些二進制文件並加入相應的重定位等信息,節約了本來在程序
啓動時的比較耗時的查詢函數地址等工作,這樣可以減少程序啓動的時間,同時也減少了內存的耗用。
Prelink的這種做法當然也有代價:每次更新動態共享庫時,相關的可執行文件都需要重新執行一遍Prelink才能保
證有效,因爲新的共享庫中的符號信息、地址等很可能與原來的已經不同了,這就是爲什麼 android framework代碼一改動,
這時候就會導致相關的應用程序重新被編譯。
這種代價對於嵌入式系統的開發者來說可能稍微帶來一些複雜度,不過好在對用戶來說幾乎是可以忽略的。
--------------------
變量設置爲false那麼將不做prelink操作
LOCAL_PRELINK_MODULE := false
默認是需要prlink的,同時需要在 build/core/prelink-linux-arm.map 中加入
libhellod.so 0x96000000
這個map文件好像是制定動態庫的地址的,在前面註釋上面有一些地址範圍的信息,注意庫與庫之間的間隔數,
如果指定不好的話編譯的時候會提示說地址空間衝突的問題。另外,注意排序,這裏要把數大的放到前面去,
按照大小降序排序。
解析 LOCAL_PRELINK_MODULE 變量
build/core/dynamic_binary.mk:94:ifeq ($(LOCAL_PRELINK_MODULE),true)
ifeq ($(LOCAL_PRELINK_MODULE),true)
$(prelink_output): $(prelink_input) $(TARGET_PRELINKER_MAP) $(APRIORI)
$(transform-to-prelinked)
transform-to-prelinked定義:
./build/core/definitions.mk:1002:define transform-to-prelinked
define transform-to-prelinked
@mkdir -p $(dir $@)
@echo "target Prelink: $(PRIVATE_MODULE) ($@)"
$(hide) $(APRIORI) /
--prelinkmap $(TARGET_PRELINKER_MAP) /
--locals-only /
--quiet /
$< /
--output $@
endef
./build/core/config.mk:183:APRIORI := $(HOST_OUT_EXECUTABLES)/apriori$(HOST_EXECUTABLE_SUFFIX)
prelink工具不是常用的prelink而是apriori,其源代碼位於” <your_android>/build/tools/apriori”
參考文檔:
動態庫優化——Prelink(預連接)技術
http://www.eefocus.com/article/09-04/71629s.html


===============
LOCAL_ARM_MODE := arm
目前Android大部分都是基於Arm處理器的,Arm指令用兩種模式Thumb(每條指令兩個字節)和arm指令(每條指令四個字節)

LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays
通過設定編譯器操作,優化級別,-O0表示沒有優化,-O1爲缺省值,-O3優化級別最高
LOCAL_CFLAGS += -W -Wall
LOCAL_CFLAGS += -fPIC -DPIC
LOCAL_CFLAGS += -O2 -g -DADB_HOST=1 -Wall -Wno-unused-parameter
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE -DSH_HISTORY
LOCAL_CFLAGS += -DUSEOVERLAY2
根據條件選擇相應的編譯參數
ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -DANDROID_GADGET=1
LOCAL_CFLAGS := $(PV_CFLAGS)
endif
ifeq ($(TARGET_BUILD_TYPE),release)
LOCAL_CFLAGS += -O2
endif

LOCAL_LDLIBS := -lpthread
LOCAL_LDLIBS += -ldl

ifdef USE_MARVELL_MVED
LOCAL_WHOLE_STATIC_LIBRARIES += lib_il_mpeg4aspdecmved_wmmx2lnx lib_il_h264decmved_wmmx2lnx
LOCAL_SHARED_LIBRARIES += libMrvlMVED
else
LOCAL_WHOLE_STATIC_LIBRARIES += lib_il_h264dec_wmmx2lnx lib_il_mpeg4aspdec_wmmx2lnx
endif

 




 以下內容轉自:http://www.360doc.com/content/11/0609/14/474846_122680003.shtml

一、Makefile的主要流程


以下主要流程都在build/core/main.mk裏安排。

    初始化相關的參數設置(buildspec.mk、envsetup.mk、config.mk)
    檢測編譯環境和目標環境
    讀取product的配置信息及目標平臺信息
    清除輸出目錄
    檢查版本號
    讀取Board的配置
    讀取所有Module的配置
    根據配置產生必要的規則(build/core/Makefile)
    生成image


主要配置文件:

    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結合的編
譯器和編譯選項。

配置部分主要完成以下幾個工作:

a) 基於Android 產品的配置(product config):選擇構建安裝的運行程序
(user package)
b) 設置 target 等相關變量TARGET_ARCH, TARGET_OS,TARGET_BUILD_TYPE,
TARGET_PREBUILT_TAG
c) 根據編譯環境設置 host等相關變量HOST_OS, HOST_ARCH,HOST_BUILD_TYPE,
HOST_PREBUILT_TAG
d) 編譯 target上運行程序所需的工具鏈及編譯參數設置,如linux-arm-
cc,cflag,include目錄等。
e) 編譯 host上運行程序所需的工具鏈及編譯參數設置。
下圖簡要介紹了Android build system的配置部分的主要構成及相互關係。


二、初始化參數設置


在main.mk裏,簡單設置幾個主要編譯路徑的變量後,來到config.mk:

——————————————config.mk——————————————

其中設置了源文件的一系列路徑,包括頭文件、庫文件、服務、API已經編譯工
具的路徑。(前36行)

從40行開始,定義一些編譯模塊的生成規則:

除了CLEAR_VARS是清楚本地變量之外,其他所有的都對應了一種模塊的生成規
則,每一個本地模塊最後都會include其中的一種來生成目標模塊。

回到config.mk,接着會嘗試讀取buildspec.mk的設置:



如同註釋所說,會嘗試查找buildspec.mk,如果文件不存在會自動使用環境變量
的設置,如果仍然未定義,會按arm默認的設置去build。

這裏的buildspec.mk可以自己創建,也可以將原先build/下的
buildspec.mk.default直接命名爲buildspec.mk並移到根目錄。

實際上,buildspec.mk配置都被屏蔽了,我們可以根據需要直接打開和修改一些
變量。在這裏我們可以加入自己的目標產品信息:

ifndef TARGET_PRODUCT

TARGET_PRODUCT:=generic_x86

endif

以及輸出目錄設置:

OUT_DIR:=$(TOPDIR)generic_x86

 

三、讀取Product的設定


回到config.mk,接着進行全局變量設置,進入envsetup.mk:

——————————————envsetup.mk——————————————

裏面的大部分函數都在build/envsetup.sh中定義。

首先,設置版本信息,(11行)在build/core/version_defaults.mk中具體定義
平臺版本、SDK版本、Product版本,我們可以將BUILD_NUMBER作爲我們產品
generic_x86的version信息,當然,也可以自定義一個版本變量。

回到envsetup.mk,接着設置默認目標產品(generic),這裏由於我們在
buildspec.mk裏設置過TARGET_PRODUCT,事實上這個變量值爲generic_x86。

然後讀取product的設置(41行),具體實現在build/core/product_config.mk
中,進而進入product.mk,從build/target/product/AndroidProducts.mk中讀出
PRODUCT_MAKEFILES,這些makefile各自獨立定義product,而我們的產品
generic_x86也應添加一個makefile文件generic_x86.mk。在generic_x86.mk中我
們可以加入所需編譯的PRODUCT_PACKAGES。

下面爲generic_x86.mk:


四、讀取BoardConfig


接着回到config.mk,(114行)這裏會搜索所有的BoardConfig.mk,主要有以下
幾個地方:

這裏的TARGET_DEVICE就是generic_x86,就是說爲了定義我們自己的產品
generic_x86,我們要在build/target/board下添加一個自己的目錄generic_x86用
來加載自己的board配置。

在BoardConfig.mk中會決定是否編譯bootloader、kernel等信息。

 

五、讀取所有Module


結束全局變量配置後,回到main.mk,馬上對編譯工具及版本進行檢查,錯誤
便中斷編譯。

142行,包含文件definitions.mk,這裏面定義了許多變量和函數供main.mk
使用。main.mk第446行,這裏會去讀取所有的Android.mk文件:

其中include $(ONE_SHOT_MAKEFILE)

這個ONE_SHOT_MAKEFILE是在前面提到的mm(envsetup.mk)函數中賦值的:

ONE_SHOT_MAKEFILE=$M make -C $T files $@

回到main.mk,最終將遍歷查找到的所有子目錄下的Android.mk的路徑保存到
subdir_makefiles變量裏(main.mk裏的470行):

我們在package/apps下每個模塊根目錄都能看到Android.mk,裏面會去定義
當前本地模塊的Tag:LOCAL_MODULE_TAGS,Android會通過這個Tag來決定哪些本地
模塊會編譯進系統,通過PRODUCT和LOCAL_MODULE_TAGS來決定哪些應用包會編譯進
系統。(前面說過,你也能通過buildspec.mk來制定你要編譯進系統的模塊)

這個過程在mian.mk的445行開始,最後需要編譯的模塊路徑打包到
ALL_DEFAULT_INSTALLED_MODULES(602行):

 

六、產生相應的Rules,生成image


所有需要配置的準備工作都已完成,下面該決定如何生成image輸出文件
了,這一過程實際上在build/core/Makefile中處理的。

這裏定義各種img的生成方式,包括ramdisk.img、userdata.img、
system.img、update.zip、recover.img等。


當Make include所有的文件,完成對所有make文件的解析以後就會尋找生成
對應目標的規則,依次生成它的依賴,直到所有滿足的模塊被編譯好,然後使用相
應的工具打包成相應的img。

 

具體make操作:


    完整編譯

我們在根目錄下輸入make命令即可開始完全編譯。這個命令實際編譯生成的
默認目標是droid。

也就是說,大家敲入make實際上執行的make droid。而接下來大家看看
main.mk文件裏最後面的部分,會有很多僞目標,如sdk、clean、clobber等,這些
在默認的make droid的命令下是不會執行的。我們可以在make後加上這些標籤來單
獨實現一些操作。如:輸入make sdk 將會生成該版本對應的SDK,輸入make clean
會清除上次編譯的輸出。


    模塊編譯

有時候我們只修改了某一個模塊,希望能單獨編譯這個模塊而不是重新完整
編譯一次,這時候我們要用到build/envsetup.sh中提供的幾個bash的幫助函
數。

在源代碼根目錄下執行:

. build/envsetup.sh(.後面有空格)

這樣大家相當於多了幾個可用的命令。

這時可以用help命令查看幫助信息:

其中對模塊編譯有幫助的是tapas、m、mm、mmm這幾個命令。

1、tapas——以交互方式設置build環境變量。

   輸入:tapas

第一步,選擇目標設備:

第二步,選擇代碼格式:

第三步,選擇產品平臺:

 

 注意:這裏,Google源代碼裏默認是generic,而我們針對自己的產品應修
改成generic_x86

 具體在build/envsetup.sh裏的函數chooseproduct()中對相應代碼進行修
改。

2、m、mm、mmm使用獨立模塊的make命令。

幾個命令的功能使用help命令查看。

舉個例子,我們修改了Camera模塊的代碼,現在需要重新單獨編譯這一塊,
這時可以使用mmm命令,後面跟指定模塊的路徑(注意是模塊的根目錄)。

具體如下:

mmm packages/apps/Camera/

爲了可以直接測試改動,編譯好後需要重新生成system.img

可以執行:make snod


    單獨編譯image文件

一般我們完整編譯後,會生成三個重要的image文件:ramdisk.img、
system.img和userdata.img。當然我們可以分開單獨去編譯這三個目標:

make ramdisk —— ramdisk.img

make userdataimage —— userdata.img

make systemimage  —— system.img


發佈了25 篇原創文章 · 獲贊 0 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章