3. gn入门
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,必须遵循以下要求:
- 在根目录创建.gn文件,该文件用于指定BUILDCONFIG.gn文件的位置;
- 在BUILDCONFIG.gn中指定编译时使用的编译工具链;
- 在独立的gn文件中定义编译使用的工具链;
- 在项目根目录下创建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:
- action: Declare a target that runs a script a single time.(指定一段指定的脚本)
- action_foreach: Declare a target that runs a script over a set of files.(为一组输入文件分别执行一次脚本)
- bundle_data: [iOS/macOS] Declare a target without output. (声明一个无输出文件的target)
- copy: Declare a target that copies files. (声明一个只是拷贝文件的target)
- create_bundle: [iOS/macOS] Build an iOS or macOS bundle. (编译MACOS/IOS包)
- executable: Declare an executable target. (生成可执行程序)
- generated_file: Declare a generated_file target.
- group: Declare a named group of targets. (执行一组target编译)
- loadable_module: Declare a loadable module target. (创建运行时加载动态连接库,和deps方式有一些区别)
- rust_library: Declare a Rust library target.
- shared_library: Declare a shared library target. (生成动态链接库,.dll or .so)
- source_set: Declare a source set target. (生成静态库,比static_library要快)
- static_library: Declare a static library target. (生成静态链接库,.lib or .a)
- target: Declare an target with the given programmatic type.
因此,我们的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入门的更多相关文章
- Vim新手入门资料和一些Vim实用小技巧
一些网络上质量较高的Vim资料 从我07年接触Vim以来,已经过去了8个年头,期间看过很多的Vim文章,我自己觉得非常不错,而且创作时间也比较近的文章有如下这些. Vim入门 目前为阿里巴巴高级技术专 ...
- 15、ASP.NET MVC入门到精通——MVC-路由
本系列目录:ASP.NET MVC4入门到精通系列目录汇总 Routing(路由) – URL url 作为广泛使用的Web用户接口,需要被重视 好的Url应该满足如下条件: URL应为获取某种资源提 ...
- IRIS数据集的分析-数据挖掘和python入门-零门槛
所有内容都在python源码和注释里,可运行! ########################### #说明: # 撰写本文的原因是,笔者在研究博文“http://python.jobbole.co ...
- Maven学习总结(一)——Maven入门——转载
一.Maven的基本概念 Maven(翻译为"专家","内行")是跨平台的项目管理工具.主要服务于基于Java平台的项目构建,依赖管理和项目信息管理. 1.1. ...
- SpringMVC学习总结(一)——SpringMVC入门
摘要: Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求 ...
- C#学习日志 day8 -------------- async await 异步方法入门(引用博客)以及序列化和反序列化的XML及json实现
首先是异步方法的介绍,这里引用自http://www.cnblogs.com/LoveJenny/archive/2011/11/01/2230933.html async and await 简单的 ...
- Vim入门基础
公司新员工学习有用到,Vim官网的手册又太大而全,而网上各方资料要么不全面,要么不够基础.在网上搜集各方资料,按照自己的框架整理一份Vim入门基础教程,分享出来.特点是偏向基础,但对入门者来说足够全面 ...
- Memcached分布式缓存快速入门
一.从单机到分布式 走向分布式第一步就是解决:多台机器共享登录信息的问题. •例如:现在有三台机器组成了一个Web的应用集群,其中一台机器用户登录,然后其他另外两台机器共享登录状态? •解决1:Asp ...
- Shiro简介及入门(四)
1.1 什么是shiro shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证.用户授权. spring中有spring security (原名Acegi),是一个权 ...
随机推荐
- Pwnable-collision
一样的连接ssh,输入密码,查看文件 看看col.c的源码 #include <stdio.h> #include <string.h> unsigned long hashc ...
- template指针小测试
测试结论: 1 函数指针 -- 使用形参固定的一系列函数作为某个函数的形参 -- callback机制 2 模板指针 -- 使用形参可变的一系列函数作为某个函数的形参 -- 3 typename -- ...
- python工具-将视频按帧截取图片(附代码)
描述:将一个视频流按帧数截取大量的图片 用途:AI的数据集制作,得到大量的图片,之后将其打标签 更改的地方 1.default--间隔的帧数 2.input/output--输入视频的路径.存放截 ...
- Vue的实例对象(三)
一.创建一个 Vue 实例 每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的: var vm = new Vue({ // 选项 }) 当创建一个 Vue 实例时,你可以传入 ...
- 再谈Token认证,如何快速方便获取用户信息
前面我写了一篇<Token认证,如何快速方便获取用户信息>的文章,引起了各位读者的积极参与,除了文章中我提出的三种方式,各位读者大佬们也贡献了其他多种实现方式. 今天决定基于大家提供的思路 ...
- 第04组 Alpha冲刺(5/6)
队名:new game 组长博客:戳 作业博客:戳 组员情况 鲍子涵(队长) 燃尽图 过去两天完成了哪些任务 才两天,也就是实现一些功能而已 复习了一下SuffixAutomata 接下来的计划 实现 ...
- c#DateTime与unix时间戳互相转换
public class UnixTimeUtil { /// <summary> /// 将dateTime格式转换为Unix时间戳 /// </summary> /// & ...
- spring-framework-core-ioc Container 笔记版本
Spring框架对于java开发人员来说是无比重要的.接触java也有3年了,接触Spring两年了.在工作中天天使用它,平时也会通过视频和书籍尝试更加的了解Spring.对于初学者来说,Spring ...
- CodeForces 574D Bear and Blocks
Limak is a little bear who loves to play. Today he is playing by destroying block towers. He built n ...
- Python 多进程池
def get_html(n): time.sleep(n) print("sub_progress success") return n # 多进程池 pool = multip ...