AOSP编译系统演进:从Make到Ninja的技术升级(Android13)

AOSP编译系统演进:从Make到Ninja的技术升级(Android13)

引言

在Android 7.0之前,Android的编译系统主要使用GNU Make和Android.mk进行构建规则的描述和执行。然而,随着项目规模的扩大,Makefile组织方式导致了编译时间的增长等问题。

为了解决这些问题,从Android 7.0开始,Google引入了Soong构建系统,Soong 构建系统正好提供了 Android build 所需的灵活性。

Soong 构建系统是在 Android 7.0 (Nougat) 中引入的,旨在取代 Make。它利用 Kati GNU Make 克隆工具和 Ninja 构建系统组件来加速 Android 的构建。

ninja作为替代GNU Make的工具,并引入了kati工具来将Android.mk转换为ninja构建规则文件。随后,在Android 8.0中,Google进一步引入了Android.bp文件,用作替代Android.mk的纯配置文件。

Android.bp文件本质上是一个基于json格式的配置文件,不包含控制流程等复杂语法。它通过Blueprint+soong的转换过程生成相应的ninja构建规则文件(build.ninja),然后使用ninja进行实际的构建工作。

通过这一系列改进,Google的目标是加速Android项目的构建过程,提高整体效率。Soong构建系统由Kati GNU Make克隆工具和Ninja构建系统组件组成,这进一步优化了Android项目的构建流程。

注意,最新消息, Google计划未来几年将AOSP编译系统全面向bazel迁移,此迁移目前处于早期阶段,但您可以对当前的 build 文件做出一些更改,以便开始针对 Bazel 做好准备。迁移完成后,Bazel 将取代 AOSP 中的所有现有构建系统和 build 配置系统(Make、Kati、Soong、基于 Make 的产品配置)。

https://source.android.google.cn/docs/setup/build/bazel/introduction?hl=zh-cn

构建流程

编译系统构成

Android的编译目录位于/build中。在Android 13源码中的build目录中,有几个重要的文件夹:

  1. blueprint:用于处理Android.bp文件,生成*.ninja文件,以供ninja处理。
  2. kati:用于处理Android.mk文件,生成*.ninja文件,同样供ninja处理。
  3. make:该文件夹包含原始的make流程,例如envsetup.sh等。
  4. soong:构建系统的核心部分,其中包括soong_ui.bash。

在build目录中,core文件夹被链接到make/core,而envsetup.sh被链接到make/envsetup.sh。这样做主要是为了对使用者屏蔽切换编译系统时的差异。

总结起来,build目录中的blueprint和kati文件夹用于处理Android.bp和Android.mk文件,生成相应的*.ninja文件供ninja处理,而make文件夹仍然保留了原始的make流程,而soong文件夹则是构建系统的核心部分。

编译流程

下图展示了soong的编译流程

在Android的编译过程中,Android.bp文件会被收集到out/soong/build.ninja.d目录。基于这些信息,blueprint工具会生成out/soong/build.ninja文件。

另一方面,Android.mk文件会由kati和ckati工具生成out/build-aosp_arm.ninja文件。

最后,这两个ninja文件会被整合合并到out/combined-aosp_arm.ninja文件中。这个合并后的ninja文件包含了Android的完整编译规则,并用于执行实际的构建操作。

编译步骤

source build/envsetup.sh
lunch aosp_arm-eng # 不清楚想要lunch的项目时,可以先执行lunch,然后在选择项目
make -j8   

编译初始化

envsetup.sh说明

编译的第一步是执行下面命令:

source build/envsetup.sh

下面是它做的一些事情

lunch说明

环境初始化完毕,我们需要启动一个编译目标,比如我们想要编译aosp_arm-eng, 那么我们只需要执行下面命令:

lunch 3
#或者
lunch aosp_arm-eng

如果你不知道想要编译的目标是什么,直接执行一个lunch命令,会列出所有的目标,直接回车,会默认使用aosp_arm-eng这个目标。

soong编译过程


当执行runKatiBuild时,有一个重要的步骤是加载build/make/core/main.mk文件。这个main.mk文件是Android Build系统的主控文件。从main.mk开始,它使用include命令将所有需要的.mk文件包含进来,最终在内存中形成一个包含所有编译脚本的集合,相当于一个巨大的Makefile文件。这个Makefile文件看起来可能很庞大,但实际上主要由三种内容构成:变量定义、函数定义和目标依赖规则。此外,mk文件之间的相互包含也非常重要。

Make 和 Soong 比较

Make示例

##Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libxmlrpc++
LOCAL_MODULE_HOST_OS := linux

LOCAL_RTTI_FLAG := -frtti
LOCAL_CPPFLAGS := -Wall -Werror -fexceptions
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/src

LOCAL_SRC_FILES := $(call \
     all-cpp-files-under,src)
