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. vlmcsd

    scp ./vlmcsd-x64-musl-static xxx@host.ip:/opt/kms/ chmod u+x /opt/kms/vlmcsd-x64-musl-static ./vlmcs ...

  2. day75_10_22频率认证和jwt

    一.频率认证原理. 1.从dispatch中获取配置,找到setting中的配置. 2.从thtoyyling中寻找到各个认证类. 3.所有认证类都继承自basethrottle,basethrott ...

  3. RabbitMQ的消息传输保障三个层级

    这里只简单介绍一下三个层级,笔记摘录自<RabbitMQ实战指南>朱忠华作者 消息可靠传输一般是业务系统接入消息中间件时候首要考虑的问题,一般消息中间件的消息传输保障分为三个层级 1  A ...

  4. django haystack报错: ModuleNotFoundError: No module named 'blog.whoosh_cn_backend'

    在配置django haystack时报错: 解决方案: 将ENGINE的值 改为 这样就可以了.

  5. 消息队列的使用<一>:介绍、使用场景和JMS概念知识

    目录 介绍 消息队列的理解 举个栗子 使用场景 消息队列的模型与概念理解 JMS模型 基本概念: 内容: JMS定义的消息结构: PTP式消息传递 PUB/SUB式消息传递 可靠性机制 事务 消息持久 ...

  6. Java 未来行情到底如何,来看看各界人士是怎么说的

    这是黄小斜的第102篇文章 作者 l 黄小斜 来源 l 公众号[程序员黄小斜](ID:AntCoder) 转载请联系作者(wx_ID:john_josh) Java从出生到现在已经走过了 20 多个年 ...

  7. python创建文件时去掉非法字符

    1.函数作用 windows系统中文件名不能包含 \ / : * ? " < > |想要创建必须过滤掉这些字符 2.函数实现 import re def filename_fil ...

  8. Module Code: CMT107

    Cardiff School of Computer Science and InformaticsCoursework Assessment Pro-formaModule Code: CMT107 ...

  9. JS解决所有浏览器连续输入英文字母不换行问题,包括火狐(转)

    问题描述: <p style="font-size:12px;line-height:30px;">测试数据测试数据</p> p标签内如果输入一长段英文字符 ...

  10. 动态html,异步加载页面的处理

    Selenium 基本使用 # 导入 webdriverfrom selenium import webdriver# 调用键盘按键操作时需要引入的Keys包from selenium.webdriv ...