阅读最新的chromium源码,发现项目的构建系统已经从GYP全面切换到GN了。在软件开发中,经常有人忠告:不要重复造轮子。但谷歌可不管这个,造的轮子一个接一个,谁叫人家牛呢?chromiumi项目为啥要折腾构建系统呢?因为谷歌chrome浏览器追求一个字:快。不仅浏览器的速度要快,构建系统也要追求快。

构建系统简介

在探讨chromium的最新GN构建系统之前,回顾一下软件开发中的构建系统。构建系统的需求是随着软件规模的增大而提出的。如果只是做软件编程训练,通常代码量比较小,编写的源代码只有几个文件。比如你编写了一段代码放入helloworld.c文件中,要编译这段代码,只需要执行以下命令:

gcc helloworld.c
  • 1

当软件规模逐渐增加,这时可能有几十个源代码文件,而且有了模块划分,有的要编译成静态库,有的要编译成动态库,最后链接成可执行代码,这时命令行方式就捉襟见肘,需要一个构建系统。常见的构建系统有GNU Make。需要注意的是,构建系统并不是取代gcc这样的工具链,而是定义编译规则,最终还是会调用工具链编译代码。

当软件规模进一步扩大,特别是有多平台支持需求的时候,编写GNU Makefile将是一件繁琐和乏味的事情,而且极容易出错。这时就出现了生成Makefile的工具,比如cmake、AutoMake等等,这种构建系统称作元构建系统(meta build system)。在Linux上软件仓库的概念还没有普及的时候,通常我们安装软件的步骤是:

./configure
make
make install
  • 1
  • 2
  • 3

第一步就是调用AutoTool工具,根据系统环境(Linux的版本众多,软件安装情况也不一样),生成GNU Makefile。

Chromium中的构建系统

在我几年前接触chromium开源项目的时候,chromium采用的是GYP(Generate Your Projects)构建系统,这也是一种元构建系统。软件工程师根据GYP规则编写构建工程文件(通常以gyp, gypi为后缀),GYP工具根据gyp文件生成GNU Makefile。接着chromium项目又整出了Ninja构建系统,但这个Ninja并不是用来取代GYP的,而是取代GNU make的,据谷歌官方的说法是速度有了好几倍的提升。对于我们开发者而言,不需要去深入了解Ninja或GNU Makefile这样构建系统,因为这只是一种中间输出,所以ninja的出现,与我们关系不大,原来怎么写gyp,现在还是怎么写,只是构建命令稍微做了改变。

最近再看chromium的源码,发现里面熟悉的GYP文件都不见了,取而代之的是GN文件(以gn和gni为文件名后缀),瞬时感觉一夜回到解放前。然而稍微研究了一个GN文件,还是那些熟悉的模块、依赖、条件等等元素,和GYP差别不大,而且总体上比原来的GYP文件更清晰。

GN构建系统

GN是一种元构建系统,生成Ninja构建文件(Ninja build files),相较GYP而言,具有如下优点:

  • 可读性更好,更容易编写和维护。
  • 速度更快,谷歌官方给的数据是20倍的速度提升。
  • 修改GN文件后,执行ninja构建时会自动更新Ninja构建文件。以前用GYP的时候就有过修改了GYP,而忘记使用gyp命令重新生成Ninja构建文件的尴尬。
  • 更简单的模块依赖,提供了public_deps, data_deps等,在GYP中,只有一种目标依赖,导致依赖关系错综复杂,容易引入不必要的模块依赖。
  • 提供了更好的工具查询模块依赖图谱。这在GYP构建系统中是一个噩梦,要查一个目标依赖哪些模块或者一个模块被哪些目标依赖几乎是不可能的。
  • 更好的调试支持。为了打印GYP中的变量值,我以前还专门写过一篇博文<<如何打印gyp构建系统中的变量值>>,在GN中,只需要一条print语句就可以解决。

快速入门

