Chromium是用gn和ninja进行编译的,即gn把.gn文件转换成.ninja文件,然后ninja根据.ninja文件将源码生成目标程序。gn和ninja的关系就与cmake和make的关系差不多。

1. 环境配置

在我们自己的项目中,也可以使用gn来进行编译。

在windows上总是会遇到各种各样的问题,还是直接下载二进制程序省心:

https://github.com/ninja-build/ninja/releases
https://chrome-infra-packages.appspot.com/p/gn/gn

然后设置环境变量,以便在命令行中直接使用。

2. 示例

这里写个hello_word来演示下gn的基本使用。

首先,写一个hello_word.cc源码文件:

#include <iostream>

int main()
{
std::cout << "Hello world: gn build example" << std::endl; return 0;
}

然后在同一目录下创建BUILD.gn文件:

executable("hello_world") {
sources = [
"hello_world.cc",
]
}

同时,gn还需要在项目根目录有一个.gn文件用于指定编译工具链。这里我们直接拷贝gn官方的例子的配置,完整工程:hello_world.zip

之后就可以直接执行编译:

gn gen out/Default
ninja -C out/Default

这样就会在out/Default目录生成可执行文件hello_world.exe。



这样一个简单的示例就完成了。

在自己的项目中使用gn,必须遵循以下要求:

  1. 在根目录创建.gn文件,该文件用于指定BUILDCONFIG.gn文件的位置;
  2. 在BUILDCONFIG.gn中指定编译时使用的编译工具链;
  3. 在独立的gn文件中定义编译使用的工具链;
  4. 在项目根目录下创建BUILD.gn文件,指定编译的目标。

3. gn命令

gn gen out/dir [--args="..."]:创建新的编译目录,会自动创建args.gn文件作为编译参数。

gn args --list out/dir:列出可选的编译参数。

gn ls out/dir:列出所有的target;

gn ls out/dir "//:hello_word*":列出匹配的target;

gn desc out/dir "//:hello_word":查看指定target的描述信息,包括src源码文件、依赖的lib、编译选项等;

gn refs out/dir 文件:查看依赖该文件的target;

gn refs out/dir //:hello_word:查看依赖该target的target

。。。

注意//代表从项目根目录开始。

4. BUILD.gn文件语法

gn语法很接近python,主要的官方文档是以下两篇:

https://chromium.googlesource.com/chromium/src/tools/gn/+/48062805e19b4697c5fbd926dc649c78b6aaa138/docs/language.md

https://gn.googlesource.com/gn/+/master/docs/reference.md

这里简单介绍下一些关键用法:

4.1 新增编译参数

declare_args() {
enable_test = true
}

这样就新增了一个enable_test的gn编译参数,默认值是true。在BUILD.gn文件中,你就可以根据这个编译参数的值进行一些特殊化配置:

if(enable_test)
{
...
}

4.2 新增宏

  defines = [ "AWESOME_FEATURE", "LOG_LEVEL=3" ]

这些宏可以直接在C++或C代码中使用。

4.3 新增编译单元

target就是一个最小的编译单元,可以将它单独传递给ninja进行编译。

从google文档上看有以下几种target:

因此,我们的hello示例其实也只是增加了一个executable target。

4.4 新增配置

使用config可以提供一个公共的配置对象,包括编译flag、include、defines等,可被其他target包含。

  config("myconfig") {
include_dirs = [ "include/common" ]
defines = [ "ENABLE_DOOM_MELON" ]
} executable("mything") {
configs = [ ":myconfig" ]
}

4.5 新增模板

模板,顾名思义,可以用来定义可重用的代码,比如添加新的target类型等。

通常可以将模板单独定义成一个.gni文件,然后其他文件就可以通过import来引入实现共享。这部分就比较复杂,具体例子可参阅官方文档。

4.6 新增依赖关系

平时我们在编译的时候都会很小心地处理各种动态库和静态库的链接引入,在gn中,我们需要使用deps来实现库的依赖关系:

if (enable_nacl) {
deps += [ "//components/nacl/loader:nacl_loader_unittests" ] if (is_linux) {
# TODO(dpranke): Figure out what platforms should actually have this.
deps += [ "//components/nacl/loader:nacl_helper" ] if (enable_nacl_nonsfi) {
deps += [
"//components/nacl/loader:helper_nonsfi",
"//components/nacl/loader:nacl_helper_nonsfi_unittests",
]
}
}
}

5.通用toolchain配置

gn编译的toolchain配置非常关键,决定了你编译的方式和产物的用途,chromium自带的toolchains也能实现跨平台,但是太过庞大,我们日常使用的话,可以使用:https://github.com/timniederhausen/gn-build

6.使用gn编译mini_chromium库

mini_chromium提供了一个mini版本的chromium base库,里面提供很多有用的工具:日志库、字符串处理、文件处理等,github地址:https://github.com/chromium/mini_chromium.git

默认它使用的是gyp编译,但是其实它已经写好了BUILD.gn文件,我们只需添加.gn文件指定编译工具链即可,修改后的仓库:https://github.com/243286065/mini_chromium.git。

