Android源码分析(二):mk文件具体的具体的执行流程

简介:

 Android编译系统集中于build/core下,几个很重要的*.mk文件如下:

         main.mk(主控 Makefile)
         base_rules.mk(对一些 Makefile的变量规则化)
         config.mk(关于编译参数、编译命令的一些配置)
         definations.mk(定义了很多编译系统中用到的宏,相当于函数库)
         Makefile(这个 Makefile特指build/core下的Makefile,此文件主要控制生成system.img,ramdisk.img,userdata.img,以及recorvery image,sdk等)
         Binary.mk(控制如何生成目标文件 )
         Clear_vars.mk(清除编译系统中用到的临时变量)
         Combo/linux-arm.mk(控制如何生成 linux-arm二进制文件,包括ARM相关的编译器,编译参数等的设置)
         Copy_headers.mk(将头文件拷贝到指定目录)
         分散于各个目录下的 Android.mk(控制生成局部模块的源码,名称所需头文件路径,依赖库等特殊选项)
         Build/envsetup.mk(编译环境初始化,定义一些实用的 shell函数,方便编译使用)
         以上几个主要的文件,可以按照社会分工打一个比方:
         Main.mk是总统,是老大,承担了很多工作。
         Makefile是副总统,辅佐老大 Main.mk
         Base_rules.mk是交警,让不规则的东西,变得规则。
         Config.mk是省长,规定了各个人民群众该如何行事
         Definations.mk是图书馆管理员
         Binary.mk应该属于村长了,规定每个人该如何行事
         Clear_vars.mk应该属于保洁公司的工人吧
         Combo/linux-arm.mk应该属于社会公民了,他决定自己该如何去做
Main.mk分析
   Main.mk主要包含如下几个部分的内容
      1.    SHELL设置
      2.    编译环境配置
      3.    编译环境检查
      4.    包含必要的宏
      5.    根据 make参数设置编译时的变量
      6.    包含需要编译的 Android.mk
      7.    设置编译系统 Target:prerequisites 控制整个编译流程
       下面对上面几点进行必要解释:
       Main.mk的第一句就根据 ANDROID_BUILD_SHELL 来包裹编译系统用到的Shell,如果我们不想使用bash,而想使用sh,那么就可以在它前面写上ANDROID_BUILD_SHELL := /bin/sh,或者在build/envsetup.sh中添加相关定义。(内容如下图)  
          定义完 SHELL之后,就是对MAKE_VERSION的检查,然后定义了默认的编译目标droid!如果我们敲入 make之后,不加任何参数,默认的目标就是droid。注意虽然后面的include $(BUILD_SYSTEM)/config.mk写在默认目标droid依赖之后,但其和之后的语句都是要执行的,这是Makefile的语法决定的。(内容如下图)  

          后面会include config.mk cleanbuild.mk对编译系统进行必要的配置。后面就是对编译环境的检查,包括是否大小写敏感、路径检查、java版本检查、javac版本检查。Android对编译环境的检查如果符合条件,在下次编译的时候,不会再次进行检查。(内容如下图) 

 

         检查完版本之后,会包含进definitions.mk,如前所述,definitions.mk中定义了很多编译系统中用到的宏,这些宏在编译时需要经常调用,因此在编译的很靠前的阶段,就将之包含了进来。(内容如下图)Definitions.mk中的内容自己有时间在回顾一下,里面定义了很多宏. 

     然后就是针对make时传入的编译类型(eng user userdebug showcommands等)进行编译配置,这些配置会影响到最终编译目标所包括的模块。对于eng user userdebug sdk win_sdk tests等编译目标的区别,可以通过查看main.mk的代码找出其中到底有什么不同。(内容如下图)

 