运行GN

从命令行运行gn,这实际上是depot_tools下的一个脚本,所以需要确保depot_tools路径包含在环境变量$PATH中。

配置一个构建

在GYP中,有两个特定的目录Debug和Release目录,分别用于生成Debug版本和Release版本。在GN中,采用了更灵活的方式,你随便指定一个目录,比如为了测试,定义一个test输出目录,可以采用如下的命令:

gn gen out/test
  • 1

那要是我要分别构建Debug版本和Release版本怎么办?GN通过传递参数来解决。也就是说,现在光通过输出目录是无法确定到底是Debug版本和Release版本,而要取决于传递的构建参数。

传递构建参数

将上面的命令稍微修改一下,即可设置构建参数:

gn args out/test
  • 1

您可以使用下面的命令列出可用的构建参数和它们的缺省值:

gn args --list out/test
  • 1

我在chromium源码下运行,参数如此之多,要翻好几屏,所以不需要记住所有的参数,只需知道几个比较常用的参数:

is_component_build = true
is_debug = false
  • 1
  • 2

前面一个参数决定是否分动态库build,现在chrome for android包含了build出了几十个so,就是这么来的,好处是节约修改代码后的构建时间。后面一个参数决定是build Debug版本还是Release版本。

从编写代码到build

  1. 编写代码,比如代码文件为test/hello_world.cc
  2. 编写GN文件,比如放在和上面代码同一目录下。

    executable("hello_world") {
    sources = ["hello_world.cc",
    ]
    }
    • 1
    • 2
    • 3
    • 4
    • 5
  3. 打开源码根目录下的BUILD.gn,加入对上述目标的依赖:

    group("root") {
    deps = [..."//url","//test:hello_world",
    ]
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这里//代表源码根目录。

  4. 构建

    gn gen out/Default
    ninja -C out/Default hello_world
    out/Default/hello_world
    • 1
    • 2
    • 3

调试

  1. 打印

    static_library("hello") {
    ...
    print(configs)
    }
    • 1
    • 2
    • 3
    • 4

    可以打印这个目标的配置信息。

  2. 查看目标信息

    gn desc out/Default //test:hello_world
    • 1

    这会列出很多详细的信息,包括配置参数、目标依赖,通过更复杂的命令参数,你还可以查看某个宏定义是在哪个目标定义,目标依赖的树结构,比如:

    gn desc out/Default //base:base_i18n deps --tree
    • 1

    更多参数的说明可以使用gn help desc查看。

总结

因为还没有编写复杂的GN文件,所以对GN的优缺点还体会不深,不过对于GYP的几个深有感受的痛点: 
- 多层嵌套,导致GYP文件难以阅读和修改,想想chromium下的build/common.gypi这个文件有多恐怖 
- 打印支持 
- 对于复杂的依赖缺少有效的手段去定位和排查

这在GN上得到了完美的解决,就冲这这一点,也要为谷歌点赞。虽然是重复发明轮子,但轮子比原来的好用啊!

参考文档

  1. What is GN?
  2. GN Quick Start guide
版权声明:本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接http://blog.csdn.net/mogoweb

chromium中的GN构建系统相关推荐

  1. google gn构建系统的介绍

    GN语言和操作 GN语言和操作 内容 介绍 使用内置的帮助 设计理念 语言 字符串 清单 条件语句 循环 函数调用 作用域和执行Scoping and execution 命名事物 文件和目录名称 构 ...

  2. google的gn构建系统

    什么是GN? GN是一个生成Ninja构建文件的元构建系统,以便你可以用Ninja构建Chromium. 你为什么从GYP切换? 我们相信GN文件比GYP文件更具可读性和可维护性. GN很快: GN比 ...

  3. Ninja构建系统入门--GN与Ninja构建过程

    Ninja构建系统入门--GN与Ninja构建过程 开始 GN构建系统 搭建 结束 开始 GN构建系统 GN是一种元构建系统,生成Ninja构建文件(Ninja build files),相较GYP而 ...

  4. centos7.9编译安装构建系统gn+ninja

    1 前言 环境Win10主机+VMware15.5+Centos7.9 登录用户:root Ninja 是Google推出的注重速度的构建工具,一般在Unix/Linux上的程序通过make/make ...

  5. 鸿蒙构建系统——gn官方FAQ翻译,以及gn官方文档分享

    GN FAQ 翻译 (PS:花了将近半个小时,把GN的官方FAQ翻译了一遍,有错漏之处欢迎大家指正.) GN 的文档在哪里? GN有大量的内置的帮助文档,所以你可以运行gn help命令查阅,但是你同 ...

  6. nuget 构建自己的包_适用于企业的NuGet:持续集成自动构建系统中的NuGet

    nuget 构建自己的包 I had the pleasure of speaking at TechEd 2011 North America last week in Atlanta. You c ...

  7. Ninja 构建系统

    Ninja 构建系统 概述 Ninja([ˈnɪndʒə]忍者)是一个构建系统,与 Make 类似.作为输入,你需要描述将源文件处理为目标文件这一过程所需的命令. Ninja 使用这些命令保持目标处于 ...

  8. OpenHarmony编译构建系统详解,从零搭建windows下开发环境,巨方便!

    自从OpenHarmony更新了dev-tool,就可以在windows下构建鸿蒙(轻量型)系统了,这对于进行MCU开发的朋友们,学习鸿蒙OS会友好许多!我们可以更快的构建出系统,方便快速学习和验证. ...

  9. 学会使用Chromium中的LOG

    转自:http://blog.csdn.net/kuerjinjin/article/details/43937345 简介 众所周知chromium项目无比巨大,想去快速的了解,调试并添加自己想要的 ...

最新文章

  1. Uva 11400 - Lighting System Design (DP)
  2. 谷歌深度学习公开课任务 5: Word2VecCBOW
  3. py-opp 类(class)
  4. “融合、智能、绿色”施耐德电气线上工博以全生命周期解决方案助推数字化
  5. LDA(线性判别分析)详解 —— matlab
  6. s905各种型号的区别_预行式增压缸和直压增压缸有什么区别?
  7. 平均薪资 38.4 万!3 步教你成为区块链开发者,收好这份学习指南!
  8. 使用Python代码处理Excel
  9. jqueryui时间插件_jQueryUI菜单插件教程示例
  10. html期末作业代码网页设计——代码质量好-宠物网(8页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 计算机毕设网页设计源码
  11. wordpress网站提示“建立数据库连接时出错”
  12. 【控制理论】离散及连续的LQR控制算法原理推导
  13. 关于芯片、CPU的区别的简单理解
  14. 国内千万级手机端视频互动娱乐直播完整源码
  15. Google Android Market电子市场/应用商店
  16. oppoa11android版本是什么,oppoa11x处理器是什么?oppoA11x配置介绍
  17. MyBatis自带的缓存配置(Cache)
  18. 如何配置自己的服务器接入微信服务器
  19. 介绍qmake2cmake
  20. 原神如何修改服务器,原神PC端界面太大怎么修改 pc窗口界面调整方法分享[多图]...

热门文章

  1. 达内code下载地址
  2. 【编程之美】一摞烙饼的排序
  3. 解析B2C电子商务网站系统架构
  4. 安卓开发———打开相机拍照或者打开相册选择照片并显示出来
  5. 从零开始的Unity萌导书#1:Hello,Unity! 1
  6. Arista-CVP初始化
  7. 1688获得店铺的所有商品教程
  8. html 不出现水平滚动条,html – 不带滚动条的水平滚动
  9. seo模拟点击软件_关键词快排是什么?SEO快排、刷点击和快排发包原理分析
  10. 微信小程序:认证注册微信小程序之后,正确登录微信小程序后台管理