gn 是 Google 的大型项目采用的编译系统,广泛应用在 chromium、Fuchsia 等项目中,主要的功能是生成 ninja 文件,再通过 ninja 编译真实的代码,与 CMake 的逻辑类似
Gn 的特点是为大项目而生,因此并不一定能保证构建配置的简单,而是清晰、结构化、易于维护
根目录结构 §
根目录需要有一个 .gn
文件,最少要包含构建的配置文件路径:
BuildConfig 规则 §
对应的配置文件需要描述当前的编译规则:
目录下有简单的跨平台编译的规则,同时也有不同构建成果的默认设置,其中 //build:compiler_defaults
这种形式表达的是下 $ROOTDIR/build
目录下的(BUILD.gn
)的 compiler_defaults
变量。
可执行文件 §
可执行文件的编译规则以 executable
作为前缀,在 tutorial
目录下的 BUILD.gn
描述:
接着可以在根目录的 BUILD.gn
中添加 tutorial
的信息,这里因为是可执行文件,无法添加成某些其他程序的依赖,因此构建一个 group
来实现:
group
在 gn 中表达的是一系列不可以被编译 or 链接的目标
编译执行 §
编译执行分两个步骤:
- 使用 gn 生成 ninja 的编译脚本
- 使用 ninja 编译
为了编译执行我们的 tutorial
:
链接库 §
动态和静态链接库的构建规则也非常简单:
可以注意下路径和作用域
Config 配置 §
因为链接库总是需要考虑编译的各种配置,例如 Flags、defines 以及 include 的文件夹路径,所以可以把这些都写入到 config 中,gn 提供了这样的功能:
public_configs
可以用来定义所有依赖你的目标的配置
- 这个 config 是可以传播的
More about labels §
Full label §
//chrome/browser:version
-> Looks for “version” in chrome/browser/BUILD.gn
Implicit name §
//base
-> Shorthand for //base:base
In current file §
:baz
-> Shorthand for “baz” in current file.
Built-in target types §
- executable, shared_library, static_library
- loadable_module: like a shared library but loaded at runtime
- source_set: compiles source files with no intermediate library
- group: a named group of targets (deps but no sources)
- copy
- action, action _foreach: run a script
- bundle_data, create_bundle: Mac & iOS
动态加载 §
BUILD. Gn 和 xxx. Gni §
BUILD.gn
一般作为模块的工程入口文件,可以配合 .gni
文件来划分源码或模块。
- 当模块比较大时,可以用
.gni
来划分内部子模块,减轻工程文件的负担
- 当多个模块之间差异很小时,可以利用 BUILD.gn 来统一管理这些模块的设置,利用.gni 来专属负责各个模块源文件管理。