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. 2. Go语言—包概念

    一.包的概念 和python一样,把相同功能的代码放到一个目录,称之为包 包可以被其他包引用(若包中变量/函数被其他包调用,名需大写) main包是用来生成可执行文件,每个程序只有一个main包 包的 ...

  2. DRF的基本使用(一)

    本帖最后由 杰哥,我就服你 于 2018-12-20 13:22 编辑 Django rest framework(DRF) D:是一个用于构建Web API强大又灵活的框架,基于Django框架二次 ...

  3. destoon模块绑定二级域名出现 File not found解决办法

    昨天晚上帮一个朋友给我说他绑定模块二级域名出现 File not found,所以今天分享关于解决办法. 模块启用二级域名后,首页打开正常,但是点内容页和列表页出现File not found. 解决 ...

  4. SpringMVC其他说明(六)

    1. 编码问题 在web.xml中配置过滤器: <!-- 源码:spring-web.jar 功能:字符集过滤器,设置编码集为UTF-8,解决POST的中文乱码问题. 参数说明: encodin ...

  5. LG3119 「USACO2015JAN」Grass Cownoisseur

    问题描述 LG3119 题解 显然,如果有个环,一定是全部走完的. 所以缩点,缩出一个 \(\mathrm{DAG}\) . 只能走一次反向,于是在正图和反图上各跑一次,枚举边,取 \(\mathrm ...

  6. Linux 下 make 的时候,老是一堆warning

    用下面的方法只显示error : 1) export CFLAGS="-w" 2) ./configure 3) make

  7. ant design pro解决初始加载,有顺序的请求/请求顺序报错问题/登录后再加载其他数据/异步的顺序问题/偷跑

    方法是:如在Authorized.jsx中解决,当未登录成功(包括登录失败和登录验证中),就显示loading,否则继续 加载渲染children 一个三目运算或者if分支就可以解决,但是要写到最先加 ...

  8. dbvisualizer客户端执行创建存储过程或自定义函数语句的方法

    DBVisualizer这个数据库客户端工具,如果要执行存储过程或函数的话,需要在创建存储过程或函数的语句的最前面和末尾分别加上[--/]和[/]符号. --/ CREATE FUNCTION B22 ...

  9. Kubernetes 部署集群内部DNS服务

    Kubernetes 部署集群内部DNS服务 部署官网:https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/ ...

  10. 练手WPF(三)——扫雷小游戏的简易实现(中)

    八.随机布雷 /// <summary> /// 随机布地雷 /// </summary> /// <param name="mineNum"> ...