在编译完整个系统之后,再运行make sdk,就可以进行sdk 的编译了。make sdk 将各种工具和image 打包,供开发和调试使用。 注: Make 命令
       make droid:等同于make 命令。droid 是默认的目标名称。
      make all: make all 将make 所有make droid 会编译的项目。同时,将编译 LOCAL_MODULE_TAGS 定义的不包括android tag 的模块。这将确保所有的在代码树里面同时有Android.mk 文件的模块。
     clean-$(LOCAL_MODULE)和clean-$(LOCAL_PACKAGE_NAME): 删除某个模块的目标文件。例如: clean-libutils 将删除所有的libutils.so 以及和它相关的中间文件;
      clean-Home 将删除Home 应用。
      make clean:删除本次配置所编译输出的结果文件。类似于:rm –rf ./out/ <configuration>
      make clobber:删除所有配置所编译输出的结果文件。类似于:rm –rf ./out/
      make dataclean:make dataclean deletes contents of the data directory inside the
     current combo directory. This is especially useful on the simulator and emulator, where
     the persistent data remains present between builds.
     make showcommands在编译的时候显示脚本的命令而不是显示编译的简报。用于调试脚本。
     make LOCAL_MODULE:编译一个单独得模块(需要有Android.mk 文件存在)。
     make targets:将输出所有拟可以编译的模块名称列表。还有一些命令,从make 文件里面应该可以找到 。)
 
       Ifeq($(SDK_ONLY),true)处,大概 400行上下,这个判断语句一直到这个语句块结束,都是对subdirs变量的设置,subdirs变量决定了哪些子文件夹最终被编译。在后面的subdir_makefiles变量的设置,决定了哪些Android.mk被编译。紧接着include $(subdir_makefiles)就会添加所有这些Android.mk文件的依赖。这其中包含了droid的依赖,后面我们会发现。(内容如下图)
 
  本地模块的 Makefile文件就是我们在Android 里面几乎上随处可见的Android.mk。Android 进行编译的时候会通过下面的函数来遍历所有子目录中的Android.mk,一旦找到就不会再往层子目录继续寻找(所有你的模块定义的顶层Android.mk 必须包含自己定义的子目录中的Android.mk)。subdir_makefiles += \$(shellbuild/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)不同类型的本地模块具有不同的语法,但基本上是相通的,只有个别变量的不同,如何添加模块在前面,如上图就是公司自己添加的模块。
         然后就会根据这些 Makefile,找出所有需要编译的模块(module),以及进行必要的分类(eng_MODULES/debug_MODULES/tests_MODULES等、modules_to_check/modules_to_install等),用以区别对待。紧接着是定义了一系列的隐含目标: prebuilt、all_copied_headers、files、checkbuild、ramdisk、systemtallball、userdataimage、userdatatarball、bootimg、droidcore等。最重要的一点,是会发现droid依赖于droidcore,而droidcore依赖于
droidcore: files \
         systemimage \
         $(INSTALLED_BOOTIMAGE_TARGET) \
         $(INSTALLED_RECOVERYIMAGE_TARGET) \
         $(INSTALLED_USERDATAIMAGE_TARGET) \
         $(INSTALLED_FILES_FILE)
正是这几个依赖项,控制着整个 android的编译。
         当我们敲 Make实际上就等同于我们执行make droid。当Make include所有的文件,完成对所有make我文件的解析以后就会寻找生成droid的规则,依次生成它的依赖,直到所有满足的模块被编译好,然后使用相应的工具打包成相应的img。
config.mk分析
          build/core/config.mk该文件被 main.mk包含。config.mk 文件的主要内容如下:头文件的定义;(各种 include 文件夹的设定)在定义头文件的部分,还include 了pathmap.mk,如下:include $(BUILD_SYSTEM)/pathmap.mk
该文件设置 include 目录和frameworks/base 下子目录等的信息。编译系统内部 mk 文件的定义; <Build system internal files>。(内容如下图)
 
设定通用的名称; <Set common values>
 Include 必要的子配置文件; <Include sub-configuration files>
 buildspec.mk
 envsetup.mk
 BoardConfig.mk
 /combo/select.mk
 /combo/javac.mk
。(内容如下图)  

 

