Android系统移植与调试之------->Android的编译系统简介

简介: 一、Makefile的主要流程 以下主要流程都在build/core/main.mk里安排。 l  初始化相关的参数设置(buildspec.mk、envsetup.

一、Makefile的主要流程

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

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

l  检测编译环境和目标环境

l  决定目标product

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

l  清除输出目录

l  检查版本号

l  读取Board的配置

l  读取所有Module的配置

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

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

http://img154.ph.126.net/5ekAHoRqfPf17ALmDJGDYA==/2269251262242871911.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,而我们针对自己的产品应修改成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




本文转载于:http://blog.csdn.net/yanzheng1113/article/details/6980480


==================================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址http://blog.csdn.net/ouyang_peng

==================================================================================================


相关文章
|
2月前
|
人工智能 搜索推荐 物联网
Android系统版本演进与未来展望####
本文深入探讨了Android操作系统从诞生至今的发展历程,详细阐述了其关键版本迭代带来的创新特性、用户体验提升及对全球移动生态系统的影响。通过对Android历史版本的回顾与分析,本文旨在揭示其成功背后的驱动力,并展望未来Android可能的发展趋势与面临的挑战,为读者呈现一个既全面又具深度的技术视角。 ####
|
4天前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
2月前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
1月前
|
监控 Java Android开发
深入探索Android系统的内存管理机制
本文旨在全面解析Android系统的内存管理机制,包括其工作原理、常见问题及其解决方案。通过对Android内存模型的深入分析,本文将帮助开发者更好地理解内存分配、回收以及优化策略,从而提高应用性能和用户体验。
|
1月前
|
存储 安全 Android开发
探索Android系统的最新安全特性
在数字时代,智能手机已成为我们生活中不可或缺的一部分。随着技术的不断进步,手机操作系统的安全性也越来越受到重视。本文将深入探讨Android系统最新的安全特性,包括其设计理念、实施方式以及对用户的影响。通过分析这些安全措施如何保护用户免受恶意软件和网络攻击的威胁,我们希望为读者提供对Android安全性的全面了解。
|
2月前
|
监控 Java Android开发
深入探讨Android系统的内存管理机制
本文将深入分析Android系统的内存管理机制,包括其内存分配、回收策略以及常见的内存泄漏问题。通过对这些方面的详细讨论,读者可以更好地理解Android系统如何高效地管理内存资源,从而提高应用程序的性能和稳定性。
99 16
|
2月前
|
前端开发 数据处理 Android开发
Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍
本文深入探讨了Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍,以及具体操作步骤、常见问题解决、高级调试技巧、团队协作中的调试应用和未来发展趋势,旨在帮助开发者提高调试效率,提升应用质量。
74 8
|
2月前
|
安全 Android开发 iOS开发
深入探讨Android与iOS系统的差异及未来发展趋势
本文旨在深入分析Android和iOS两大移动操作系统的核心技术差异、用户体验以及各自的市场表现,进一步探讨它们在未来技术革新中可能的发展方向。通过对比两者的开放性、安全性、生态系统等方面,本文揭示了两大系统在移动设备市场中的竞争态势和潜在变革。
|
2月前
|
算法 JavaScript Android开发
|
2月前
|
安全 搜索推荐 程序员
深入探索Android系统的碎片化问题及其解决方案
在移动操作系统的世界中,Android以其开放性和灵活性赢得了广泛的市场份额。然而,这种开放性也带来了一个众所周知的问题——系统碎片化。本文旨在探讨Android系统碎片化的现状、成因以及可能的解决方案,为开发者和用户提供一种全新的视角来理解这一现象。通过分析不同版本的Android系统分布、硬件多样性以及更新机制的影响,我们提出了一系列针对性的策略,旨在减少碎片化带来的影响,提升用户体验。

热门文章

最新文章