目录
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>