include $(BUILD_SHARED_LIBRARY)

Soong示例

##Android.bp
cc_library_shared {
     name: “libxmlrpc++”,

     rtti: true,
     cppflags: [
           “-Wall”,
           “-Werror”,
           “-fexceptions”,
     ],
     export_include_dirs: [“src”],
     srcs: [“src/**/*.cpp”],

     target: {
           darwin: {
                enabled: false,
           },
     },
}

工具链关系

Android.mk文件、Android.bp、kati、Soong、Blueprint和Ninja之间的关系如下:

  1. Android.bp --> Blueprint --> Soong --> Ninja

    • Android.bp文件通过Blueprint工具进行生成和解析,然后传递给Soong工具进行处理,最终生成Ninja文件。
  2. Makefile或Android.mk --> kati --> Ninja

    • Makefile或Android.mk文件经过kati工具的转换,生成Ninja文件。
  3. Android.mk --> Soong --> Blueprint --> Android.bp

    • Android.mk文件可以通过Soong提供的androidmk工具转换为Android.bp文件,但仅适用于简单的配置。

在编译过程中,现有的Android.mk文件和已有的Android.bp文件分别被转换为相应的Ninja文件。从Android.mk及其他Makefile文件生成的是out/build-<product_name>.ninja文件,而从Android.bp文件生成的是out/soong/build.ninja文件。此外,还会生成一个较小的out/combined-<product_name>.ninja文件,用于将两者组合起来作为执行入口。

最终,Ninja文件是直接控制源码编译的工具。它们包含了编译所需的规则和指令,用于构建Android系统。

Soong模块编译小技巧

我们一般使用mm命令进行模块编译,但是每次修改都使用mm,那么编译时间会让你怀疑人生,因为每次执行mm都会做全局检查,重新生成*.ninja全局文件,这个速度是很慢的,所以建议如下
Android.bp或者Android.mk有改动, 或者源码文件有增删的情况下,使用mm命令。

无Android.bp或者文件增删情况下使用ninja命令,使用脚本封装一些快捷命令,这样就能跳过全局检查,节省编译时间。

参考链接

[Soong构建系统] https://android.googlesource.com/platform/build/soong/+/refs/heads/master/README.md
[Android Make构建系统] https://android.googlesource.com/platform/build/+/master/README.md
[借助 Bazel 打造 Android 平台]https://docs.bazel.build/versions/master/bazel-overview.html?hl=zh-cn

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言第入门——第十六课

目录 一、分治策略与递归 二、递归 1.求解n的阶乘 2.输入整数、倒序输出 3.输入整数、正序输出 4.计算第n位Fibonacci数列 ​编辑5.无序整数数组打印 6.找到对应数组下标 一、分治策略与递归 在我们遇到大问题的时候&#xff0c;我们的正确做法是将它分解成小问题&a…

实验六:Android的网络编程基础

实验六&#xff1a;Android 的网络编程基础 6.1 实验目的 本次实验的目的是让大家熟悉 Android 开发中的如何获取天气预报&#xff0c;包括了 解和熟悉 WebView、WebService 使用、网络编程事件处理等内容。 6.2 实验要求 熟悉和掌握 WebView 使用 了解 Android 的网络编程…

Unity 预制体放在场景中可见,通过代码复制出来不可见的处理

首先我制作了一个预制体&#xff0c;在场景中是可见的&#xff0c;如下图 无论是Scene视图&#xff0c;还是Game视图都正常。 我把预制体放到Resources里面&#xff0c;然后我通过如下代码复制到同个父物体下。 GameObject obj1 Instantiate(Resources.Load("Butcon&quo…

windows使用lcx端口转发登陆远程主机

1.编译lcx源码: GitHub - UndefinedIdentifier/LCX: 自修改免杀lcx端口转发工具 2.在win7上安装vs2010并编译生成lcx.exe 3.在要被控制主机上运行: lcx -slave 192.168.31.248 51 192.168.31.211 3389 192.168.31.248为远程主控制主机,51为远程主机端口 192.168.31.211为被…

Web server failed to start. Port 8080 was already in use.

Windows 服务端口被占用&#xff0c;杀死进程命令&#xff1a; netstat -ano | findstr 8080taskkill -PID [xxx] -F

9款AI让你在2分钟内创建任何东西

1、免费AI绘画&#xff1a;LeonardoAi一个免费的 Midjourney 替代品&#xff0c;能够快速创建高品质和风格统一的视觉图片&#xff0c;帮你释放创造力。 2、 模板编辑AI&#xff1a;Canva 将所有AI的强大功能汇聚于一处&#xff0c;为你的工作流程注入超级动力。 3、构建网站&…

【C++初阶】STL详解(二)string类的模拟实现

