android系统源码的环境下用make来编译,Android源码编译系统入门

做过 Android 平台开发的朋友对make,mm或make clean命令应该很熟悉,但也许大家只是熟知这些命令的作用却不知道这些命令底下有些什么原理?那么今天我就带着大家推开Android编译系统的大门,探索一下这片未知的恐怖之森(问啥要用恐怖之森后面大家就知道了)。

Makefile入门

在讲解Android编译系统之前首先来了解一下什么是Makefile:

简单的说,Makefile提供了一种机制,让使用者可以有效的组织工作。

注意这里用的是“工作”而非“编译”,这是因为Makefile并不是用来完成编译工作的,它只是一种规则的执行者,而使用者用它来执行什么规则没有任何限制。如既可以用它来编译系统,也能用它备份文档或只是打印log。

既然它是用来执行规则的,那么我们就来看看Makefile的规则。

TARGET:PREREQUISITES

COMMANDS

注意:COMMANDS前面必须有一个TAB制表符

在 Makefile 的规则中TARGET是需要生成的目标文件,PREREQUISITES是目标的先决条件,也是另一个规则中的target。COMMANDS是生成目标文件的命令,当 prerequisites 中的任何一个文件比 target 文件要新的时候就会触发 commands。commands 的具体内容取决于使用者的需求,如调用 gcc 编译器。

下面我们用一个简单的例子说明一下Makefile规则的用法。

涉及到的文件如下:

文件名

描述

mian.c

主函数所在文件

test.h

提供一个测试函数getNumber的声明

test.c

提供getNumber的函数实现,用于返回一个值

Makefile

我们的主角,用于编译整个例子

文件内容如下:

(1)test.h对getNumber进行声明。

int getNumber();

(2)test.c实现getNumber函数

#include "test.h"

int getNumber()

{

return 2333;

}

(3)main.c打印getNumber的返回值

#include

#include "test.h"

int main()

