打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Android 系统编译

Android 系统编译

文章分类:移动开发

最近研究了下Android 的编译系统,下面结合编译我们自己的产品 mobot 来对整个编译系统进行必要的介绍,方便大家今后对默认编译的修改。

 

先列出几个觉得重要的Make 文件:

build/buildspec.mk

build/envsetup.sh

build/core/main.mk

build/core/envsetup.mk

build/config.mk

 

总的来说,Android 以模块 (module/package) 的形式来组织各个系统的部件,每个模块 (module/package) 的目录下都会有一个 Android.mk 。所谓 module 就是指系统的 Native Code ,而相对于 Java 写的 Android application 称为 package

 

 

 

Makefile的主要流程 1

初始化参数设置 2

读取Product 的设定 3

读取BoardConfig 4

读取所有Module 4

产生相应的Rules ,生成 image 5

具体make 操作: 6

完整编译 6

模块编译 6

单独编译image 文件 7

一些疑问和解答: 7

 

 

 

Makefile的主要流程

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

初始化相关的参数设置(buildspec.mk envsetup.mk config.mk)

检测编译环境和目标环境

决定目标product

读取product 的配置信息及目标平台信息

清除输出目录

检查版本号

读取Board 的配置

读取所有Module 的配置

根据配置产生必要的规则(build/core/Makefile)

生成image

初始化参数设置

main.mk 里,简单设置几个主要编译路径的变量后,来到config.mk

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

其中设置了源文件的一系列路径,包括头文件、库文件、服务、API 已经编译工具的路径。(前 36 行)

40 行开始,定义一些编译模块的生成规则:

 

这里面除了第一个CLEAR_VARS 外,其他都对应的一种模块的生成规则,每一个 module 都会来 include 其中某个来生成目标模块。

例如:

Camera模块的 makefile 里( Android.mk )就包含了其中的一种生成规则BUILD_PACKAGE

 

也就是Camera 会按照 package.mk 里的生成规则去生成目标模块。

回到config.mk ,接着会尝试读取 buildspec.mk 的设置:

 

如同注释所说,会尝试查找 buildspec.mk ,如果文件不存在会自动使用环境变量的设置,如果仍然未定义,会按arm 默认的设置去 build

这里的buildspec.mk 可以自己创建,也可以将原先 build/ 下的 buildspec.mk.default 直接命名为 buildspec.mk 并移到根目录。

 

 

实际上,buildspec.mk 配置都被屏蔽了,我们可以根据需要直接打开和修改一些变量。在这里我们可以加入自己的目标产品信息:

ifndef TARGET_PRODUCT

TARGET_PRODUCT:=mobot

endif

以及输出目录设置:

OUT_DIR:=$(TOPDIR)mobot

读取Product 的设定

回到config.mk ,接着进行全局变量设置,进入 envsetup.mk

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

里面的大部分函数都在build/envsetup.sh 中定义。

首先,设置版本信息,(11 ) build/core/version_defaults.mk 中具体定义平台版本、 SDK 版本、 Product 版本,我们可以将 BUILD_NUMBER 作为我们产品 mobot version 信息,当然,也可以自定义一个版本变量。

回到envsetup.mk ,接着设置默认目标产品 (generic) ,这里由于我们在 buildspec.mk 里设置过 TARGET_PRODUCT ,事实上这个变量值为mobot

然后读取product 的设置 (41 ) ,具体实现在 build/core/ product_config.mk 中,进而进入product.mk ,从 build/target/product/ AndroidProducts.mk 中读出PRODUCT_MAKEFILES ,这些 makefile 各自独立定义 product ,而我们的产品 mobot 也应添加一个 makefile 文件 mobot.mk 。在 mobot.mk 中我们可以加入所需编译的 PRODUCT_PACKAGES

下面为HOST 配置信息及输出目录,最后打印相关信息:

 

读取BoardConfig

接着回到config.mk (114 ) 这里会搜索所有的 BoardConfig.mk ,主要有以下两个地方:

$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk 

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

这里的TARGET_DEVICE 就是 mobot ,就是说为了定义我们自己的产品 mobot ,我们要在 build/target/board 下添加一个自己的目录 mobot 用来加载自己的 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 $@

M=$(findmakefile), 最终实现在:

 

回到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 等。具体对应的 rules 可以参考下图:

http://p.blog.csdn.net/images/p_blog_csdn_net/yili_xie/EntryImages/20091214/make%20goals.png

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 ,而我们针对自己的产品应修改成 mobot

           具体在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

一些疑问和解答:

1)  什么是recovery.img

顾名思义,recovery.img 是为了恢复系统的,相对于普通的 boot.img recovery.img 多了一些图片文件 ( 恢复时界面的背景 ) /sbin/recovery/ 目录 ( 跟恢复有关的二进制文件 ) ,一些初始化文件也不相同 (init.rc init.goldfish.rc default.prop)

这就是为什么启动恢复模式时会进入类似文本界面而不是图形界面。

recovery.img 文件复制到 SD 卡中,进入 shell 下输入:

mount -a

flash_image recovery /sdcard/recovery.img

若提示“no space on device ”,可用 fastboot 模式刷

fastboot erase recovery

fastboot flash recovery recovery.img

在关机状态下按home+power 键进入 recovery 模式,根据选项选择需要的操作。

 

2)  make sdk make droid 编译有什么不同?

make sdk

其实,执行make sdk ,编译后会在目录 out/host/linux-x86 里生成 sdk 目录,这个 sdk 和官方下载的 sdk 包是一样的,可以直接使用。

make droid

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Android系统编译过程分析
Android编译系统
Android makefile
Android编译系统环境初始化过程分析
android移植简述
Ubuntu10.04上编译Android源码(Build Android source in Ubuntu10.04 Platform)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服