本专栏内容为&#xff1a;C学习专栏&#xff0c;分为初阶和进阶两部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握C。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&…

07 robotframework JS和RFS值传递

1、JS的值传给RFS变量 示例1&#xff1a; ${bb} Execute Javascript function rand ( n ){return ( Math.floor ( Math.random ( ) * n 1 ) );};var aa rand(100);return aa; sleep ${bb}ms 示例2&#xff1a; var a [];$("iframe&quo…

UE4动作游戏实例RPG Action解析一:角色移动,旋转,动画创建,创建武器,及武器配置

文末有git地址 一、角色移动,摄像机旋转 1.1、官方RPGAction Demo下载地址: ​ 1.2、在场景中创建一个空的角色 创建一个Character蓝图和一个PlayerController蓝图,添加弹簧臂组件和摄像机,并为网格体添加上一个骨骼网格体 ​ 1.3、如何让这个角色出现在场景中, 创建一…

前端性能优化的方式

文章目录 前言DNS 预解析存储使用 HTTP / 2.0预加载预渲染懒执行与懒加载文件优化webpack优化如何根据chrome的timing优化移动端优化后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端系列文章 &#x1f431;‍&#x1f453;博主在前端…

Kafka入门教程与详解(一)

Kafka入门教程与详解&#xff08;一&#xff09; 一、Kafka入门教程 1.1 消息队列&#xff08;Message Queue) Message Queue消息传送系统提供传送服务。消息传送依赖于大量支持组件&#xff0c;这些组件负责处理连接服务、消息的路由和传送、持久性、安全性以及日志记录。消…

鞋业生产制造用什么ERP软件?能为企业带来哪些好处

鞋服这类商品的种类众多&#xff0c;同时也是我们生活当中较为常见的产品&#xff0c;各个制鞋企业有差异化的营销渠道和经营模式&#xff0c;日常生产过程存在的问题呈现多样化。 有些制鞋企业依然采用传统的管理方式&#xff0c;在这种模式之下&#xff0c;企业并不能随时掌…

西浦成立产业家学院破解 “产业级” 问题!AMT企源成首批合作机构

在推动高质量发展的国家战略背景下&#xff0c;从集成电路到人工智能&#xff0c;从新能源到绿色低碳&#xff0c;从健康养老到数字文创&#xff0c;无论国家还是区域都面临着产业转型升级或突破创新的发展需求&#xff0c; 这些 “产业级” 问题的难度远非单个企业层面问题可比…

微信小程序 限制字数文本域框组件封装

微信小程序 限制字数文本域框 介绍&#xff1a;展示类组件 导入 在app.json或index.json中引入组件 "usingComponents": {"text-field":"/pages/components/text-field/index"}代码使用 <text-field maxlength"500" bindtabsIt…

思源笔记的优缺点 vs Obsidian vs Logseq vs Trilium

新用户对思源笔记的印象。&#xff08;PS&#xff1a;两年前我试用过思源笔记&#xff0c;被卡顿劝退了&#xff09; 优点 相比obsidian&#xff0c; 可在文档树拖拽 拖拽调整笔记顺序 拖拽使一个笔记成为另一个笔记的子笔记&#xff0c;树状结构 设置-文档树&#xff0c;默认…

鸿蒙APP外包开发需要注意的问题

在进行鸿蒙&#xff08;HarmonyOS&#xff09;应用开发时&#xff0c;开发者需要注意一些重要的问题&#xff0c;以确保应用的质量、性能和用户体验。以下是一些鸿蒙APP开发中需要特别关注的问题&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软…

Linux 基础操作手记四

文章目录 环境变量生效配置python版本安装SSH关闭GUIvi 清空 环境变量生效 source ~/.bashrc # 或 source ~/.zshrc 配置python版本 sudo add-apt-repository ppa:deadsnakes/ppa sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1 sudo upd…

C++初阶:STL之string类

一.为什么学习string类&#xff1f; 在C语言中没有字符串这一数据类型&#xff0c;都是用字符数组来处理字符串&#xff0c;C也支持这种C风格的字符串。除此之外&#xff0c;C还提供了一种自定义数据类型--string&#xff0c;string是C标准模板库(STL)中的一个字符串类&#x…

React项目首页中用canvas实现星空

文章目录 前言代码使用后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端系列文章 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&#xff0c;感谢大家…

2019年全国硕士研究生入学统一考试管理类专业学位联考数学试题——解析版

2019 年 1 月份管综初数真题 一、问题求解&#xff08;本大题共 5 小题&#xff0c;每小题 3 分&#xff0c;共 45 分&#xff09;下列每题给出 5 个选项中&#xff0c;只有一个是符合要求的&#xff0c;请在答题卡上将所选择的字母涂黑。 1、某车间计划 10 天完成一项任务&a…