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. 5. git-lab 项目操作

    项目操作 一.给成员授权项目权限 之前我们是给组增加成员.  当有的项目需要给组下面的成员授权不一样的时候. 我们需要在项目里面给成员授权权限 点击管理区域 点这个项目 看下图,我们可以看到  现在这 ...

  2. 新建全色或者resize(毫无价值,只是做记录)

    import glob import os,sys import shutil import numpy as np import cv2 import matplotlib.pyplot as pl ...

  3. django框架创建app及使用、

    App 创建一个app : python manage.py startapp app01 admin: from django.contrib import admin # Register you ...

  4. BZOJ2073 「POI2004」PRZ 状压DP

    问题描述 BZOJ2073 题解 发现 \(n \le 16\) ,显然想到状压 设 \(opt[S]\) 代表过河集合为 \(S\) 时,最小时间. 枚举 \(S\) 的子集,进行转移 枚举子集的方 ...

  5. luoguP2597 [ZJOI2012]灾难

    题意 这题思路好奇怪啊 见到有向无环图显然是要拓朴排序,不妨按照被吃向吃连边,那么\(x\)灭绝当且仅当x的入点都灭绝,于是考虑怎样x的入点都灭绝 比如4号节点,它灭绝当且仅当2和3灭绝,2和3灭绝当 ...

  6. Python 链表(linked list)

    链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 链表由一系列结点组成,结点可以在运行时动态生成 优点 由于不必须按顺序存储,链表在插入.删除的时候 ...

  7. web 服务

    package main import ( "strings" "fmt" "net/http" "log" ) fun ...

  8. FFT_应用和例题

    卷积 现有两个定义在 N 上的函数 \(f(n),g(n)\),定义 \(f\) 和 \(g\) 的卷积(convolution)为 \(f \otimes g\) \[ (f \otimes g)( ...

  9. Flutter命令突然无响应、vscode突然无法连接到IOS模拟器

    这周过来突然flutter相关命令运行都没有响应, 打开任务管理器,关闭所有dart进程即可解决

  10. k8s二进制部署

    k8s二进制部署 1.环境准备 主机名 ip地址 角色 k8s-master01 10.0.0.10 master k8s-master02 10.0.0.11 master k8s-node01 1 ...