Android編譯系統分析

來源:互聯網
上載者:User

轉自 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

相關文章

聯繫我們

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