GN使用指南

GN使用指南

运行 GN

你可以在命令行里直接输入gn运行。因为在depot_tools(路径应该在你的环境变量PATH中已经设置过)工具目录中有一个相同名字的脚本。这个脚本会找到当前目录中的二进制文件并运行它。

构建一个build

使用GYP时,系统会根据相应的配置参数分别生成Debug和Release编译目录。但GN不一样,你可以任意配置你的编译参数和生成目录。编译时如果检测到Ninja文件需要更新时,也会自动重新生成。

新生成一个编译目录:

gn gen out/my_build

传入编译参数

设置编译目录的编译参数:

gn args out/my_build

然后,会弹出一个文本编辑器,像下面这样输入编译参数:

is_component_build = trueis_debug = false

查看所有的参数变量以及他们的默认值:

gn args --list out/my_build

这个命令必须指定编译目录,因为不同的目录有不同的参数值。

Chrome 开发者还可以参考Chrome-specific build configuration的指示获取更多信息。

交叉编译配置(Cross-compiling to a target OS or architecture)

运行gn args out/Default(用你需要的目录替换),添加下面的常用的交叉编译选项中的一个或多个:

target_os = "chromeos"target_os = "android"target_cpu = "arm"target_cpu = "x86"target_cpu = “x64”

goma 配置

运行gn args out/Default(用你需要的目录替换)。并添加:

use_goma = truegoma_dir = “~/foo/bar/goma”

如果你的 goma 安装在默认路径(~/goma),可以忽略goma_dir参数。

配置 component 模式

运行gn args out/Default并添加:

is_component_build = true

分步详解

增加一个编译文件(BUILD.gn)

创建文件tools/gn/tutorial/BUILD.gn并输入:

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

在目标目录中应该存在一个hello_world.cc的文件,包含你期望的内容。现在我们仅仅需要告诉编译器需要处理这个编译文件就行了。打开根目录(src)下的BUILD.gn文件,将新创建的编译文件添加到其中一个根group的依赖项中(这里的每个group是其它目标的一个集合):

group(“root”) { deps = [ … “//url”, “//tools/gn/tutorial:hello_world”, ]}

你可以看到你的目标文件标签的前面有一个”//”符号(表示源码的根目录,也就是src目录),后面紧跟具体路径,再接一个冒号,最后就是你的项目的目标名称。

测试你新增的工程

在源码根目录中,使用命令行操作:

gn gen out/Defaultninja -C out/Default hello_worldout/Default/hello_world

GN 鼓励对静态库使用相同的名字。编译其中的某个时,你可以将不带前缀”//”的标签文本传给 ninja:

ninja -C out/Default tools/gn/tutorial:hello_world

声明依赖

现在来构建一个静态库,它有一个函数,功能是对任何人说hello。这些都包含在一个hello.cc的文件中。打开tools/gn/tutorial/BUILD.gn,将下面的配置静态库的文本添加到文件的最下面:

static_library(“hello”) { sources = [ “hello.cc”, ]}

我再添加一个可执行文件的工程,依赖上面的静态库:

executable(“say_hello”) { sources = [ “say_hello.cc”, ] deps = [ “:hello”, ]}

这个exe的工程包含一个源文件并且依赖上面的lib工程。lib是通过exe中的deps依赖项来引入的。你也可以使用全路径文本//tools/gn/tutorial:hello,但是如果你引入的工程是在同一个build文件中,你可以使用缩写:hello。

测试静态库

在源码根目录中输入:

ninja -C out/Default say_helloout/Default/say_hello

你不需要再次运行 GN 命令了。当BUILD.gn文件改变的时候 GN会自动重新生成 ninja 文件。你知道的,这通常发生在 ninja 刚运行时,它会打印出[1/1] Regenerating ninja files。

预编译设置(Compiler settings)

我们的 hello lib工程有一个新功能,就是可以同时对两个人说 hello。这个功能是通过宏定义TWO_PEOPLE来控制的。我们可以在工程中这样添加:

static_library(“hello”) { sources = [ “hello.cc”, ] defines = [ “TWO_PEOPLE”, ]}

将一些设置放到config中(Putting settings in a config)

然而,使用lib的工程也需要知道这个预定义,将定义放到lib工程中,仅仅对这个工程中的文件生效。如果别的工程包含了hello.h,他们是看不到这个定义的。如果要看到这个定义,每个引入这个lib的工程都必须定义TWO_PEOPLE。

GN 有一个”config”的概念,可以将一些设置放在里面。现在我们来创建一个”config”并将我们需要的预定义宏放到里面:

config(“hello_config”) { defines = [ “TWO_PEOPLE”, ]}

如何在目标工程中引入这些设置,你只需要在目标的configs选项中将需要的配置罗列出来即可:

static_library(“hello”) { … configs += [ “:hello_config”, ]}

这个地方你需要使用+=,而不是=,因为每个目标工程构建编译的都有一系列的默认配置。你要做是将新的配置添加到默认的配置中,而不是全部重写它。如果需要查看默认的配置,你可以在编译文件(BUILD.gn)中使用print函数或者desc命令行子命令(下面的例子都会介绍)。

依赖配置项(Dependent configs)

上面介绍的方法可以很好的封装我们的配置,但是它仍然需要每个使用lib的工程在他们自己的配置里去设置。如果每个使用lib的工程可以自动获取这些配置,那该有多好。现在来改变以下lib的配置:

static_library(“hello”) { sources = [ “hello.cc”, ] all_dependent_configs = [ “:hello_config” ]}

这会将hello_config的配置应用到hello工程本身,以及所有依赖(所有继承,包含间接依赖)hello的工程。现在每个依赖我们的lib的工程都会获取这些配置。你也可以设置public_configs来设置只应用到直接依赖的目标项目中(不传递)。

现在,如果你编译并运行的话,你将会看到两个人的新版本:

ninja -C out/Default say_helloninja: Entering directory ‘out/Default’[1/1] Regenerating ninja files[4/4] LINK say_hello> out/Default/say_helloHello, Bill and Joy.

添加一个新的编译参数

你可以通过declare_args直接声明你接受的参数并指定它们的默认值。

declare_args() { enable_teleporter = true enable_doom_melon = false}

使用gn help buildargs来获取它们工作原理的概述。使用gn help declare_args获取声明参数的细节。

不知道发生了什么?(Don‘t know what’s going on?)

你可以运行 GN 的 verbose 模式,会看到很多关于当前发生的信息。使用-v启用。

打印调试信息

有一个print的命令,可以输出到 stdout:

static_library(“hello”) { … print(configs)}

这会打印出应用到目标项目的所有配置信息(包括默认的)。

“desc”命令

你可以运行gn desc <build_dir> 获取指定目标的信息。

gn desc out/Default //tools/gn/tutorial:say_hello

这会打印出很多我们想要的信息。你也可以只打印一项。现在来告诉你,如何知道目标工程say_hello中的TWO_PEOPLE宏定义在什么地方:

gn desc out/Default //tools/gn/tutorial:say_hello defines --blame…lots of other stuff omitted… From //tools/gn/tutorial:hello_config (Added by //tools/gn/tutorial/BUILD.gn:12) TWO_PEOPLE

你可以看见TWO_PEOPLE是通过一个 config 来定义的,你也可以知道是哪行将config应用到目标工程的(在这里,是all_dependent_configs那行)。

两外一个特别有趣的命令:

gn desc out/Default //base:base_i18n deps --tree

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值