目錄
1、執行命令$source build/envsetup.sh導出環境變量,加載編譯用到的環境變量,添加產品相應配置 2
2、執行source mbldenv.sh構建環境文件配置...2
3、然後執行命令$lunch選擇相應的產品,列出所有系統編譯項,讓用戶選擇編譯平臺...2
4、最後執行編譯Android系統de命令$make -j2.3
① 、/device/reallytek/rlk6737m_65_n/AndroidProducts.mk:裏面定義了安卓產品列表: 4
②、device\mediatek\mt6735\device.mk和device\reallytek\rlk6737m_65_n\evice.mk文件 4
③、Android.mk在Android的源碼目錄下去添加一個應用程序,在packages\apps下面有很多,可以仿照。 5
④、初始化腳本,分爲安卓默認的初始化腳本init.rc和廠商自定義的初始化腳本init.**.rc兩種 5
一、Android 編譯大概過程
1、執行命令$source build/envsetup.sh導出環境變量,加載編譯用到的環境變量,添加產品相應配置
涉及到:build\envsetup.sh和build\core\config.mk 和build\core\envsetup.mk等等
2、執行source mbldenv.sh構建環境文件配置
3、然後執行命令$lunch選擇相應的產品,列出所有系統編譯項,讓用戶選擇編譯平臺
其實lunch的本質就是遍歷vendorsetup.sh文件,這個文件名一定不能改,死的。在這裏我們可以添加lunch鏡像的選項
這裏會設計到一個腳本:device/reallytek/rlk6737m_65_n/full_rlk6737m_65_n.mk,該文件主要有如下重要信息:
//下面是定製信息
# Set those variables here to overwrite the inherited values.
PRODUCT_MANUFACTURER := TECNO //廠商
PRODUCT_NAME := full_rlk6737m_65_n //項目名稱
PRODUCT_DEVICE := rlk6737m_65_n
PRODUCT_MODEL := rlk6737m_65_n
PRODUCT_POLICY := android.policy_phone
PRODUCT_BRAND := TECNO //品牌,廠商名
PRODUCT_BUILD_NAME := H3713 //主板名
PRODUCT_DEVICE_NAME := TECNO-CX-Air //設備名
執行lunch顯示如下:
You're building on Linux
Lunch menu... pick a combo:
1. aosp_arm-eng
2. aosp_arm64-eng
3. aosp_mips-eng
4. aosp_mips64-eng
5. aosp_x86-eng
6. aosp_x86_64-eng
7. full_fugu-userdebug
8. aosp_fugu-userdebug
9.mini_emulator_arm64-userdebug
10. m_e_arm-userdebug
11. m_e_mips64-eng
12. m_e_mips-userdebug
13.mini_emulator_x86_64-userdebug
14.mini_emulator_x86-userdebug
15. aosp_dragon-userdebug
16. aosp_dragon-eng
17.aosp_flounder-userdebug
18. aosp_angler-userdebug
19.aosp_bullhead-userdebug
20. hikey-userdebug
21. aosp_shamu-userdebug
22.full_rlk6737m_35g_n-eng
23.full_rlk6737m_35g_n-userdebug
24. full_rlk6737m_35g_n-user
25.full_rlk6737m_35_n-eng
26.full_rlk6737m_35_n-userdebug
27.full_rlk6737m_35_n-user
28. full_rlk6737m_65_n-eng
29. full_rlk6737m_65_n-user
30.full_rlk6737m_65_n-userdebug
31.full_rlk6737t_35g_n-eng
32.full_rlk6737t_35g_n-userdebug
33.full_rlk6737t_35g_n-user
34.full_rlk6737t_35_n-eng
35.full_rlk6737t_35_n-userdebug
36.full_rlk6737t_35_n-user
37.full_rlk6737t_65_n-eng
38. full_rlk6737t_65_n-user
39.full_rlk6737t_65_n-userdebug
40.dax1_grouper_sw-userdebug
41.dax1_hammerhead_hw-userdebug
42.dax1_hammerhead_sw-userdebug
43.dax1_manta_sw-userdebug
上面的這些選項對應每一個文件夾:
./vendor/dolby/device/dax1_manta_sw/vendorsetup.sh
./vendor/dolby/device/dax1_hammerhead_hw/vendorsetup.sh
./vendor/dolby/device/dax1_grouper_sw/vendorsetup.sh
./vendor/dolby/device/dax1_hammerhead_sw/vendorsetup.sh
./device/moto/shamu/vendorsetup.sh
./device/htc/flounder/vendorsetup.sh
./device/google/dragon/vendorsetup.sh
./device/huawei/angler/vendorsetup.sh
./device/lge/bullhead/vendorsetup.sh
./device/linaro/hikey/vendorsetup.sh
./device/generic/mini-emulator-x86/vendorsetup.sh
./device/generic/mini-emulator-mips64/vendorsetup.sh
./device/generic/mini-emulator-mips/vendorsetup.sh
./device/generic/mini-emulator-arm64/vendorsetup.sh
./device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
./device/generic/mini-emulator-x86_64/vendorsetup.sh
./device/asus/fugu/vendorsetup.sh
./device/reallytek/rlk6737t_35g_n/vendorsetup.sh
./device/reallytek/rlk6737t_35_n/vendorsetup.sh
./device/reallytek/rlk6737t_65_n/vendorsetup.sh
./device/reallytek/rlk6737m_35_n/vendorsetup.sh
./device/reallytek/rlk6737m_65_n/vendorsetup.sh
./device/reallytek/rlk6737m_35g_n/vendorsetup.sh
例如:cxair_ABOM_user\device\reallytek\rlk6737m_65_n\vendorsetup.sh內容:
add_lunch_combofull_rlk6737m_65_n-eng
add_lunch_combofull_rlk6737m_65_n-user
add_lunch_combofull_rlk6737m_65_n-userdebug
4、最後執行編譯Android系統de命令$make -j2
在當前目錄執行編譯,–j2表示2個線程同時編譯(僅多核CPU),它會執行一系列.mk,會生成很多鏡像文件,如boot.img、ramdisk.img、system.img、system.img、recovery.img。
比較:
執行命令source rlk_setenv.shcxlite_h3713_a1 user就會把三個腳本文件執行一次(器實質就是同時按順序執行完上面的前三步)
二、Android編譯過程中重要的參與文件
編譯過程:make命令-------去讀取main.mk-------包含子目錄makefile
1、幾個重要的makefile
① 、Android.mk:編譯源碼MK文件,每個module和package目錄下有這麼一個文件(要使得某一個目錄下的東西能夠編譯,必修在該目錄下有這個文件),它的內容就是告訴編譯器本層的哪些需要編譯哪些不需要編譯。
② main.mk:定義了編譯全部代碼的依賴關係。---總的.MK,相當於頂層makefile。
③ Config.mk:用於配置編譯系統,決定如何編譯(定義了編譯規則,如何編譯java,如何編譯Mk等等)
④ envsetup.mk:定義了編譯環境配置(環境變量的值)
⑤ product_config.mk:讀取AndroidProducts.mk生成TARGET_DEVICE變量,這一項已經不存在了
⑥ AndroidProducts.mk:定義某廠商所有產品文件列表
⑦、BoardConfig.mk:定義開發板軟件相關配置項,將來影響系統條件編譯,對具體硬件的說明
2、下面介紹一些重要的編譯文件的詳細解析:
在Android源碼目錄結構中,device目錄很重要,它是定製廠商的。其目錄架構一般爲:device/廠商目錄(mediatek)/產品目錄(mt6735)/設備相關代碼
① 、/device/reallytek/rlk6737m_65_n/AndroidProducts.mk:裏面定義了安卓產品列表:
PRODUCT_MAKEFILES:= $(LOCAL_DIR)/full_rlk6737m_65_n.mk //就這一句話,可以繼續增加,如:
PRODUCT_MAKEFILES:= \
$(LOCAL_DIR)/full_rlk6737m_65_n.mk\
$(LOCAL_DIR)/jianmin.niu_arm11.mk\
…………….
②、device\mediatek\mt6735\device.mk和device\reallytek\rlk6737m_65_n\evice.mk文件
DEVICE_PACKAGE_OVERLAYS +=用自己的APK軟件去覆蓋默認的,企業自己寫的一些特殊的東西,如下例子:
DEVICE_PACKAGE_OVERLAYS +=device/mediatek/common/overlay/slim_rom
DEVICE_PACKAGE_OVERLAYS +=device/mediatek/common/overlay/slim_ram
DEVICE_PACKAGE_OVERLAYS +=device/mediatek/common/overlay/qHD
PRODUCT_PACKAGES += 系統預裝的軟件,在Android源碼中packages目錄下具體實現它們。如下例子:
PRODUCT_PACKAGES +=DangerDash
PRODUCT_PACKAGES += Weather_tecno
PRODUCT_PACKAGES += NoteBookTecno
PRODUCT_PACKAGES += fingerprintd
PRODUCT_COPY_FILES += 拷貝文件,把和產品特性相關的文件拷貝到相應目錄,供系統啓動時使用。如下例子:【格式爲:PRODUCT_COPY_FILES +=原路徑:目標路徑】
PRODUCT_COPY_FILES +=device/reallytek/rlk6737m_65_n/ueventd.mt6735.rc:root/ueventd.mt6735.rc
PRODUCT_COPY_FILES +=frameworks/native/data/etc/android.hardware.sensor.light.xml:system/etc/permissions/android.hardware.sensor.light.xml (.xml是安卓裏的一些佈局,軟件信息相關的東西)
PRODUCT_PROPERTY_OVERRIDES +=可以定製一些東西。如下例子:
PRODUCT_PROPERTY_OVERRIDES += ro.view.dropframe=false //應用使用的一些限制
PRODUCT_PROPERTY_OVERRIDES +=persist.sys.view.gpower=true //應用使用的一些限制
、、、、、、、、、、、、、、、、
PRODUCT_PROPERTY_OVERRIDES +=\
……/上海
……country=CN //國家簡寫
Language=zh //中文簡寫
③、Android.mk在Android的源碼目錄下去添加一個應用程序,在packages\apps下面有很多,可以仿照。
內部相關代碼解釋:
LOCAL_PATH:= $(call my-dir)---- 定義了一個LOCAL_PATH變量;$表示取了一個命令執行的結果(在這裏獲得了call命令執行的結果);call表示調用某一個命令,這裏是調用my-dir命令;my-dir是安卓系統在shell中寫的一個命令(得到當前目錄路徑)
include $(CLEAR_VARS)-----把以前定義的變量的值全部清除掉
LOCAL_MODULE_TAGS := optional -------表示工程編譯需要的一個文件,也可以賦值爲eng等,eng表示工程機裏的東西。
LOCAL_MODULE := bluetooth.mapsapi------目標文件,致命要編譯出來的模塊的名字,它可以是一個共享庫或APP的一個名字,若爲共享庫則改爲:LOCAL_MODULE := libbluetooth.so
LOCAL_SRC_FILES := \
$(call all-java-files-under, lib/mapapi)
或者:LOCAL_MODULE :=libLegacy------指定編譯的源文件
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime\
libnativehelper\------- //編譯時需要鏈接的其它共享庫
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE)-------//指定一個頭文件路徑,JNI_H_INCLUDE爲java本地接口,包含JNI的一些頭文件
LOCAL_PRELINK_MODULE := false //預鏈接沒有
include $(BUILD_SHARED_LIBRARY) //表示編譯成共享庫,若爲include$(BUILD_PACKAGE)表示編譯成App應用文件,也可以編譯成可執行文件
④、初始化腳本,分爲安卓默認的初始化腳本init.rc和廠商自定義的初始化腳本init.**.rc兩種
system\core\init\ readme.txt就是對初始化腳本init.rc的解析。
在init文件中包含四個類型Actions CommandsServices Options
它們的關係我用一句話來表示:
在哪些Actions條件執行之後(on ...),將會執行哪些commands;要去啓動哪一個特定的服務Services,在啓動這個services時我們應該添加哪些選項Options。
詳細說明:
system\core\init:
} init進程,它是一個由內核啓動的用戶級進程。內核自行啓動(已經被載入內存,開始運行,並已初始化所有的設備驅動程序和數據結構等)之後,就通過啓動一個用戶級程序init的方式,完成引導進程。init始終是第一個進程.
} Init進程一起來就根據init.rc和init.xxx.rc腳本文件建立了幾個基本的服務:
} servicemanamger
} zygote
} …
} 最後Init並不退出,而是擔當起service的功能,用來監聽sigal,keychod和property。
} 官方說明:system/core/init/readme.txt
} 包含四個類型的聲明:
} Actions
} Commands
} Services
} Options.
} 特點:
} 所有這些都是以行爲單位的,各種記號由空格來隔開。
} 行末的反斜槓用於折行,註釋行以井號(#)開頭(允許以空格開頭)。
} Actions和Services聲明一個新的分組Section。所有的命令或選項都屬於最近聲明的分組。位於第一個分組之前的命令或選項將會被忽略
} Actions和Services有唯一的名字。如果有重名的情況,第二個申明的將會被作爲錯誤忽略。
} Actions
} Actions其實就是一序列的Commands(命令)。Actions都有一個trigger(觸發器),它被用於決定action的執行時間。當一個符合action觸發條件的事件發生時,action會被加入到執行隊列的末尾,除非它已經在隊列裏了。
} 隊列中的每一個action都被依次提取出,而這個action中的每個command(命令)都將被依次執行。
Actions的形式如下:
on <trigger/name> 在一個觸發條件成立的條件下,下面的命令將一一被執行
<command1>
<command2>
<command3>
} 當trigger被觸發時,command1,command2,command3,會依次執行,直到下一個Action或下一個Service。
簡單來說,Actions就是Android在啓動時定義的一個啓動腳本,當條件滿足時,會執行該腳本,腳本里都是一些命令commands,不同的腳本用on來區分。
} 常用的Commands
} exec <path> [ <argument> ]* 執行
} export <name> <value> 輸出,例如導出環境變量
} ifup <interface> 啓動網卡
} hostname <name> 設置主機名
} chmod <octal-mode> <path> 修改文件屬性,設置權限
} chown <owner> <group> <path> 修改文件目錄屬性,改變所有者
} class_start <serviceclass>class 服務器可以歸類,加載類時是靠它啓動的
} class_stop <serviceclass> class_start 和class_stop是Android特有的
} insmod <path> 加載模塊
} mkdir <path> [mode] [owner] [group]
} mount <type> <device> <dir> [ <mountoption>]*掛在文件系統
} setprop <name> <value> 設置一個屬性的值,即鍵值對
} start/stop <service> 啓動/停止具體的一個服務
} write <path> <string> [ <string> ]*
} Services(服務)是一個程序,它在初始化時啓動,並在退出時可選擇讓其重啓。Services(服務)的形式如下:
service <name><pathname> [ <argument> ]*
<option>
<option>
name:服務名
pathname:當前服務對應的程序位置
option:當前服務設置的選項
Options
Options(選項)是一個Services(服務)的修正者。他們影響Services(服務)在何時,並以何種方式運行。
critical
disabled
setenv <name><value>
socket <name><type> <perm> [ <user> [ <group> ] ]
class <name>