最后是再windows上和ubuntu上测试通过。不过发现mini_chromium上的确实内容太少了,连timer和json库都没有。

3. gn入门的更多相关文章

  1. Vim新手入门资料和一些Vim实用小技巧

    一些网络上质量较高的Vim资料 从我07年接触Vim以来,已经过去了8个年头,期间看过很多的Vim文章,我自己觉得非常不错,而且创作时间也比较近的文章有如下这些. Vim入门 目前为阿里巴巴高级技术专 ...

  2. 15、ASP.NET MVC入门到精通——MVC-路由

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 Routing(路由) – URL url 作为广泛使用的Web用户接口,需要被重视 好的Url应该满足如下条件: URL应为获取某种资源提 ...

  3. IRIS数据集的分析-数据挖掘和python入门-零门槛

    所有内容都在python源码和注释里,可运行! ########################### #说明: # 撰写本文的原因是,笔者在研究博文“http://python.jobbole.co ...

  4. Maven学习总结(一)——Maven入门——转载

    一.Maven的基本概念 Maven(翻译为"专家","内行")是跨平台的项目管理工具.主要服务于基于Java平台的项目构建,依赖管理和项目信息管理. 1.1. ...

  5. SpringMVC学习总结(一)——SpringMVC入门

    摘要: Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求 ...

  6. C#学习日志 day8 -------------- async await 异步方法入门(引用博客)以及序列化和反序列化的XML及json实现

    首先是异步方法的介绍,这里引用自http://www.cnblogs.com/LoveJenny/archive/2011/11/01/2230933.html async and await 简单的 ...

  7. Vim入门基础

    公司新员工学习有用到,Vim官网的手册又太大而全,而网上各方资料要么不全面,要么不够基础.在网上搜集各方资料,按照自己的框架整理一份Vim入门基础教程,分享出来.特点是偏向基础,但对入门者来说足够全面 ...

  8. Memcached分布式缓存快速入门

    一.从单机到分布式 走向分布式第一步就是解决:多台机器共享登录信息的问题. •例如:现在有三台机器组成了一个Web的应用集群,其中一台机器用户登录,然后其他另外两台机器共享登录状态? •解决1:Asp ...

  9. Shiro简介及入门(四)

    1.1     什么是shiro shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证.用户授权. spring中有spring security (原名Acegi),是一个权 ...

随机推荐

  1. jacoco统计自动化代码覆盖率

    jacoco统计自动化代码覆盖率 1. 简介 1.1. 什么是Jacoco Jacoco是一个开源的代码覆盖率工具,可以嵌入到Ant .Maven中,并提供了EclEmma Eclipse插件,也可以 ...

  2. 并行计算:并行I/O服务器的操作参数

    视频来源:新竹清华大学:并行计算与并行编程课程 上图结论:随着年限,计算力的增长很快,而I/O近于平缓,二者之间的差距增大,带来不利的影响.需要一些方法来处理这较大的差距. 解决方案: 1:I/O 内 ...

  3. Visual Studio 2017 编译 gens 世嘉模拟器

    1) 下载源代码 2.14 版本 http://gens.me/downloads.shtml 2) 下载 老版本 DirectX 并且安装 https://github.com/apitrace/a ...

  4. Paper | One-to-Many Network for Visually Pleasing Compression Artifacts Reduction

    目录 故事 网络设计 网络前端 升采样中的平移-均值化 网络度量 训练 发表于2017年CVPR. 目标:JPEG图像去压缩失真. 主要内容: 同时使用感知损失.对抗损失和JPEG损失(已知量化间隔, ...

  5. P2按要求补全表达式

    ---恢复内容开始--- #include<stdio.h> int main () {   int x; printf("输入一个整数"); scanf(" ...

  6. N!(hdu1042)

    N! Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N! Input One N in one line, process ...

  7. ELK 框架整体流程编写 以及logstash脚本编写

    Elasticsearch Elasticsearch 是一个实时的分布式搜索和分析引擎,它可以用于全文搜索,结构化搜索以及分析.它是一个建立在全文搜索引擎 Apache Lucene 基础上的搜索引 ...

  8. TensofFlow函数: tf.image.crop_and_resize

    tf.image.crop_and_resize( image, boxes, box_ind, crop_size, method='bilinear', extrapolation_value=0 ...

  9. 使用EF批量新增数据十分缓慢

    使用EF来批量新增数据,发现效率非常的差,几千条数据时甚至需要几分钟来执行,迫于无奈使用sql来执行了. 今天偶然看到一篇关于EF的文章,才发觉原来是自己对EF不够了解的原因. 一般新增时我们是将所有 ...

  10. Java生鲜电商平台-积分,优惠券,会员折扣,签到、预售、拼团、砍价、秒杀及抽奖等促销模块架构设计

    Java生鲜电商平台-积分,优惠券,会员折扣,签到.预售.拼团.砍价.秒杀及抽奖等促销模块架构设计 说明:本标题列举了所有目前社会上常见的促销方案,目前贴出实际的业务运营手段以及架构设计,包括业务说明 ...