{![这里写图片描述](https://images.xiaozhuanlan.com/photo/2019/f0432963128c61125fd09b4ec93d6f38.)

printf("Hello,getNumber=%d\n",getNumber());

return 0;

}

(4)Makefile文件,用于组织这个小例子的编译工作

MakefileTest : main.o test.o

gcc -o MakefileTest main.o test.o

main.o : main.c

gcc -c main.c

test.o : test.c

gcc -c test.c

对上面这段代码简单解释一下,MakefileTest为TAEGET即目标产物,main.o和test.o是MakefileTest的先决条件。gcc -o MakefileTest main.o test.o则是MakefileTest对应的COMMANDS,这条命令使用gcc命令将main.o和test.o编译成MakefileTest可执行文件。

最后通过使用make命令就会在当前目录生成一个MakefileTest可执行文件,运行结果如下:

e1f5046f43a4de864a28f64a4295fa05.png

这里写图片描述

上面这个是一个非常简单的Makefile的示例,但“麻雀虽小,五脏俱全”,它清晰的展示了一个Makefile的编写过程。另外Make工具本身是非常强大的,它有很多隐含的规则来帮助开发者快速搭建复杂的编译体系。如利用它的自动推导功能可以简化对象间的依赖关系,还可以加入变量来减少重复输入。

上面的Makefile还可以写成这样:

OBJECT = main.o test.o

MakefileTest : $(OBJECT)

gcc -o MakefileTest $(OBJECT)

关于Makefile的更多用法可以查看how to write makefile。希望大家多了解一下makefile的用法,这有助于理解Android的编译系统。

Android编译系统入门

像我这样从事过Android平台开发的开发人员对make,mm等命令应该很熟悉,同样也知道Android.mk文件,用它结合mm命令来编译单个的Android模块。如果这就是你对Android编译系统的全部了解,那只能说你是一个普通的Android平台开发人员。想要在Android平台开发界混的话,学习和掌握Android编译系统的原理将是必不可少的。前面说道Android编译系统是一个恐怖之森,应为它真好符合恐怖之森的两个特点,让人望而却步和容易迷失方向。这么说一点也不过分,在学习Android编译系统的时候,如果缺少很明确的指引很容易迷失方向,或者让你根本就不敢去试着闯一闯。

makefile依赖树的概念

不难发现在makefile中的target的依赖关系实际上可以组成一棵树,我将其称为makefile依赖树,仍然以上一个MakefileTest为例,给出它的makefile依赖树:

b07f563d0e1e08728aefe6baf50080fb.png

这里写图片描述

只要照个这个树形结构顺藤摸瓜,那么分析Android编译系统也就变得有目的性了。

恐怖之森里的树

有了上面的知识做铺垫,我们也就可以大胆的往恐怖之森闯了。

04bfa44a58e2e3c24fe015e27be7c5d4.png

这里写图片描述

根节点

既然是树,肯定有它的根节点,我们就来找一找Android编译系统的根节点。

如果make命令没有指定文件的话默认会在当前目录寻找Makefile这个文件,所以先看看Android源码根目录的那个Makefile文件:

### DO NOT EDIT THIS FILE ###

include build/core/main.mk

### DO NOT EDIT THIS FILE ###

原来这里只是指路牌,真正的文件是build/core/main.mk。

在 Makefile 使用 include 关键字可以把别的 Makefile 包含进来,这很像 C 语言的

\#include,被包含的文件会原模原样的放在当前文件的包含位置。

打开main.mk发现它有上千行代码,并且在其中又包含了很多其他makefile脚本,所以整个文件的内部结构让人感觉杂乱无章,无法入手。这时候我们就不能一行行的去读这个文件,这样很可能会事倍功半。我们需要找出它其中依赖树的根节点,以此为突破口。但往往大型的工程中不止一棵依赖树,这时候如果没有指定依赖树的话make命令会以从上至下第一个target作为默认依赖树的根节点。其实大家非常熟悉的make clean中的clean就是这些依赖树中的一棵。

.PHONY: clean

clean:

@rm -rf $(OUT_DIR)/*

@echo "Entire build directory removed."

clean是一个伪目标,伪目标一般没有目标文件。且使用.PHONY显示声明。

从上面clean的COMMANDS知道它的作用是删除\$(OUT_DIR)下的所有目录和文件,而\$(OUT_DIR)就是out目录。

OK,那么我们就跟着上面的思路找寻那棵默认依赖树,对照main.mk代码很快就发现了它的默认依赖树根节点:

# This is the default target. It must be the first declared target.

.PHONY: droid

DEFAULT_GOAL := droid

$(DEFAULT_GOAL):

从注释中可以看出来droid就是我们找的依赖树的根节点,不过这里只是定义了一下,没有给出真正的规则。根据关键字搜索的话会发现main.mk中有几处对droid规则的定义:

ifneq ($(TARGET_BUILD_APPS),)

# If this build is just for apps, only build apps and not the full system by default.

...

.PHONY: apps_only

apps_only: $(unbundled_build_modules)

droid: apps_only

...

else # TARGET_BUILD_APPS

...

# Building a full system-- the default is to build droidcore

droid: droidcore dist_files

上面会根据TARGET_BUILD_APPS变量的值是否为空来走不同的分支,如果不为空,则droid的先决条件是apps_only,如果为空droid的先决条件是droidcore和dist_files,我们使用默认的make命令编译android系统的话这里的TARGET_BUILD_APPS的值为空,所以走下面这个分支。TARGET_BUILD_APPS何时不为空,感兴趣的朋友可以自行分析一下。

main.mk总览

在分析droidcore和dist_files两个先决条件之前先来看一下main.mk的一个文件结构,它除了构建droid等依赖树外,有一大半内容是在做一下这些事情。

对编译环境的检测

比如java环境是否符合要求,当前是linux系统还是mac系统。如果这些检测中有任何一项不符合要求,则会终止编译。

进行一些必要的前期处理

比如整个项目工程是否要进行清理操作,部分工具的安装等。

引用其他Makefile文件

比如引用config.mk,cleanbuild.mk等。

设置全局变量

各种函数的实现

Android编译系统中定义了很多实用的函数,它们提供了整个编译系统的统一解决方案。比如my-dir这个在Android.mk中出镜率最高的函数,就是用来获得当前的路径。

下表是对Android编译系统中涉及的主要Makefile文件的解释,可供参考。

Name

Description

main.mk

整个编译系统的主导文件

config.mk

产品配置的主导文件

base_rules.mk

编译系统需要遵循的基础规则定义

build_id.mk

版本id号的定义

cleanbuild.mk

clean操作的定义

clear_vars.mk

LOCAL开头的相关系统变量

definitions.mk

提供了大量实用的函数定义

envsetup.mk

配置编译时的环境变量

executable.mk

负责BUILD_EXECUTABLE的具体实现

host_executable.mk

负责BUILD_HOST_EXECUTABLE的具体实现

host_static_library.mk

负责BUILD_HOST_STATIC_LIBRARY的具体实现,其他类型的BUILD_XX这里不再赘述

product_config.mk

产品级别的配置,属于config的一部分

version_defaults.mk

负责生成版本信息,如版本号BUILD_NUMBER := eng.$(USER).$(shell date +%Y%m%d.%H%M%S)

droidcore节点

droid规则的定义如下:

# Build files and then package it into the rom formats

.PHONY: droidcore

droidcore: files \

systemimage \

$(INSTALLED_BOOTIMAGE_TARGET) \

$(INSTALLED_RECOVERYIMAGE_TARGET) \

$(INSTALLED_USERDATAIMAGE_TARGET) \

$(INSTALLED_CACHEIMAGE_TARGET) \

$(INSTALLED_VENDORIMAGE_TARGET) \

$(INSTALLED_FILES_FILE)

可以看出来droidcore有如下几个先决条件,

Prerequisite

Description

files

代表其所依赖的先决条件的集合,没有实际意义

systemimage

将生成system.img

INSTALLED_BOOTIMAGE_TARGET

将生成boot.img

INSTALLED_RECOVERYIMAGE_TARGET

将生成recovery.img

INSTALLED_USERDATAIMAGE_TARGET

将生成userdata.img

INSTALLED_CACHEIMAGE_TARGET

将生成cache.img

INSTALLED_VENDORIMAGE_TARGET

将生成vendor.img

INSTALLED_FILES_FILE

将生成install-files.txt,用于记录当前系统中预装的程序、库等模块

这几个先决条件的生成原理类似,这里挑几个做重点分析。

1.files

定义如下:

```mk

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/573525.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(mac)阿里云ECS服务器配置过程

-----首先本人是半只脚入门的iOS开发者,弄这个只是单纯想多学点东西。 -----阿里云服务器的配置选择:既然是学习用的,最最基础的配置就行了。1M带宽,1核1G...这就不详述了。没啥可选的,(其中有个创建实例&a…

android 换到iphone,从安卓换到苹果到底是什么感受?最后一个让我彻底放弃了iPhone!...

原标题:从安卓换到苹果到底是什么感受?最后一个让我彻底放弃了iPhone!iPhone X是近几年来苹果最具创新力的iPhone,然而高昂的售价让很多消费者望而却步。随着今年苹果秋季新品发布会的临近,苹果即将发布价格更低廉&…

php 5.5 xhprof for windows

今天看到一个好的性能优软件xhprof(有facebook开发的类库)在国内找了很多网站都没有找到相关php5.5的扩展,只好FQ还是外面的世界精彩一下就找到了link (http://windows.php.net/downloads/pecl/releases/xhprof/0.10.6/)如果不能FQ的小伙伴可以到我的百度…

鸿蒙分布式体验,一张图看懂鸿蒙OS 2.0 分布式能力升级构筑全场景体验

原标题:一张图看懂鸿蒙OS 2.0 分布式能力升级构筑全场景体验【手机中国新闻】9月10日下午,华为召开HDC2020大会,全新的HarmonyOS 2.0正式发布。新系统的分布式能力全面升级,同时还为开发者提供了完整分布式设备与应用开发生态&…

如何在android模拟器中安装apk

1. 启动android模拟器 2. 将要安装的apk,拷贝在与adb.exe同文件夹中。我的路径:D:\android\android-sdk-windows\platform-tools 3. 在cmd中,进入上目录,输入adb install xxx.apk,最后可看见success 4. 回到android模拟…

传感器系列之4.3流量传感器

4.3 流量数据采集实验 一、实验目的掌握水流量计的结构与工作原理掌握霍尔传感器的使用二、实验材料具有USB 串口通讯的PC 机1 台ADS1.2 集成开发软件1 套J-Link-ARM 仿真器及软件1 套NXP LPC2378 实验节点板1 个LCD 显示实验板1 个BMP085数字气压传感器模块1个三、实验原理流量…

鸿蒙日程管理若离,2020华为HDC日程确定,鸿蒙、HMS以及EMUI 11成最关注点

HDC:华为开发者大会,目前已经确定将在9月10日正式开幕。日前华为已经在其官网公布了HDC的日程,从现在的消息看华为开发者大会有三大点最受业内关注。鸿蒙操作系统鸿蒙操作系统应该是大家关注最大的话题,不过此前余承东已经正式表示…

语言课设医院诊疗系统_江苏孤独症孩子有哪些典型特征?上海六一儿童医院

孤独症孩子有哪些典型特征当家长发现孩子不爱说话,不理人的时候,有时怀疑孩子是不是患了孤独症。对于孤独症的孩子和正常的孩子还是不一样的。那么,孤独症孩子有哪些典型的特征呢?孤独症孩子的典型特征主要有以下几点:特征一&…

android 6.0适应的机型,提升用户体验 可升Android 6.0机型盘点

原标题:提升用户体验 可升Android 6.0机型盘点【手机中国 导购】2009年Android系统正式发布,由此加速手机走向智能化进度。如今,随着Android系统日渐成熟,众多手机厂商都在此基础上研发出符合自家特色的系统版本,并且流…

antd 能自适应吗_一种能自适应识别母线运行方式的备自投装置应用探讨

中山供电局的研究人员江清楷,在2019年第8期《电气技术》杂志上撰文,介绍了一种220kV备自投装置,列出了母联备自投和线路备自投的充电条件及起动条件。以220kV逸仙变电站为例,指出该备自投装置在双母线单分段接线的变电站应用中存在…

html页面tableview,用JS写的一个TableView控件代码

请看看编码是否规范,使用是否方便HTML:代码编号姓名{value}{value}编号名称{value}{value}Javascript:代码//class TableView {//构造函数function TableView(ID){var htmlTable document.getElementById(ID);this.container htmlTable.getElementsByTagName(&quo…

HTML中空格代码为,html空格 html 空格代码

html 空格和html空格代码篇在HTML网页排版机关时,一个翰墨与翰墨间空格可使用一个使用空格键直接空一格便可。然则要实现多个空格间隔,打再多空格键空格,始终至多展现一个空格地位。那末如何才智html构造中笔墨间完成多个空格成果&#xff1f…

centos 下载文件很慢_CentOS镜像下载

官网下载链接:http://isoredirect.centos.org/centos/7/isos/x86_64/step1: 进入下载页,选择阿里云站点进行下载Actual Country 国内资源 Nearby Countries 周边国家资源阿里云站点:http://mirrors.aliyun.com/centos/7/isos/x86_64/每个链接…

移动端html搜索怎么写,移动端实现搜索功能

在移动端需要实现如下搜索相关的功能点击搜索按钮实现搜索搜索按钮这里首先就会遇到怎么弹出搜索按钮。在html5 中 input 已经支持search 类型,iso/安卓所幸也都有自己的相应实现。只需要按照移动端的标准来写,那我就会为我们提供我们所需的搜索按钮。按…

计算机裸机与应用程序及用户之间的桥梁是,2016计算机二级《MS Office》单选试题与解析...

2016计算机二级《MS Office》单选试题与解析(1)下列叙述中正确的是A)一个算法的空间复杂度大,则其时间复杂度也必定大B)一个算法的空间复杂度大,则其时间复杂度必定小C)一个算法的时间复杂度大,则其空间复杂度必定小D)算法的时间复杂度与空间…

10kv线路负载率计算_10kV配电线路保护的整定计算

1、10kV配电线路的特点10kV配电线路结构特点是一致性差,如有的为用户专线,只接带一、二个用户,类似于输电线路;有的呈放射状,几十台甚至上百台变压器T接于同一条线路的各个分支上;有的线路短到几百m&#x…

diamond升级IP,覆盖的时候报错

这几天给客户调试DDR3 SDRAM Controllerd发现个很奇怪的问题。客户之前用的IP是DDR3 SDRAM Controllerd 1.4,客户想升级为DDR3 SDRAM Controllerd 3.0。客户直接双击之前的工程,然后regenerate,发现报错了,如下图。然后我就思考是…

一台微型计算机的处理速度主要取决于,2017年答案计算机等级考试题库「附答案」...

2017年答案计算机等级考试题库「附答案」一、单选题1、世界上首次提出存储程序计算机体系结构的是A 莫奇莱 B 艾仑图灵 C 乔治布尔 D 冯诺依曼2、世界上第一台电子计算机诞生于A 1941年 B 1946年 C 1949年 D 1950年3、世界上第一台电子数字计算机采用的主要逻辑部件是A 电子管 …

html高度随宽度编号,纯css实现容器高度随宽度等比例变化的四种解决方案

使用一个隐藏的图片来实现这个方法是我最推荐的,因为不需要考虑任何兼容性,PC移动完美运行。除了增加了一个dom结构,但是相对与一个页面成百上千的代码来说,不值一提我们知道,div容器如果不给定高度,它的高…

燕山大学计算机学院官网,燕山大学信息科学与工程学院(专业学位)计算机技术保研夏令营...

考研真题资料优惠价原价选择燕山大学信息科学与工程学院(专业学位)计算机技术保研夏令营信息,是考研之前需要获取相应的考研信息,比如考试大纲、招考专业、招考目录等等基本信息,这些内容是进行考研前期工作的必要准备。考生可以从各院校的研…