检查 BUILD_ENV_SEQUENCE_NUMBER 版本号;
In order to make easier for people when the build system changes, when it is necessary
to make changes to buildspec.mk or to rerun the environment setup scripts, they contain
a version number in the variable BUILD_ENV_SEQUENCE_NUMBER. If this variable does
not match what the build system expects, it fails printing an error message explaining
what happened. If you make a change that requires an update, you need to update two
places so this message will be printed.
· In config/envsetup.make, increment the
CORRECT_BUILD_ENV_SEQUENCE_NUMBER definition.
· In buildspec.mk.default, update the BUILD_ENV_SEQUENCE_DUMBER definition
to match the one in config/envsetup.make
The scripts automatically get the value from the build system, so they will trigger the
warning as well.。(内容如下图)
       设置常用工具的常量; < Generic tools.>
       设置目标选项; < Set up final options.>
       遍历并设置 SDK 版本;

envsetup.mk分析

       125行又包含了另外一个重要的 mk文件envsetup.mk,我们来看一下。

        上面的代码是指定了目标输出代码的位置和主机输出代码的位置,重要的几个如下:PRODUCT_OUT = 这个的结果要根据 product_config.mk文件内容来决定。envsetup.mk文件主要包含了 product_config.mk文件,然后指定了编译时要输出的所有文件的OUT目录。

        envsetup.mk又包含了product_config.mk文件

 

build/core/product_config.mk又包含了product.mk文件。
          因此 android编译系统通过各种依赖关系、确保某个模块的修改引起相依赖的文件的重新编译链接,甚至还包括目标文件系统的生成,配置文件的生成等。

 










本文转自 646676684 51CTO博客,原文链接:http://blog.51cto.com/2402766/1077778,如需转载请自行联系原作者
目录
相关文章
|
6月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
177 2
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
6月前
|
Java Android开发
Android studio中build.gradle文件简单介绍
本文解析了Android项目中build.gradle文件的作用,包括jcenter仓库配置、模块类型定义、包名设置及依赖管理,涵盖本地、库和远程依赖的区别。
615 19
|
9月前
|
移动开发 安全 Java
Android历史版本与APK文件结构
通过以上内容,您可以全面了解Android的历史版本及其主要特性,同时掌握APK文件的结构和各部分的作用。这些知识对于理解Android应用的开发和发布过程非常重要,也有助于在实际开发中进行高效的应用管理和优化。希望这些内容对您的学习和工作有所帮助。
961 83
|
6月前
|
存储 XML Java
Android 文件数据储存之内部储存 + 外部储存
简介:本文详细介绍了Android内部存储与外部存储的使用方法及核心原理。内部存储位于手机内存中,默认私有,适合存储SharedPreferences、SQLite数据库等重要数据,应用卸载后数据会被清除。外部存储包括公共文件和私有文件,支持SD卡或内部不可移除存储,需申请权限访问。文章通过代码示例展示了如何保存、读取、追加、删除文件以及将图片保存到系统相册的操作,帮助开发者理解存储机制并实现相关功能。
1763 2
|
8月前
|
安全 算法 小程序
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
551 28
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
|
7月前
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码android版环境配置流程及功能明细
部署需基于 CentOS 7.9 系统,硬盘不低于 40G,使用宝塔面板安装环境,包括 PHP 7.3(含 Redis、Fileinfo 扩展)、Nginx、MySQL 5.6、Redis 和最新 Composer。Swoole 扩展需按步骤配置。2021.08.05 后部署需将站点目录设为 public 并用 ThinkPHP 伪静态。开发环境建议 Windows 操作系统与最新 Android Studio,基础配置涉及 APP 名称修改、接口域名更换、包名调整及第三方登录分享(如 QQ、微信)的配置,同时需完成阿里云与腾讯云相关设置。
|
8月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
9月前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
308 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
API Android开发
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 )(一)
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 )(一)
251 0
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 )(一)
|
Android开发
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(四)
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(四)
278 0