gn+ninja 编译项目

 

gn的帮助说明

gn的帮助说明

使用步骤

  1. 创建.gn
    1. 指定根目录
    2. 用 buildconfig 來指定构建配置的位置
  2. 创建build/BUILDCONFIG.gn
    1. 指定要使用的 toolchain
    2. 设定编译参数
  3. 建立 build/toolchains/BUILD.gn
    1. 指定工具链中各工具的使用命令(规则)
  4. 建立 BUILD.gn
    1. 在 root/ 新增一个 BUILD.gn
    2. 指定最终的目标由哪些sources编译链接成
  5. 构建
    1. gn gen out
      1. 在out中生成ninja构建脚本
    2. ninja -C out
      1. 用 ninja 执行构建脚本
    3. 重新构建时,不需要再生成新的构建脚本

快速入门

配置一个构建

gn gen out/test

定义一个test输出目录

要分别构建Debug版本和Release版本怎么办?GN通过传递参数来解决。也就是说,现在光通过输出目录是无法确定到底是Debug版本和Release版本,而要取决于传递的构建参数。

传递构建参数

gn args out/test

列出可用的构建参数和它们的缺省值:

gn args --list out/test

整体构建流程

  • 在当前目录中查找.gn 文件,然后沿着目录树向上走,直到找到.gn文件所在目录为止。
    • 将此目录设置为“source root”并解析此文件以查找构建配置文件的名称。
  • 执行构建配置文件(这是默认的工具链)。
  • 将BUILD.gn文件加载到根目录中。
  • 递归加载其他目录BUILD.gn以解析所有当前依赖项。
    • 如果在指定位置找不到BUILD文件,GN将查看tools/gn/secondary中的相应位置。
  • 解决目标的依赖关系后,将.ninja文件写入磁盘。
  • 解决所有目标后,写出根build.ninja文件。

Ninja 构建系统

  1. 在Web浏览器中浏览依赖关系图

     ninja -t browse --port=8000 --no-browser mytarget
    
  2. 以自动图形布局工具graphviz的语法输出一个文件

     ninja -t graph mytarget | dot -Tpng -ograph.png
    

目标

目标是构建图中的一个节点。它通常代表将要生成的某种类型的可执行文件或库文件

目标取决于其他目标。内置的目标类型(请参阅gn help 以获取更多帮助)是:

  • action:运行一个脚本来生成一个文件。
  • action_foreach:为每个源文件运行一次脚本。
  • bundle_data:声明数据加入到Mac / iOS包。
  • create_bundle:创建一个Mac / iOS包。
  • executable:生成一个可执行文件。
  • group:引用一个或多个其他目标的虚拟依赖关系节点。
  • shared_library:.dll或.so。
  • loadable_module:.dll或.so只能在运行时加载。
  • source_set:一个轻量级的虚拟静态库(通常比真正的静态库更可取,因为它的构建速度会更快)。
  • static_library:.lib或.a文件(通常你会想要一个source_set)。

您可以使用模板来扩展它制作自定义目标类型(请参见下文)。在Chrome中,一些更常用的模板是:

  • component:源集或共享库,取决于构建类型。
  • test:测试可执行文件 在移动设备上,这将为测试创建适当的本机应用程序类型。
  • app:可执行文件或Mac/iOS应用程序。
  • android_apk:制作一个APK。有很多其他的Android模版,看//build/config/android/rules.gni。

CONFIGS

配置文件是命名对象,用于指定标志集,包含目录和定义。他们可以被应用到一个目标,并推到相关的目标

要定义一个配置:

config("myconfig") {
    includes = [ "src/include" ]
    defines = [ "ENABLE_DOOM_MELON" ]
}

要将配置应用于目标:

executable("doom_melon") {
    configs = [ ":myconfig" ]
}

构建配置文件通常指定设置默认配置列表的目标默认值。目标可以根据需要添加或删除。所以在实践中你通常会使用configs += “:myconfig”追加到默认列表。

请参阅gn help config有关如何声明和应用配置的更多信息。

路径处理

通常情况下,您需要创建一个文件名或相对于不同目录的文件名列表。运行脚本时,这种情况尤为常见,这些脚本是以构建输出目录作为当前目录执行的,而构建文件通常是指与其包含的目录相关的文件。

您可以使用rebase_path转换目录。查看gn help rebase_path更多的帮助和例子。将相对于当前目录的文件名转换为相对于根目录的典型用法是:new_paths = rebase_path(“myfile.c”, root_build_dir)

sources

sources: Source files for a target

sources: 目标的源文件

A list of files. Non-absolute paths will be resolved relative to the current build file.

文件列表。非绝对路径将相对于当前构建文件进行解析

Sources for binary targets

二进制目标的源代码

For binary targets (source sets, executables, and libraries), the known file types will be compiled with the associated tools. Unknown file types and headers will be skipped. However, you should still list all C/C+ header files so GN knows about the existence of those files for the purposes of include checking.

为了得到二进制目标(源集、可执行文件和库),已知的文件类型将使用相关的工具进行编译。未知的文件类型和头将被跳过。但是,你仍然应该列出所有的C/C+头文件,以便GN知道这些文件的存在,以便进行include检查。

As a special case, a file ending in “.def” will be treated as a Windows module definition file. It will be appended to the link line with a preceding “/DEF:” string. There must be at most one .def file in a target and they do not cross dependency boundaries (so specifying a .def file in a static library or source set will have no effect on the executable or shared library they’re linked into).

作为特殊情况,以”.def”结尾的文件将被视为Windows模块定义文件。它将被附加到链接行前面的”/DEF:”字符串。目标中最多只能有一个.def文件,并且它们不跨越依赖边界(因此在静态库或源集中指定.def文件对它们链接到的可执行库或共享库没有影响)。

For Rust targets that do not specify a crate_root, then the crate_root will look for a lib.rs file (or main.rs for executable) or a single file in sources, if sources contains only one file.

对于没有指定crate_root的Rust目标,crate_root将查找lib.rs文件(或main.rs为可执行文件)或源文件中的单个文件,如果源文件只包含一个文件。

Sources for non-binary targets

用于非二进制目标的源代码

action_foreach

The sources are the set of files that the script will be executed over. The script will run once per file.

resources 是脚本将在其上执行的文件集。该脚本将对每个文件运行一次。

action

The sources will be treated the same as inputs. See "gn help inputs" for more information and usage advice.

sources 将被视为与输入相同。有关更多信息和使用建议,请参阅“gn help inputs”。

copy

The source are the source files to copy.

sources 是要复制的源文件

source_set

source_set:声明一个源码集目标

source_set目标的语言由其源码中的扩展名决定

C-语言 source_sets

A source set is a collection of sources that get compiled, but are not linked to produce any kind of library. Instead, the resulting object files are implicitly added to the linker line of all targets that depend on the source set.

一个源码集是一个源码的集合,它被编译,但不被链接以产生任何类型的库。相反,产生的对象文件被隐含地添加到所有依赖源集的目标的链接器行中

source_sets是要编译的文件集合,这些.o文件被导出给链接器的搜索空间

In most cases, a source set will behave like a static library, except no actual library file will be produced. This will make the build go a little faster by skipping creation of a large static library, while maintaining the organizational benefits of focused build targets.

在大多数情况下,一个源码组的行为就像一个静态库,只是不会产生实际的库文件。这将通过跳过创建大型静态库而使构建速度更快一些,同时保持集中构建目标的组织优势。

只编译不链接,提高速度

The main difference between a source set and a static library is around handling of exported symbols. Most linkers assume declaring a function exported means exported from the static library. The linker can then do dead code elimination to delete code not reachable from exported functions.

源代码集和静态库之间的主要区别在于对导出符号的处理。大多数链接器认为声明一个被导出的函数意味着从静态库中导出。然后,链接器可以进行死代码消除,删除无法从导出的函数中获得的代码。

A source set will not do this code elimination since there is no link step. This allows you to link many source sets into a shared library and have the “exported symbol” notation indicate “export from the final shared library and not from the intermediate targets.” There is no way to express this concept when linking multiple static libraries into a shared library.

由于没有链接步骤,源集不会进行这种代码消除。 这允许你将许多源集链接到一个共享库中,并使用“导出符号”表示“从最终共享库而不是中间目标导出”。当将多个静态库链接到一个共享库时,没有办法表达这个概念。

Rust-语言 source_sets

A Rust source set is a collection of sources that get passed along to the final target that depends on it. No compilation is performed, and the source files are simply added as dependencies on the eventual rustc invocation that would produce a binary.

Rust源码集是传递到依赖于它的最终目标的源的集合。不执行编译,源文件只是作为将生成二进制文件的最终rustc调用的依赖项添加。

变量

Flags: cflags, cflags_c, cflags_cc, cflags_objc, cflags_objcc, asmflags, defines, include_dirs, inputs, ldflags, lib_dirs, libs, precompiled_header, precompiled_source, rustflags, rustenv Deps: data_deps, deps, public_deps Dependent configs: all_dependent_configs, public_configs General: check_includes, configs, data, friend, inputs, metadata, output_name, output_extension, public, sources, testonly, visibility

defines

defines: C preprocessor defines.

定义:C预处理器定义

A list of strings

These strings will be passed to the C/C++ compiler as #defines. The strings may or may not include an “=” to assign a value.

这些字符串将按照#define的方式传递给C/C++编译器。字符串可以包含也可以不包含”=”来赋值。

Ordering of flags and values

  1. Those set on the current target (not in a config).
  2. Those set on the “configs” on the target in order that the configs appear in the list.
  3. Those set on the “all_dependent_configs” on the target in order that the configs appear in the list.
  4. Those set on the “public_configs” on the target in order that those configs appear in the list.
  5. all_dependent_configs pulled from dependencies, in the order of the “deps” list. This is done recursively. If a config appears more than once, only the first occurence will be used.
  6. public_configs pulled from dependencies, in the order of the “deps” list. If a dependency is public, they will be applied recursively.

标志和值的排序

1. 那些在当前目标上设置的(不是在配置中)。
2. 那些设置在“配置”上的目标,以使配置出现在列表中。
3. 那些在目标上的“all_dependent_configs”上设置的,以便配置出现在列表中。
4. 那些在目标上的“public_configs”上设置的,以便那些配置出现在列表中。
5. 从依赖项中提取的All_dependent_configs,按照“deps”列表的顺序。这是递归地完成的。如果一个配置出现多次,则只使用第一次出现的配置。
6. 从依赖项中提取的Public_configs,按照“deps”列表的顺序。如果依赖项是公共的,则将递归地应用它们。

Example

defines = [ “AWESOME_FEATURE”, “LOG_LEVEL=3” ]

include_dirs

  • include_dirs:其他包含目录

    • 源码目录的列表
    • The directories in this list will be added to the include path for the files in the affected target.
    • 这个列表中的目录将被添加到受影响目标涉及的各文件的include路径中

标志和值的排序

  1. 那些在当前目标上设置的(不是在配置config中)。
  2. 那些设置在“配置config”上的目标,以使配置出现在列表中
  3. 那些在目标上的“all_dependent_configs”上设置的,以便配置出现在列表中。
  4. 那些在目标上的“public_configs”上设置的,以便那些配置出现在列表中。
  5. 从依赖项中提取的All_dependent_configs,按照“deps”列表的顺序。这是递归地完成的。如果一个配置出现多次,则只使用第一次出现的配置。
  6. 从依赖项中提取的Public_configs,按照“deps”列表的顺序。如果依赖项是公共的,则将递归地应用它们。

Example

include_dirs = [ “src/include”, “//third_party/foo” ]

declare_args()

declare_args: Declare build arguments.

declare_args:声明构建参数

Introduces the given arguments into the current scope. If they are not specified on the command line or in a toolchain’s arguments, the default values given in the declare_args block will be used. However, these defaults will not override command-line values.

将给定的参数引入当前作用域。如果没有在命令行或工具链的参数中指定它们,则将使用在declare_args块中给出的默认值。但是,这些默认值不会覆盖命令行值

See also “gn help buildargs” for an overview.

参见“gn help buildargs”以获得概述。

The precise behavior of declare args is:

declare args的精确行为是:

  1. The declare_args() block executes. Any variable defined in the enclosing scope is available for reading, but any variable defined earlier in the current scope is not (since the overrides haven’t been applied yet).

    执行declare_args()块。在封闭作用域中定义的任何变量都可以读取,但在当前作用域中较早定义的任何变量都不能读取(因为还没有应用覆盖)。

  2. At the end of executing the block, any variables set within that scope are saved, with the values specified in the block used as the “default value” for that argument. Once saved, these variables are available for override via args.gn.

    在执行块结束时,将保存在该范围内设置的所有变量,并将块中指定的值用作该参数的“默认值”。保存后,这些变量可通过args.gn进行重写

  3. User-defined overrides are applied. Anything set in “gn args” now overrides any default values. The resulting set of variables is promoted to be readable from the following code in the file.

    应用用户定义的覆盖。“gn args”中设置的任何内容现在都会覆盖任何默认值。生成的变量集将升级为可从文件的后续代码读取

This has some ramifications that may not be obvious:

这可能会产生一些不明显的后果:

- You should not perform difficult work inside a declare_args block since this only sets a default value that may be discarded. In particular, don't use the result of exec_script() to set the default value. If you want to have a script-defined default, set some default "undefined" value like [], "", or -1, and after the declare_args block, call exec_script if the value is unset by the user.

    你不应该在declare_args块中执行困难的工作,因为这只设置了一个可能被丢弃的默认值。特别是,不要使用exec_script()的结果来设置默认值。如果要让脚本定义默认值,请设置一些默认的“未定义”值,如`[]`、`""`或-1,如果用户未设置该值,请在`declare_args`块之后调用`exec_script`

- Because you cannot read the value of a variable defined in the same block, if you need to make the default value of one arg depend on the possibly-overridden value of another, write two separate declare_args() blocks:

    由于无法读取同一块中定义的变量的值,如果需要使一个参数的默认值取决于另一个参数的可能重写值,请编写两个单独的declare_args()块

    ```java
    declare_args() {
      enable_foo = true
    }
    declare_args() {
      # Bar defaults to same user-overridden state as foo.
      enable_bar = enable_foo
    }
    ```

Example

```java
declare_args() {
    enable_teleporter = true
    enable_doom_melon = false
}
```

如果要覆盖(默认禁用)Doom Melon:

  gn --args="enable_doom_melon=true enable_teleporter=true"

这也会设置 teleporter,但它已默认为打开,因此不会产生任何效果

buildargs

Build Arguments Overview

构建参数概述

Build arguments are variables passed in from outside of the build that build files can query to determine how the build works.

构建参数是从构建外部传入的变量,构建文件可以查询这些变量以确定构建的工作方式

How build arguments are set

如何设置构建参数

First, system default arguments are set based on the current system. The built-in arguments are:

首先,基于当前系统设置系统默认参数。内置参数包括:

  • host_cpu
  • host_os
  • current_cpu
  • current_os
  • target_cpu
  • target_os

Next, project-specific overrides are applied. These are specified inside the default_args variable of //.gn. See “gn help dotfile” for more.

接下来,应用特定于项目的重写。它们是在//.gndefault_args变量中指定的。参见“gn help dotfile”了解更多信息。

If specified, arguments from the –args command line flag are used. If that flag is not specified, args from previous builds in the build directory will be used (this is in the file args.gn in the build directory).

如果命令行有–args标志,则使用–args命令行标志中的参数。如果未指定该标志,则将使用build目录中以前构建的参数(位于生成目录中的args.gn文件中)。

Last, for targets being compiled with a non-default toolchain, the toolchain overrides are applied. These are specified in the toolchain_args section of a toolchain definition. The use-case for this is that a toolchain may be building code for a different platform, and that it may want to always specify Posix, for example. See “gn help toolchain” for more.

最后,对于使用非默认工具链编译的目标,将应用工具链覆盖。这些在工具链定义的toolchain_args部分中指定。这方面的用例是,工具链可能正在为不同的平台构建代码,例如,它可能希望始终指定Posix。有关更多信息,请参阅“gn help toolchain”。

If you specify an override for a build argument that never appears in a “declare_args” call, a nonfatal error will be displayed.

如果为从未出现在“declare_args”调用中的构建参数指定重写,将显示非致命错误。

Examples

- gn args out/FooBar

  Create the directory out/FooBar and open an editor. You would type something like this into that file:

  在/FooBar中创建目录并打开编辑器。你可以在文件中输入如下内容:

      ```bash
      enable_doom_melon=false
      os="android"
      ```

- gn gen out/FooBar --args="enable_doom_melon=true os=\"android\""

  This will overwrite the build directory with the given arguments. (Note that the quotes inside the args command will usually need to be escaped for your shell to pass through strings values.)

  这将使用给定的参数覆写构建目录。(请注意,args命令中的引号通常需要转义,以便shell传递字符串值。)

How build arguments are used

如何使用构建参数

If you want to use an argument, you use declare_args() and specify default values. These default values will apply if none of the steps listed in the “How build arguments are set” section above apply to the given argument, but the defaults will not override any of these.

如果要使用参数,可以使用declare_args()并指定默认值。如果上面“如何设置构建参数”一节中列出的步骤都不适用于给定参数,则将应用这些默认值,但默认值不会覆盖其中任何一个。

Often, the root build config file will declare global arguments that will be passed to all buildfiles. Individual build files can also specify arguments that apply only to those files. It is also useful to specify build args in an “import”-ed file if you want such arguments to apply to multiple buildfiles.

通常,根构建配置文件将声明传递给所有构建文件的全局参数。单个构建文件还可以指定仅适用于这些文件的参数。如果您希望将这些参数应用于多个构建文件,那么在“import”-ed文件中指定构建参数也是有用的。

template

template: Define a template rule.

template:定义模板规则。

A template defines a custom name that acts like a function. It provides a way to add to the built-in target types.

模板定义了一个类似于函数的自定义名称。它提供了一种添加内置目标类型的方法。

The template() function is used to declare a template. To invoke the template, just use the name of the template like any other target type.

template()函数用于声明一个模板。要调用模板,只需像使用任何其他目标类型一样使用模板的名称。

Often you will want to declare your template in a special file that other files will import (see “gn help import”) so your template rule can be shared across build files.

通常你会想要在一个特殊的文件中声明你的模板,其他文件将会导入(参见“gn help import”),这样你的模板规则就可以在构建文件之间共享。

Variables and templates:

变量与模板:

When you call template() it creates a closure around all variables currently in scope with the code in the template block. When the template is invoked, the closure will be executed.

当您调用template()时,它会用模板块中的代码围绕当前范围内的所有变量创建一个闭包。当模板被调用时,闭包将被执行。

When the template is invoked, the code in the caller is executed and passed to the template code as an implicit “invoker” variable. The template uses this to read state out of the invoking code.

调用模板时,将执行调用者中的代码,并将其作为隐式“invoker”变量传递给模板代码。模板使用它来读取调用代码的状态。

One thing explicitly excluded from the closure is the “current directory” against which relative file names are resolved. The current directory will be that of the invoking code, since typically that code specifies the file names. This means all files internal to the template should use absolute names.

闭包中显式排除的一个东西是相对文件名解析的“当前目录”。当前目录将是调用代码的目录,因为通常该代码指定文件名。这意味着模板内部的所有文件都应该使用绝对名称。

A template will typically forward some or all variables from the invoking scope to a target that it defines. Often, such variables might be optional. Use the pattern:

模板通常会将一些或所有变量从调用范围转发到它定义的目标。通常,这些变量可能是可选的。使用模式:

```java
if (defined(invoker.deps)) {
  deps = invoker.deps
}
```

The function forward_variables_from() provides a shortcut to forward one or more or possibly all variables in this manner:

函数forward_variables_from()提供了以这种方式转发一个或多个变量(可能是所有变量)的快捷方式:

```java
# 从invoker转发到deps, public_deps
forward_variables_from(invoker, ["deps", "public_deps"])
```

Target naming

Your template should almost always define a built-in target with the name the template invoker specified. For example, if you have an IDL template and somebody does:

您的模板几乎应该始终使用模板调用器指定的名称定义一个内置目标。例如,如果您有一个IDL模板,而有人有

```java
idl("foo") {...
```

you will normally want this to expand to something defining a source_set or static_library named “foo” (among other things you may need). This way, when another target specifies a dependency on “foo”, the static_library or source_set will be linked.

通常,您会希望将其扩展到定义名为“foo”的source_set或static_library的内容(以及您可能需要的其他内容)。这样,当另一个目标指定对“foo”的依赖关系时,将链接static_library或source_set。

It is also important that any other targets your template expands to have unique names, or you will get collisions.

模板中的任何其他目标都必须扩展为具有唯一名称,否则会发生冲突,这一点也很重要。

Access the invoking name in your template via the implicit “target_name” variable. This should also be the basis for how other targets that a template expands to ensure uniqueness.

通过隐式的“target_name”变量访问模板中的调用名。这也应该是模板如何展开其他目标以确保惟一性的基础。

A typical example would be a template that defines an action to generate some source files, and a source_set to compile that source. Your template would name the source_set “target_name” because that’s what you want external targets to depend on to link your code. And you would name the action something like “${target_name}_action” to make it unique. The source set would have a dependency on the action to make it run.

一个典型的例子是一个模板,该模板定义了一个生成源文件的操作,以及一个编译该源文件的source_set。您的模板应该将source_set命名为“target_name”,因为您希望外部目标依赖于它来链接您的代码。您可以将操作命名为“${target_name}_action”,以使其惟一。源码集将依赖于使其运行的操作。

Overriding builtin targets

覆盖内建目标

You can use template to redefine a built-in target in which case your template takes a precedence over the built-in one. All uses of the target from within the template definition will refer to the built-in target which makes it possible to extend the behavior of the built-in target:

您可以使用模板重新定义内置目标,在这种情况下,您的模板优先于内置目标。模板定义中对目标的所有使用都将引用内置目标,从而可以扩展内置目标的行为:

```java
template("shared_library") {
  shared_library(shlib) {
    forward_variables_from(invoker, "*")
    ...
  }
}
```

Example of defining a template

```python
template("my_idl") {
    # Be nice and help callers debug problems by checking that the variables the template requires are defined. This gives a nice message rather than giving the user an error about an undefined variable in the file defining the template
    # 友好一点,通过检查模板所需的变量是否已定义,帮助调用者调试问题。
    # 这提供了一条很好的消息,而不是给用户一个关于定义模板的文件中未定义变量的错误
    #
    # You can also use defined() to give default values to variables unspecified by the invoker.
    # 还可以使用defined()为调用程序未指定的变量提供默认值。
    assert(defined(invoker.sources),
        "Need sources in $target_name listing the idl files.")

    # Name of the intermediate target that does the code gen. This must incorporate the target name so it's unique across template instantiations.
    # 生成代码的中间目标的名称。这必须包含目标名称,以便它在模板实例化中唯一。
    code_gen_target_name = target_name + "_code_gen"

    # Intermediate target to convert IDL to C source. Note that the name is based on the name the invoker of the template specified. This way, each time the template is invoked we get a unique intermediate action name (since all target names are in the global scope).
    # 将IDL转换为C源的中间目标。请注意,该名称基于指定模板的调用程序的名称
    # 这样,每次调用模板时,我们都会得到一个唯一的中间操作名称(因为所有目标名称都在作用域中)
    action_foreach(code_gen_target_name) {
    # Access the scope defined by the invoker via the implicit "invoker" variable.
    # 通过隐式“invoker”变量访问调用程序定义的范围。
    sources = invoker.sources

    # Note that we need an absolute path for our script file name. The  current directory when executing this code will be that of the invoker  (this is why we can use the "sources" directly above without having to  rebase all of the paths). But if we need to reference a script relative  to the template file, we'll need to use an absolute path instead.
    # 请注意,我们需要脚本文件名的绝对路径。执行此代码时的当前目录将是调用程序的目录(这就是为什么我们可以直接使用上面的“源”,而不必重新设置所有路径的基础)。但是,如果需要引用相对于模板文件的脚本,则需要使用绝对路径。
    script = "//tools/idl/idl_code_generator.py"

    # Tell GN how to expand output names given the sources.See "gn help source_expansion" for more.
    # 告诉GN如何在给定源的情况下展开输出名称。
    # 有关更多信息,请参阅“gn help source_expansion”。
    outputs = [ "$target_gen_dir/.cc",
                "$target_gen_dir/.h" ]
    }

    # Name the source set the same as the template invocation so instancing this template produces something that other targets can link to in their deps.
    # 将源码集设置命名为与模板调用相同的名称,
    # 这样实例化该模板将生成其他目标可以在其dep中链接到的内容。
    source_set(target_name) {
    # Generates the list of sources, we get these from the action_foreach above.
    # 生成源列表,我们从上面的action_foreach获取这些
    sources = get_target_outputs(":$code_gen_target_name")

    # This target depends on the files produced by the above code gen target.
    # 这个目标依赖于上面代码生成的文件
    deps = [ ":$code_gen_target_name" ]
    }
}
```

Example of invoking the resulting template

调用结果模板的示例:

```python
# This calls the template code above, defining target_name to be "foo_idl_files" and "invoker" to be the set of stuff defined in the curly brackets.
# 调用上面的模板代码,将target_name定义为“foo_idl_files”,将“invoker”定义为花括号中定义的内容集。
my_idl("foo_idl_files") {
    # Goes into the template as "invoker.sources".
    # 作为"invoker.sources"进入模板
    sources = [ "foo.idl", "bar.idl" ]
}

# Here is a target that depends on our template.
# 这是一个依赖于模板的目标。
executable("my_exe") {
    # Depend on the name we gave the template call above. Internally, this will produce a dependency from executable to the source_set inside the template (since it has this name), which will in turn depend on the code gen action.
    # 取决于我们给上面的模板调用的名称
    # 在内部,这将产生一个从可执行文件到模板内部source_set的依赖关系(因为它有这个名称),这将反过来依赖于代码生成操作
    deps = [ ":foo_idl_files" ]
}
```

action_foreach()

action_foreach: Declare a target that runs a script over a set of files.

action_foreach: 声明一个在一组文件上运行脚本的目标

This target type allows you to run a script once-per-file over a set of sources. If you want to run a script once that takes many files as input, see “gn help action”.

这种目标类型允许您在一组源文件集上的每个文件运行一次脚本。如果你想运行一个脚本,它接受多个文件作为输入,请参阅”gn help action”。

Inputs

The script will be run once per file in the “sources” variable. The “outputs” variable should specify one or more files with a source expansion pattern in it (see “gn help source_expansion”). The output file(s) for each script invocation should be unique. Normally you use “” in each output file.

该脚本将在“sources”变量中的每个文件中运行一次。”outputs”变量应该指定一个或多个文件,其中包含源展开模式(参见”gn help source_expansion”)。每个脚本调用的输出文件应该是唯一的。通常在每个输出文件中使用“”。

If your script takes additional data as input, such as a shared configuration file or a Python module it uses, those files should be listed in the “inputs” variable. These files are treated as dependencies of each script invocation.

如果您的脚本接受额外的数据作为输入,例如共享配置文件或它使用的Python模块,这些文件应该列在“inputs”变量中。这些文件被视为每个脚本调用的依赖项

If the command line length is very long, you can use response files to pass args to your script. See “gn help response_file_contents”.

如果命令行长度很长,可以使用响应文件向脚本传递参数。参见”gn help response_file_contents”。

You can dynamically write input dependencies (for incremental rebuilds if an input file changes) by writing a depfile when the script is run (see “gn help depfile”). This is more flexible than “inputs”.

通过在脚本运行时编写一个depfile(参见“gn help depfile”),可以动态地编写输入依赖关系(如果输入文件发生更改,则增量地重新构建)。这比“输入”更灵活

The “deps” and “public_deps” for an action will always be completed before any part of the action is run so it can depend on the output of previous steps. The “data_deps” will be built if the action is built, but may not have completed before all steps of the action are started. This can give additional parallelism in the build for runtime-only dependencies.

操作的”deps”和”public_deps”将始终在操作的任何部分运行之前完成,因此它可以依赖于前面步骤的输出。如果构建了操作action,则将构建“data_deps”,但在操作的所有步骤开始之前可能还没有完成。这可以为仅运行时依赖项的构建提供额外的并行性

Outputs

The script will be executed with the given arguments with the current directory being that of the root build directory. If you pass files to your script, see “gn help rebase_path” for how to convert file names to be relative to the build directory (file names in the sources, outputs, and inputs will be all treated as relative to the current build file and converted as needed automatically).

脚本将使用给定的参数执行,当前目录是根构建目录(root build)。如果将文件传递给脚本,请参阅“gn help rebase_path”,了解如何将文件名转换为相对于构建目录的文件名(源、输出和输入中的文件名都将被视为相对于当前构建文件,并根据需要自动转换)。

GN sets Ninja’s flag ‘restat = 1` for all action commands. This means that Ninja will check the timestamp of the output after the action completes. If output timestamp is unchanged, the step will be treated as if it never needed to be rebuilt, potentially eliminating some downstream steps for incremental builds. Scripts can improve build performance by taking care not to change the timstamp of the output file(s) if the contents have not changed.

GN为所有动作命令设置忍者的标志’restat = 1 ‘。这意味着忍者将在操作action完成后检查输出的时间戳。如果输出时间戳没有改变,则该步骤将被视为永远不需要重新构建,这可能会消除一些用于增量构建的下游步骤。如果输出文件的内容没有更改,脚本可以通过不更改输出文件的时间戳来提高构建性能。

File name handling

All output files must be inside the output directory of the build. You would generally use $target_out_dir or $target_gen_dir to reference the output or generated intermediate file directories, respectively.
所有输出文件必须位于构建的输出目录中。通常使用 $target_out_dir $target_gen_dir 分别引用输出或生成的中间文件目录。

Variables

args, data, data_deps, depfile, deps, inputs, metadata, outputs, pool, response_file_contents, script, sources*

  • = required

Example

```python
# Runs the script over each IDL file. The IDL script will generate both a .cc and a .h file for each input.
# 在每个IDL文件上运行脚本。IDL脚本将为每个输入生成一个.cc和一个.h文件。
action_foreach("my_idl") {
    script = "idl_processor.py"
    sources = [ "foo.idl", "bar.idl" ]

    # Our script reads this file each time, so we need to list it as a dependency so we can rebuild if it changes.
    # 我们的脚本每次都读取这个文件,所以我们需要把它作为一个依赖项,这样如果它改变了,我们可以重新构建
    inputs = [ "my_configuration.txt" ]

    # Transformation from source file name to output file names.
    # 源文件名到输出文件名的转换。
    outputs = [ "$target_gen_dir/.h",
                "$target_gen_dir/.cc" ]

    # Note that since "args" is opaque to GN, if you specify paths here, you will need to convert it to be relative to the build directory using rebase_path().
    # 注意,由于“args”对GN不透明,如果您在这里指定路径,您将需要使用rebase_path()将其转换为相对于构建目录。
    args = [
    "",
    "-o",
    rebase_path(relative_target_gen_dir, root_build_dir) +
        "/.h" ]
}
```

toolchain

toolchain: Defines a toolchain.

A toolchain is a set of commands and build flags used to compile the source code. The toolchain() function defines these commands.

toolchain:定义工具链

工具链是用于编译源代码的一组命令和构建标志。toolchain()函数定义了这些命令。

Toolchain overview

You can have more than one toolchain in use at once in a build and a target can exist simultaneously in multiple toolchains. A build file is executed once for each toolchain it is referenced in so the GN code can vary all parameters of each target (or which targets exist) on a per-toolchain basis.

您可以在一个构建中同时使用多个工具链,并且一个目标可以同时存在于多个工具链中。构建文件对其所引用的每个工具链执行一次,因此GN代码可以在每个工具链的基础上改变每个目标(或存在哪些目标)的所有参数。

When you have a simple build with only one toolchain, the build config file is loaded only once at the beginning of the build. It must call set_default_toolchain() (see “gn help set_default_toolchain”) to tell GN the label of the toolchain definition to use. The “toolchain_args” section of the toolchain definition is ignored.

当你有一个只有一个工具链的简单构建时,构建配置文件只在构建开始时加载一次。它必须调用set_default_toolchain()(见 “gn help set_default_toolchain”)来告诉GN要使用的工具链定义的标签。工具链定义中的 “toolchain_args “部分被忽略。

When a target has a dependency on a target using different toolchain (see “gn help labels” for how to specify this), GN will start a build using that secondary toolchain to resolve the target. GN will load the build config file with the build arguments overridden as specified in the toolchain_args. Because the default toolchain is already known, calls to set_default_toolchain() are ignored.

当一个目标与使用不同工具链的目标有依赖关系时(参见 “gn help labels”了解如何指定),GN 将使用该第二工具链启动构建,以解析该目标。GN 将加载 build 配置文件,并覆盖 toolchain_args 中指定的 build 参数。 因为默认的工具链已经知道了,对set_default_toolchain()的调用被忽略了。

To load a file in an alternate toolchain, GN does the following:

1. Loads the file with the toolchain definition in it (as determined by the toolchain label).
2. Re-runs the master build configuration file, applying the arguments specified by the toolchain_args section of the toolchain definition.
3. Loads the destination build file in the context of the configuration file in the previous step.

要在备用工具链中加载一个文件,GN会执行以下操作:

1. 加载包含工具链定义的文件(由工具链标签决定)。

2. 重新运行主构建配置文件,应用工具链定义的toolchain_args部分指定的参数。

3.在上一步中,在配置文件的上下文中加载目标构建文件。

The toolchain configuration is two-way. In the default toolchain (i.e. the main build target) the configuration flows from the build config file to the toolchain. The build config file looks at the state of the build (OS type, CPU architecture, etc.) and decides which toolchain to use (via set_default_toolchain()). In secondary toolchains, the configuration flows from the toolchain to the build config file: the “toolchain_args” in the toolchain definition specifies the arguments to re-invoke the build.

工具链的配置是双向的。在默认的工具链中(例如,主要构建目标),配置从构建配置文件流到工具链。构建配置文件查看构建的状态(OS类型、CPU架构等),并决定使用哪个工具链(通过set_default_toolchain())。在辅助工具链中,配置从工具链流向构建配置文件:工具链定义中的“toolchain_args”指定了重新调用构建的参数。

Functions and variables

tool()

The tool() function call specifies the commands to run for a given step. See "gn help tool".

tool()函数的调用指定了在给定步骤中要运行的命令。参见 "gn help tool"。

toolchain_args [scope]

Overrides for build arguments to pass to the toolchain when invoking it.  This is a variable of type "scope" where the variable names correspond to variables in declare_args() blocks.

构建参数的重写,以便在调用工具链时传递给它。 这是一个 "范围" 类型的变量,其中的变量名称对应于 declare_args() 块中的变量。

When you specify a target using an alternate toolchain, the master build configuration file is re-interpreted in the context of that toolchain.  toolchain_args allows you to control the arguments passed into this alternate invocation of the build.

当你使用另一个工具链指定一个目标时,主构建配置文件会在该工具链的上下文中被重新解释。toolchain_args允许你控制传递到这个另一个构建调用的参数。

Any default system arguments or arguments passed in via "gn args" will also be passed to the alternate invocation unless explicitly overridden by toolchain_args.

任何默认的系统参数或者通过 "gn args "传递的参数也将被传递给备用调用,除非被toolchain_args明确覆盖。

The toolchain_args will be ignored when the toolchain being defined is the default. In this case, it's expected you want the default argument values.

当被定义的工具链是默认的时候,toolchain_args将被忽略。在这种情况下,预计你想要默认的参数值。

See also "gn help buildargs" for an overview of these arguments.

参见 "gn help buildargs "以了解这些参数的概况。

propagates_configs [boolean, default=false]

传播配置

Determines whether public_configs and all_dependent_configs in this toolchain propagate to targets in other toolchains.

确定此工具链中的public_configs和all_dependent_configs是否传播到其他工具链中的目标

When false (the default), this toolchain will not propagate any configs to targets in other toolchains that depend on it targets inside this toolchain. This matches the most common usage of toolchains where they represent different architectures or compilers and the settings that apply to one won't necessarily apply to others.

当为false(默认值)时,此工具链将不会将任何配置传播到依赖于此工具链的其他工具链中的目标。这与工具链的最常见用法相匹配,它们表示不同的架构或编译器,适用于一个的设置不一定适用于其他的。

When true, configs (public and all-dependent) will cross the boundary out of this toolchain as if the toolchain boundary wasn't there. This only affects one direction of dependencies: a toolchain can't control whether it accepts such configs, only whether it pushes them. The build is responsible for ensuring that any external targets depending on targets in this toolchain are compatible with the compiler flags, etc. that may be propagated.

当为true时,configs(公共的和所有依赖的)将跨越这个工具链的边界,就好像工具链的边界不存在一样。这只影响依赖的一个方向:工具链不能控制是否接受这些配置,只能控制是否推送它们。构建负责确保任何依赖于此工具链中的目标的外部目标与可能传播的编译器标志等兼容。

deps [string list]

Dependencies of this toolchain. These dependencies will be resolved before any target in the toolchain is compiled. To avoid circular dependencies these must be targets defined in another toolchain.

此工具链的依赖关系。在编译工具链中的任何目标之前,将解析这些依赖项。为了避免循环依赖,这些必须是在另一个工具链中定义的目标。

This is expressed as a list of targets, and generally these targets will always specify a toolchain:

它表示为一个目标列表,通常这些目标将始终指定一个工具链:

    ```python
    deps = [ "//foo/bar:baz(//build/toolchain:bootstrap)" ]
    ```

This concept is somewhat inefficient to express in Ninja (it requires a lot of duplicate of rules) so should only be used when absolutely necessary.

这个概念在Ninja中表达起来有些低效(它需要大量规则的重复),所以应该只在绝对必要的时候使用

Example of defining a toolchain

```java    
toolchain("32") {
    tool("cc") {
        command = "gcc "
        ...
    }

    toolchain_args = {
        use_doom_melon = true  # Doom melon always required for 32-bit builds.
        current_cpu = "x86"
    }
}

toolchain("64") {
    tool("cc") {
        command = "gcc "
        ...
    }

    toolchain_args = {
        # use_doom_melon is not overridden here, it will take the default.
        current_cpu = "x64"
    }
}
```

Example of cross-toolchain dependencies

If a 64-bit target wants to depend on a 32-bit binary, it would specify a dependency using data_deps (data deps are like deps that are only needed at runtime and aren’t linked, since you can’t link a 32-bit and a 64-bit library).

如果一个64位目标希望依赖于一个32位二进制文件,它将使用data_deps指定一个依赖项(数据deps类似于只在运行时需要的deps,并且没有链接,因为您不能链接32位库和64位库)。

```java
executable("my_program") {
  ...
  if (target_cpu == "x64") {
    # The 64-bit build needs this 32-bit helper.
    data_deps = [ ":helper(//toolchains:32)" ]
  }
}

if (target_cpu == "x86") {
  # Our helper library is only compiled in 32-bits.
  shared_library("helper") {
    ...
  }
}
```

target

target: Declare an target with the given programmatic type.

target: 用给定的程序化类型声明一个目标

```python
target(target_type_string, target_name_string) { ... }
```

The target() function is a way to invoke a built-in target or template with a type determined at runtime. This is useful for cases where the type of a target might not be known statically.

target()函数是一种调用内置目标或模板的方法,其类型在运行时确定。这对于目标的类型可能不是静态已知的情况下很有用。

Only templates and built-in target functions are supported for the target_type_string parameter. Arbitrary functions, configs, and toolchains are not supported.

target_type_string参数只支持模板和内置目标函数。不支持任意的函数、配置和工具链。

调用

```python
target("source_set", "doom_melon") {
```
相当于

```python
source_set("doom_melon") {
```

Example

```java
if (foo_build_as_shared) {
    my_type = "shared_library"
} else {
    my_type = "source_set"
}

target(my_type, "foo") {
    ...
}
```

语法

Language and grammar for GN build files

Tokens

符号

GN build files are read as sequences of tokens. While splitting the file into tokens, the next token is the longest sequence of characters that form a valid token.

GN构建文件被读取为符号序列。当将文件分割为多个令牌时,下一个令牌是组成有效令牌的最长字符序列。

White space and comments

White space is comprised of spaces (U+0020), horizontal tabs (U+0009), carriage returns (U+000D), and newlines (U+000A).

Comments start at the character “#” and stop at the next newline.

White space and comments are ignored except that they may separate tokens that would otherwise combine into a single token.

空格和注释会被忽略,除非它们可以将组合成单个标记的标记分开

Identifiers

Identifiers name variables and functions.

  identifier = letter { letter | digit } .
  letter     = "A" ... "Z" | "a" ... "z" | "_" .
  digit      = "0" ... "9" .

Keywords

The following keywords are reserved and may not be used as identifiers:

      else    false   if      true

Integer literals

An integer literal represents a decimal integer value.

  integer = [ "-" ] digit { digit } .

Leading zeros and negative zero are disallowed.

String literals

A string literal represents a string value consisting of the quoted characters with possible escape sequences and variable expansions.

字符串字面值表示由带引号的字符和可能的转义序列和变量扩展组成的字符串值

  string           = `"` { char | escape | expansion } `"` .
  escape           = `\` ( "$" | `"` | char ) .
  BracketExpansion = "{" ( identifier | ArrayAccess | ScopeAccess "
                     ") "}" .
  Hex              = "0x" [0-9A-Fa-f][0-9A-Fa-f]
  expansion        = "$" ( identifier | BracketExpansion | Hex ) .
  char             = /* any character except "$", `"`, or newline "
                    "*/ .

After a backslash, certain sequences represent special characters:

      \"    U+0022    quotation mark
      \$    U+0024    dollar sign
      \\    U+005C    backslash

All other backslashes represent themselves.

To insert an arbitrary byte value, use $0xFF. For example, to insert a newline character: “Line one$0x0ALine two”.

An expansion will evaluate the variable following the ‘$’ and insert a stringified version of it into the result. For example, to concat two path components with a slash separating them: “$var_one/$var_two” Use the “${var_one}” format to be explicitly deliniate the variable for otherwise-ambiguous cases.

Punctuation

The following character sequences represent punctuation:

      +       +=      ==      !=      (       )
      -       -=      <       <=      [       ]
      !       =       >       >=      {       }
                      &&      ||      .       ,

Grammar

The input tokens form a syntax tree following a context-free grammar:

  File = StatementList .

  Statement     = Assignment | Call | Condition .
  LValue        = identifier | ArrayAccess | ScopeAccess .
  Assignment    = LValue AssignOp Expr .
  Call          = identifier "(" [ ExprList ] ")" [ Block ] .
  Condition     = "if" "(" Expr ")" Block
                  [ "else" ( Condition | Block ) ] .
  Block         = "{" StatementList "}" .
  StatementList = { Statement } .

  ArrayAccess = identifier "[" Expr "]" .
  ScopeAccess = identifier "." identifier .
  Expr        = UnaryExpr | Expr BinaryOp Expr .
  UnaryExpr   = PrimaryExpr | UnaryOp UnaryExpr .
  PrimaryExpr = identifier | integer | string | Call
              | ArrayAccess | ScopeAccess | Block
              | "(" Expr ")"
              | "[" [ ExprList [ "," ] ] "]" .
  ExprList    = Expr { "," Expr } .

  AssignOp = "=" | "+=" | "-=" .
  UnaryOp  = "!" .
  BinaryOp = "+" | "-"                  // highest priority
           | "<" | "<=" | ">" | ">="
           | "==" | "!="
           | "&&"
           | "||" .                     // lowest priority

All binary operators are left-associative.

Types

The GN language is dynamically typed. The following types are used:

  • Boolean: Uses the keywords “true” and “false”. There is no implicit conversion between booleans and integers.

  • Integers: All numbers in GN are signed 64-bit integers.

  • Strings: Strings are 8-bit with no enforced encoding. When a string is used to interact with other systems with particular encodings (like the Windows and Mac filesystems) it is assumed to be UTF-8. See “String literals” above for more.

  • Lists: Lists are arbitrary-length ordered lists of values. See “Lists” below for more.

  • Scopes: Scopes are like dictionaries that use variable names for keys. See “Scopes” below for more.

— 领域: 领域类似于使用变量名作为键的字典。详见下面的“Scopes”。

Lists

Lists are created with [] and using commas to separate items:

   mylist = [ 0, 1, 2, "some string" ]

A comma after the last item is optional. Lists are dereferenced using 0-based indexing:

   mylist[0] += 1
   var = mylist[2]

Lists can be concatenated using the ‘+’ and ‘+=’ operators. Bare values can not be concatenated with lists, to add a single item, it must be put into a list of length one.

Items can be removed from lists using the ‘-‘ and ‘-=’ operators. This will remove all occurrences of every item in the right-hand list from the left-hand list. It is an error to remove an item not in the list. This is to prevent common typos and to detect dead code that is removing things that no longer apply.

It is an error to use ‘=’ to replace a nonempty list with another nonempty list. This is to prevent accidentally overwriting data when in most cases ‘+=’ was intended. To overwrite a list on purpose, first assign it to the empty list:

mylist = []
mylist = otherlist

When assigning to a list named ‘sources’ using ‘=’ or ‘+=’, list items may be automatically filtered out. See “gn help set_sources_assignment_filter” for more.

Scopes

All execution happens in the context of a scope which holds the current state (like variables). With the exception of loops and conditions, ‘{‘ introduces a new scope that has a parent reference to the old scope.

所有的执行都发生在保存当前状态的作用域的上下文中(比如变量)。除了循环和条件之外,’{‘引入了一个对旧作用域具有父引用的新作用域。

Variable reads recursively search all nested scopes until the variable is found or there are no more scopes. Variable writes always go into the current scope. This means that after the closing ‘}’ (again excepting loops and conditions), all local variables will be restored to the previous values. This also means that “foo = foo” can do useful work by copying a variable into the current scope that was defined in a containing scope.

变量读取递归搜索所有嵌套作用域,直到找到变量或不再有作用域。变量写操作总是进入当前作用域。这意味着在关闭’}’之后(同样排除循环和条件),所有局部变量都将恢复到之前的值。这也意味着”foo = foo”可以通过将变量复制到包含作用域中定义的当前作用域中来完成有用的工作。

Scopes can also be assigned to variables. Such scopes can be created by functions like exec_script, when invoking a template (the template code refers to the variables set by the invoking code by the implicitly-created “invoker” scope), or explicitly like:

作用域也可以分配给变量。这样的作用域可以在调用模板(模板代码引用调用代码通过隐式创建的”invoker”作用域设置的变量)时由像exec_script这样的函数创建,也可以显式地像:

empty_scope = {}
myvalues = {
  foo = 21
  bar = "something"
}

Inside such a scope definition can be any GN code including conditionals and function calls. After the close of the scope, it will contain all variables explicitly set by the code contained inside it. After this, the values can be read, modified, or added to:

在这样的作用域定义中可以包含任何GN代码,包括条件和函数调用。在作用域关闭之后,它将包含由其中包含的代码显式设置的所有变量。在此之后,可以读取、修改或添加这些值:

myvalues.foo += 2
empty_scope.new_thing = [ 1, 2, 3 ]

Scope equality is defined as single-level scopes identical within the current scope. That is, all values in the first scope must be present and identical within the second, and vice versa. Note that this means inherited scopes are always unequal by definition.

作用域相等定义为当前作用域内相同的单层作用域。也就是说,第一个作用域中的所有值必须出现,并且在第二个作用域中相同,反之亦然。注意,这意味着继承的作用域根据定义总是不相等的。

.gn 文件

When gn starts, it will search the current directory and parent directories for a file called “.gn”. This indicates the source root. You can override this detection by using the –root command-line argument

gn启动时,它将在当前目录和父目录中搜索名为“.gn”的文件。这表示源根目录。您可以使用–root命令行参数覆盖此检测

The .gn file in the source root will be executed. The syntax is the same as a buildfile, but with very limited build setup-specific meaning.

这个将执行源根目录中的gn文件。语法与构建文件相同,但具有非常有限的构建设置特定含义

If you specify –root, by default GN will look for the file .gn in that directory. If you want to specify a different file, you can additionally pass –dotfile:

如果指定–root,默认情况下,GN将在那个目录中查找该.gn文件。如果要指定其他文件,还可以传递–dotfile:

gn gen out/Debug --root=/home/build --dotfile=/home/my_gn_file.gn

Example .gn file contents

buildconfig = "//build/config/BUILDCONFIG.gn"

check_targets = [
    "//doom_melon/*",  # Check everything in this subtree.
    "//tools:mind_controlling_ant",  # Check this specific target.
]

root = "//:root"

secondary_source = "//build/config/temporary_buildfiles/"

default_args = {
    # Default to release builds for this project.
    is_debug = false
    is_component_build = false
}

check_targets [optional]

A list of labels and label patterns that should be checked when running “gn check” or “gn gen –check”. If unspecified, all targets will be checked. If it is the empty list, no targets will be checked. To bypass this list, request an explicit check of targets, like “//*”.

运行“gn check”或“gn gen–check”时应检查的标签和标签模板列表。如果未指定,将检查所有目标。如果是空列表,则不会检查任何目标。要绕过此列表,请请求显式检查目标,如“//*”。

The format of this list is identical to that of “visibility” so see “gn help visibility” for examples.

此列表的格式与“可见性”的格式相同,因此请参见“gn help visibility”以获取示例。

group

group: Declare a named group of targets.

group:声明一组命名的目标

This target type allows you to create meta-targets that just collect a set of dependencies into one named target. Groups can additionally specify configs that apply to their dependents.

此目标类型允许您创建只将一组依赖项收集到一个命名目标中的元目标。组还可以指定应用于其从属项的配置。

Variables

Deps: data_deps, deps, public_deps Dependent configs: all_dependent_configs, public_configs

Example

group("all") {
    deps = [
        "//project:runner",
        "//project:unit_tests",
    ]
}

shared_library

Declare a shared library target.

A shared library will be specified on the linker line for targets listing the shared library in its “deps”. If you don’t want this (say you dynamically load the library at runtime), then you should depend on the shared library via “data_deps” or, on Darwin platforms, use a “loadable_module” target type instead.

共享库将在链接器行中指定,目标将在其“deps”中列出共享库。如果您不希望这样(假设您在运行时动态加载库),那么您应该通过“data_deps”依赖于共享库,或者,在Darwin平台上,使用“loadable_module”目标类型。

Language and compilation

语言和编译

The tools and commands used to create this target type will be determined by the source files in its sources. Targets containing multiple compiler-incompatible languages are not allowed (e.g. a target containing both C and C++ sources is acceptable, but a target containing C and Rust sources is not).

用于创建此目标类型的工具和命令将由其源文件中的源文件决定。不允许目标包含多个编译器不兼容的语言(例如,包含C和c++源的目标是可以接受的,但包含C和Rust源的目标是不允许的)。

Variables

Flags: cflags, cflags_c, cflags_cc, cflags_objc, cflags_objcc, asmflags, defines, include_dirs, inputs, ldflags, lib_dirs, libs, precompiled_header, precompiled_source, rustflags, rustenv Deps: data_deps, deps, public_deps Dependent configs: all_dependent_configs, public_configs General: check_includes, configs, data, friend, inputs, metadata, output_name, output_extension, public, sources, testonly, visibility Rust variables: aliased_deps, crate_root, crate_name, crate_type

rebase_path

Rebase a file or directory to another location.

将文件或目录重设为另一个位置

converted = rebase_path(input, new_base = "", current_base = ".")

Takes a string argument representing a file name, or a list of such strings and converts it/them to be relative to a different base directory.

接受表示文件名或此类字符串列表的字符串参数,并将其/它们转换为相对于不同的基目录

When invoking the compiler or scripts, GN will automatically convert sources and include directories to be relative to the build directory. However, if you’re passing files directly in the “args” array or doing other manual manipulations where GN doesn’t know something is a file name, you will need to convert paths to be relative to what your tool is expecting.

在调用编译器或脚本时,GN会自动将源文件和包含文件的目录转换为相对于构建目录的目录。然而,如果你在 “args”数组中直接传递文件,或做其他手工操作,而GN不知道某样东西是一个文件名,你将需要把路径转换成相对于你的工具所期望的。

The common case is to use this to convert paths relative to the current directory to be relative to the build directory (which will be the current directory when executing scripts).

常见的情况是用它将相对于当前目录的路径转换为相对于构建目录的路径(执行脚本时,它将是当前目录)。

If you want to convert a file path to be source-absolute (that is, beginning with a double slash like “//foo/bar”), you should use the get_path_info() function. This function won’t work because it will always make relative paths, and it needs to support making paths relative to the source root, so can’t also generate source-absolute paths without more special-cases.

如果你想把文件路径转换为源绝对路径(即以双斜线开始,如”//foo/bar”),你应该使用get_path_info()函数。这个函数不能工作,因为它总是生成相对路径,而且它需要支持生成相对于源根的路径,所以如果没有更多的特殊情况,就不能生成源绝对路径。

Arguments

input

A string or list of strings representing file or directory names These can be relative paths (“foo/bar.txt”), system absolute paths (“/foo/bar.txt”), or source absolute paths (“//foo/bar.txt”).

代表文件或目录名称的字符串或字符串列表 这些可以是相对路径(”foo/bar.txt”),系统绝对路径(”/foo/bar.txt”),或源绝对路径(”//foo/bar.txt”)。

new_base

The directory to convert the paths to be relative to. This can be an absolute path or a relative path (which will be treated as being relative to the current BUILD-file’s directory).

要将路径转换为相对路径的目录。这可以是一个绝对路径或相对路径(将被视为相对于当前BUILD-file的目录)。

As a special case, if new_base is the empty string (the default), all paths will be converted to system-absolute native style paths with system path separators. This is useful for invoking external programs.

作为一种特殊情况,如果new_base是空字符串(默认),所有路径将被转换为带有系统路径分隔符的系统绝对本地风格路径。这对于调用外部程序很有用。

current_base

Directory representing the base for relative paths in the input. If this is not an absolute path, it will be treated as being relative to the current build file. Use “.” (the default) to convert paths from the current BUILD-file’s directory.

代表输入中相对路径的基础的目录。如果这不是一个绝对路径,它将被视为是相对于当前构建文件的。使用”.”(默认)来转换来自当前BUILD-文件目录的路径。

Return value

The return value will be the same type as the input value (either a string or a list of strings). All relative and source-absolute file names will be converted to be relative to the requested output System-absolute paths will be unchanged.

返回值将与输入值的类型相同(字符串或字符串列表)。所有相对的和源绝对值的文件名将被转换为与请求的输出相对的系统绝对值路径将不会改变。

Whether an output path will end in a slash will match whether the corresponding input path ends in a slash. It will return “.” or “./” (depending on whether the input ends in a slash) to avoid returning empty strings. This means if you want a root path (“//” or “/”) not ending in a slash, you can add a dot (“//.”).

一个输出路径是否以斜线结尾,将与相应的输入路径是否以斜线结尾相匹配。它将返回”. “或”./” (取决于输入是否以斜线结尾)以避免返回空字符串。这意味着如果你想要一个不以斜线结尾的根路径(”//”或”/”),你可以添加一个点(”//。”)。

Example

# Convert a file in the current directory to be relative to the build directory (the current dir when executing compilers and scripts).
# 将当前目录下的文件转换为与构建目录(执行编译器和脚本时的当前目录)的相对关系
foo = rebase_path("myfile.txt", root_build_dir)
# might produce "../../project/myfile.txt".

# Convert a file to be system absolute:
foo = rebase_path("myfile.txt")
# Might produce "D:\\source\\project\\myfile.txt" on Windows or
# "/home/you/source/project/myfile.txt" on Linux.

# Typical usage for converting to the build directory for a script.
action("myscript") {
    # Don't convert sources, GN will automatically convert these to be relative to the build directory when it constructs the command line for your script.
    # 不要转换源码,GN在为你的脚本构建命令行时,会自动将这些源码转换为相对的构建目录
    sources = [ "foo.txt", "bar.txt" ]

    # Extra file args passed manually need to be explicitly converted to be relative to the build directory:
    # 手动传递的额外文件参数需要明确转换为相对于构建目录的参数。
    args = [
    "--data",
    rebase_path("//mything/data/input.dat", root_build_dir),
    "--rel",
    rebase_path("relative_path.txt", root_build_dir)
    ] + rebase_path(sources, root_build_dir)
}
    

root_build_dir: [string]

Directory where build commands are run.

运行构建命令的目录

This is the root build output directory which will be the current directory when executing all compilers and scripts.

这是根构建输出目录,在执行所有编译器和脚本时,它将是当前目录。

Most often this is used with rebase_path (see “gn help rebase_path”) to convert arguments to be relative to a script’s current directory.

最常见的是与 rebase_path(见 “gn help rebase_path”)一起使用,将参数转换为相对于脚本的当前目录。

tool

tool: Specify arguments to a toolchain tool.

tool:为工具链工具指定参数

Usage

tool(<tool type>) {
    <tool variables...>
}

Tool types

Compiler tools:
  "cc": C compiler
  "cxx": C++ compiler
  "objc": Objective C compiler
  "objcxx": Objective C++ compiler
  "rc": Resource compiler (Windows .rc files)
  "asm": Assembler

Linker tools:
  "alink": Linker for static libraries (archives)
  "solink": Linker for shared libraries
  "link": Linker for executables

Other tools:
  "stamp": Tool for creating stamp files
  "copy": Tool to copy files.
  "action": Defaults for actions

Platform specific tools:
  "copy_bundle_data": [iOS, macOS] Tool to copy files in a bundle.
  "compile_xcassets": [iOS, macOS] Tool to compile asset catalogs.

Rust tools:
  "rust_bin": Tool for compiling Rust binaries
  "rust_cdylib": Tool for compiling C-compatible dynamic libraries.
  "rust_dylib": Tool for compiling Rust dynamic libraries.
  "rust_macro": Tool for compiling Rust procedural macros.
  "rust_rlib": Tool for compiling Rust libraries.
  "rust_staticlib": Tool for compiling Rust static libraries.

Tool variables

command  [string with substitutions]

    Valid for: all tools except "action" (required)

    适用于:除“action”之外的所有工具(必需的)

    The command to run.

    要运行的命令

command_launcher  [string]

    Valid for: all tools except "action" (optional)

    The prefix with which to launch the command (e.g. the path to a Goma or CCache compiler launcher).

    用于启动命令的前缀(例如,Goma或CCache编译器启动器的路径)。

    Note that this prefix will not be included in the compilation database or IDE files generated from the build.

    请注意,这个前缀不会包含在编译数据库或生成的IDE文件中

default_output_dir  [string with substitutions]

    Valid for: linker tools

    Default directory name for the output file relative to the root_build_dir. It can contain other substitution patterns. This will be the default value for the  expansion (discussed below) but will be overridden by the "output_dir" variable in a target, if one is specified.

    输出文件相对于root_build_dir的默认目录名。它可以包含其他替换模式。这将是展开的默认值(下面将讨论),但如果指定了目标变量,则会被“output_dir”变量覆盖。

    GN doesn't do anything with this string other than pass it along, potentially with target-specific overrides. It is the tool's job to use the expansion so that the files will be in the right place.

    GN对该字符串不做任何操作,只是传递它,可能使用特定于目标的覆盖。该工具的工作是使用展开,以便文件将位于正确的位置。

default_output_extension  [string]
    Valid for: linker tools

    Extension for the main output of a linkable tool. It includes the leading dot. This will be the default value for the  expansion (discussed below) but will be overridden by by the "output extension" variable in a target, if one is specified.  Empty string means no extension.

    可链接工具的主要输出的扩展。它包括前导点。这将是扩展(下面将讨论)的默认值,但如果指定了目标变量,则会被“output extension”变量覆盖。空字符串意味着没有扩展名。

    GN doesn't actually do anything with this extension other than pass it along, potentially with target-specific overrides. One would typically use the  value in the "outputs" to read this value.

    GN实际上对这个扩展不做任何事情,只是传递它,可能与目标特定的覆盖。通常使用“output”中的值来读取该值。

    Example: default_output_extension = ".exe"

depfile  [string with substitutions]
    Valid for: compiler tools (optional)

    If the tool can write ".d" files, this specifies the name of the resulting file. These files are used to list header file dependencies (or other implicit input dependencies) that are discovered at build time. See also "depsformat".

    如果工具可以写”.d"文件,这指定了结果文件的名称。这些文件用于列出在构建时发现的头文件依赖项(或其他隐式输入依赖项)。参见“depsformat”。

    Example: depfile = ".d"

depsformat  [string]
    Valid for: compiler tools (when depfile is specified)

    Format for the deps outputs. This is either "gcc" or "msvc". See the     ninja documentation for "deps" for more information.

    deps输出的格式。这是"gcc"或"msvc"。有关更多信息,请参阅忍者文档“deps”

    Example: depsformat = "gcc"

description  [string with substitutions, optional]
    Valid for: all tools

    What to print when the command is run.

    运行命令时要打印的内容。

    Example: description = "Compiling "

exe_output_extension [string, optional, rust tools only]
rlib_output_extension [string, optional, rust tools only]
dylib_output_extension [string, optional, rust tools only]
cdylib_output_extension [string, optional, rust tools only]
rust_proc_macro_output_extension [string, optional, rust tools only]
    Valid for: Rust tools

    These specify the default tool output for each of the crate types.  The default is empty for executables, shared, and static libraries and ".rlib" for rlibs. Note that the Rust compiler complains with an error if external crates do not take the form `lib<name>.rlib` or `lib<name>.<shared_extension>`, where `<shared_extension>` is `.so`, `.dylib`, or `.dll` as appropriate for the platform.

    这些指定了每个carte类型的默认工具输出。 对于可执行文件、共享库和静态库,默认为空,对于rlibs,默认为".rlib"。请注意,如果外部板条箱不采用`lib<name>.rlib`或`lib<name>.<shared_extension>`的形式,Rust编译器会报错,其中`<shared_extension>`是`.so`、`.dylib`或`.dll`,根据平台的情况而定。

lib_switch  [string, optional, link tools only]
lib_dir_switch  [string, optional, link tools only]
    Valid for: Linker tools except "alink"

    These strings will be prepended to the libraries and library search directories, respectively, because linkers differ on how to specify them.

    这些字符串将分别被预置到库和库搜索目录中,因为链接器在如何指定它们方面存在差异。

    If you specified:
      lib_switch = "-l"
      lib_dir_switch = "-L"
    then the "" expansion for
      [ "freetype", "expat" ]
    would be
      "-lfreetype -lexpat".

framework_switch [string, optional, link tools only]
framework_dir_switch [string, optional, link tools only]
    Valid for: Linker tools

    These strings will be prepended to the frameworks and framework search path directories, respectively, because linkers differ on how to specify them.

    这些字符串将分别被预置到框架和框架搜索路径目录中,因为链接器在如何指定它们方面有所不同。

    If you specified:
      framework_switch = "-framework "
      framework_dir_switch = "-F"
    then the "" expansion for
      [ "UIKit.framework", "$root_out_dir/Foo.framework" ]
    would be
      "-framework UIKit -F. -framework Foo"

outputs  [list of strings with substitutions]
    Valid for: Linker and compiler tools (required)

    An array of names for the output files the tool produces. These are relative to the build output directory. There must always be at least one output file. There can be more than one output (a linker might produce a library and an import library, for example).

    该工具产生的输出文件的名称数组。这些是相对于构建输出目录的。总是必须至少有一个输出文件。可以有一个以上的输出(例如,一个链接器可能产生一个库和一个导入库)。

    This array just declares to GN what files the tool will produce. It is your responsibility to specify the tool command that actually produces these files.

    这个数组只是向GN声明该工具将产生哪些文件。你有责任指定实际产生这些文件的工具命令。

    If you specify more than one output for shared library links, you should consider setting link_output, depend_output, and runtime_outputs.

    如果你为共享库链接指定一个以上的输出,你应该考虑设置link_output、depend_output和runtime_outputs。

    Example for a compiler tool that produces .obj files:

    一个产生.obj文件的编译工具的例子。

      outputs = [
        "/.obj"
      ]

    Example for a linker tool that produces a .dll and a .lib. The use of ,  and  allows the target to override these values.

    一个链接器工具的例子,它能产生一个.dll和一个.lib。使用、和允许目标覆盖这些值。

      outputs = [
        "/"
            "",
        "/.lib",
      ]

pool [label, optional]
    Valid for: all tools (optional)

    Label of the pool to use for the tool. Pools are used to limit the
    number of tasks that can execute concurrently during the build.

    See also "gn help pool".

link_output  [string with substitutions]
depend_output  [string with substitutions]
    Valid for: "solink" only (optional)

    These two files specify which of the outputs from the solink tool should be used for linking and dependency tracking. These should match entries in the "outputs". If unspecified, the first item in the "outputs" array will be used for all. See "Separate linking and dependencies for shared libraries" below for more.

    这两个文件指定了哪些来自solink工具的输出应被用于链接和依赖性跟踪。这些应该与 "output"中的条目相匹配。如果没有指定,"output"数组中的第一项将被用于所有。更多信息请参见下面的 "共享库的单独链接和依赖关系"。

    On Windows, where the tools produce a .dll shared library and a .lib import library, you will want the first two to be the import library and the third one to be the .dll file. On Linux, if you're not doing the separate linking/dependency optimization, all of these should be the .so output.

    在Windows上,工具会产生一个.dll共享库和一个.lib导入库,你会希望前两个是导入库,第三个则是.dll文件。在Linux上,如果你不做单独的链接/依赖性优化,所有这些都应该是.so的输出。

output_prefix  [string]
    Valid for: Linker tools (optional)

    Prefix to use for the output name. Defaults to empty. This prefix will be prepended to the name of the target (or the output_name if one is manually specified for it) if the prefix is not already there. The result will show up in the  substitution pattern.

    用于输出名称的前缀。默认为空。如果目标名称中没有前缀,该前缀将被添加到目标名称中(或者如果手动指定了output_name)。其结果将显示在的替换模式中。

    Individual targets can opt-out of the output prefix by setting:
      output_prefix_override = true
    (see "gn help output_prefix_override").

    This is typically used to prepend "lib" to libraries on
    Posix systems:
      output_prefix = "lib"

precompiled_header_type  [string]
    Valid for: "cc", "cxx", "objc", "objcxx"

    Type of precompiled headers. If undefined or the empty string, precompiled headers will not be used for this tool. Otherwise use "gcc" or "msvc".

    预编译头文件的类型。如果未定义或为空字符串,预编译头文件将不被用于该工具。否则使用 "gcc "或 "msvc"。

    For precompiled headers to be used for a given target, the target (or a
    config applied to it) must also specify a "precompiled_header" and, for
    "msvc"-style headers, a "precompiled_source" value. If the type is
    "gcc", then both "precompiled_header" and "precompiled_source" must
    resolve to the same file, despite the different formats required for
    each."

    See "gn help precompiled_header" for more.

restat  [boolean]
    Valid for: all tools (optional, defaults to false)

    Requests that Ninja check the file timestamp after this tool has run to determine if anything changed. Set this if your tool has the ability to skip writing output if the output file has not changed.

    请求忍者在此工具运行后检查文件的时间戳,以确定是否有任何更改。如果您的工具能够在输出文件没有更改的情况下跳过写入输出,则设置此选项。

    Normally, Ninja will assume that when a tool runs the output be new and downstream dependents must be rebuild. When this is set to trye, Ninja can skip rebuilding downstream dependents for input changes that don't actually affect the output.

    通常情况下,Ninja会认为当一个工具运行时,输出是新的,下游的依赖必须重建。当这个选项被设置为trye时,Ninja可以跳过重建对输出没有实际影响的输入依赖关系。

    Example:
      restat = true

rspfile  [string with substitutions]
    Valid for: all tools except "action" (optional)

    Name of the response file. If empty, no response file will be used. See "rspfile_content".

    响应文件的名称。如果为空,则不使用响应文件。看到“rspfile_content”。

rspfile_content  [string with substitutions]
    Valid for: all tools except "action" (required when "rspfile" is used)

    The contents to be written to the response file. This may include all or part of the command to send to the tool which allows you to get around OS command-line length limits.

    要写入响应文件的内容。这可能包括要发送给工具的全部或部分命令,这允许您绕过操作系统命令行长度限制。

    This example adds the inputs and libraries to a response file, but passes the linker flags directly on the command line:

    这个例子将输入和库添加到响应文件中,但直接在命令行上传递链接器标志:

      tool("link") {
        command = "link -o   @.rsp"
        rspfile = ".rsp"
        rspfile_content = "  "
      }

runtime_outputs  [string list with substitutions]
    Valid for: linker tools

    If specified, this list is the subset of the outputs that should be added to runtime deps (see "gn help runtime_deps"). By default (if runtime_outputs is empty or unspecified), it will be the link_output.

    如果指定了,则该列表是应该添加到运行时deps的输出的子集(请参阅"gn help runtime_deps")。默认情况下(如果runtime_outputs为空或未指定),它将是link_output。

Expansions for tool variables

All paths are relative to the root build directory, which is the current directory for running all tools. These expansions are available to all tools:

所有路径都相对于根构建目录,根构建目录是运行所有工具的当前目录。所有工具都可以使用这些扩展:

    The label of the current target. This is typically used in the "description" field for link tools. The toolchain will be omitted from the label for targets in the default toolchain, and will be included for targets in other toolchains.

    当前目标的标签。这通常用于链接工具的“描述”字段。工具链将从默认工具链中的目标的标签中省略,并将在其他工具链中的目标中包含。


    The short name of the label of the target. This is the part after the colon. For "//foo/bar:baz" this will be "baz". Unlike , this is not affected by the "output_prefix" in the tool or the "output_name" set on the target.

    目标器标签的短名称。这是":"后面的部分。对于"//foo/bar:baz",这将是"baz"。与不同,它不受工具中的“output_prefix”或目标上设置的“output_name”的影响。


    The relative path and name of the output(s) of the current build step.  If there is more than one output, this will expand to a list of all of them. Example: "out/base/my_file.o"

    当前构建步骤的输出的相对路径和名称。如果有多个输出,则将扩展为所有输出的列表。
    
    示例: "out/base/my_file.o"



    The directory of the generated file and output directories, respectively, for the current target. There is no trailing slash. See also  for linker tools. Example: "out/base/test"

    生成文件的目录和输出目录,分别为当前目标。没有尾随斜杠。链接器工具参见。
    
    例如: "out/base/test"


    The short name of the current target with no path information, or the value of the "output_name" variable if one is specified in the target.  This will include the "output_prefix" if any. See also .

    不带路径信息的当前目标的短名称,如果目标中指定了“output_name”变量,则为该变量的值。如果有的话,这将包括“output_prefix”。参见。

    Example: "libfoo" for the target named "foo" and an output prefix for the linker tool of "lib".

    例如:目标名为“foo”的目标为“libfoo”,连接器工具的输出前缀为“lib”。

Compiler tools have the notion of a single input and a single output, along with a set of compiler-specific flags. The following expansions are available:

编译器工具具有单一输入和单一输出的概念,以及一组特定于编译器的标志。以下是可用的扩展:

    Strings correspond that to the processed flags/defines/include directories specified for the target.

    字符串对应于为目标指定的已处理的flags/defines/include目录

    Example: "--enable-foo --enable-bar"

    Defines will be prefixed by "-D" and include directories will be prefixed by "-I" (these work with Posix tools as well as Microsoft ones).

    定义的前缀是"-D",包含的目录的前缀是"-I"(这些在Posix工具和微软的工具上都能使用)。


    The relative path and name of the current input file.

    当前输入文件的相对路径和名称。

    Example: "../../base/my_file.cc"


    The file part of the source including the extension (with no directory information).

    source的文件部分,包括扩展名(没有目录信息)。
    
    Example: "foo.cc"


    The filename part of the source file with no directory or extension.
    Example: "foo"



    The directory in the generated file and output directories, respectively, for the current input file. If the source file is in the same directory as the target is declared in, they will will be the same as the "target" versions above. Example: "gen/base/test"

    生成文件和输出目录中的目录,分别为当前输入文件。如果源文件与目标文件声明在同一目录下,它们将与上面的 "目标 "版本相同。例如。"gen/base/test"

Linker tools have multiple inputs and (potentially) multiple outputs. The static library tool (“alink”) is not considered a linker tool. The following expansions are available:

链接器工具有多个输入和(潜在的)多个输出。静态库工具(”alink”)不被认为是一个链接器工具。有以下几种扩展方式。

    Expands to the inputs to the link step. This will be a list of object files and static libraries.
    Example: "obj/foo.o obj/bar.o obj/somelibrary.a"

    扩展到链接步骤的输入。这将是一个对象文件和静态库的列表。
    例如。"obj/foo.o obj/bar.o obj/somelibrary.a"

    The "_newline" version will separate the input files with newlines instead of spaces. This is useful in response files: some linkers can take a "-filelist" flag which expects newline separated files, and some Microsoft tools have a fixed-sized buffer for parsing each line of a response file.

    "_newline "版本将用换行符而不是空格来分隔输入文件。这在响应文件中很有用:一些链接器可以使用"-filelist "标志,期望用换行符分隔文件,一些微软工具有一个固定大小的缓冲区来解析响应文件的每一行。


    Expands to the processed set of ldflags and library search paths specified for the target.
    Example: "-m64 -fPIC -pthread -L/usr/local/mylib"

    扩展到为目标指定的ldflags和库搜索路径的处理集
    例如。"-m64 -fPIC -pthread -L/usr/local/mylib"


    Expands to the list of system libraries to link to. Each will be prefixed by the "lib_switch".

    扩展到要链接的系统库的列表。每一个都将以 "lib_switch "为前缀。

    As a special case to support Mac, libraries with names ending in ".framework" will be added to the  with "-framework" preceding it, and the lib prefix will be ignored.

    作为支持Mac的特殊情况,名称以".framework "结尾的库将被添加到中,前面是"-framework",而lib前缀将被忽略。

    Example: "-lfoo -lbar"


    The value of the "output_dir" variable in the target, or the the value of the "default_output_dir" value in the tool if the target does not override the output directory. This will be relative to the root_build_dir and will not end in a slash. Will be "." for output to the root_build_dir.

    目标中 "output_dir "变量的值,如果目标没有覆盖输出目录,则是工具中 "default_output_dir "的值。这将是相对于root_build_dir的,不会以斜线结尾。对于输出到root_build_dir,将是"."。

    This is subtly different than  which is defined by GN based on the target's path and not overridable.  is for the final output,  is generally for object files and other outputs.

    这与有细微的不同,后者是由GN根据目标的路径定义的,不可重写。用于最终输出,一般用于对象文件和其他输出。

    Usually  would be defined in terms of either  or 

    通常,会被定义为或的一部分。


    The value of the "output_extension" variable in the target, or the value of the "default_output_extension" value in the tool if the target does not specify an output extension.

    目标中 "output_extension "变量的值,如果目标没有指定输出扩展,则是工具中 "default_output_extension "的值。

    Example: ".so"


    Extra libraries from shared library dependencies not specified in the
    . This is the list of link_output files from shared libraries
    (if the solink tool specifies a "link_output" variable separate from
    the "depend_output").

    These should generally be treated the same as libs by your tool.

    Example: "libfoo.so libbar.so"


    Shared libraries packaged as framework bundle. This is principally
    used on Apple's platforms (macOS and iOS). All name must be ending
    with ".framework" suffix; the suffix will be stripped when expanding
     and each item will be preceded by "-framework".

The static library (“alink”) tool allows plus the common tool substitutions.

The copy tool allows the common compiler/linker substitutions, plus which is the source of the copy. The stamp tool allows only the common tool substitutions.

复制工具允许常见的编译器/链接器替换,加上,这是复制的源。stamp工具只允许常见的工具替换。

The copy_bundle_data and compile_xcassets tools only allows the common tool substitutions. Both tools are required to create iOS/macOS bundles and need only be defined on those platforms.

copy_bundle_data和compile_xcassets工具只允许常用的工具替换。这两个工具都是创建iOS/MacOS捆绑包所需要的,只需要在这些平台上定义。

The copy_bundle_data tool will be called with one source and needs to copy (optionally optimizing the data representation) to its output. It may be called with a directory as input and it needs to be recursively copied.

The compile_xcassets tool will be called with one or more source (each an asset catalog) that needs to be compiled to a single output. The following substitutions are available:

    Expands to the list of .xcassets to use as input to compile the asset catalog.


    Expands to the product_type of the bundle that will contain the
    compiled asset catalog. Usually corresponds to the product_type
    property of the corresponding create_bundle target.


    Expands to the path to the partial Info.plist generated by the
    assets catalog compiler. Usually based on the target_name of
    the create_bundle target.

Rust tools have the notion of a single input and a single output, along with a set of compiler-specific flags. The following expansions are available:

    Expands to the string representing the crate name of target under
    compilation.


    Expands to the string representing the type of crate for the target
    under compilation.


    Expands to the list of --extern flags needed to include addition Rust
    libraries in this target. Includes any specified renamed dependencies.


    Expands to the list of -Ldependency=<path> strings needed to compile
    this target.


    Expands to the list of environment variables.


    Expands to the list of strings representing Rust compiler flags.

Separate linking and dependencies for shared libraries

共享库的单独链接和依赖关系

Shared libraries are special in that not all changes to them require that dependent targets be re-linked. If the shared library is changed but no imports or exports are different, dependent code needn’t be relinked, which can speed up the build.

共享库的特殊之处在于,并非所有对共享库的修改都需要重新链接依赖的目标。如果共享库被改变了,但没有进口或出口的变化,依赖的代码就不需要重新链接,这可以加快构建速度。

If your link step can output a list of exports from a shared library and writes the file only if the new one is different, the timestamp of this file can be used for triggering re-links, while the actual shared library would be used for linking.

如果你的链接步骤可以从共享库中输出一个导出的列表,并且只在新的共享库不同的情况下写入文件,那么这个文件的时间戳就可以用来触发重新链接,而实际的共享库将被用来链接。

You will need to specify restat = true in the linker tool to make this work, so Ninja will detect if the timestamp of the dependency file has changed after linking (otherwise it will always assume that running a command updates the output):

在链接器工具中,为了使其发挥作用,所以Ninja会在链接后检测依赖文件的时间戳是否有变化(否则它总是认为运行一个命令会更新输出)。

tool("solink") {
    command = "..."
    outputs = [
    "/",
    "/"
        ".TOC",
    ]
    link_output =
    "/"
    depend_output =
    "/"
        ".TOC"
    restat = true
}

Example

toolchain("my_toolchain") {
    # Put these at the top to apply to all tools below.
    # 把这些放在顶部适用于下面的所有工具
    lib_switch = "-l"
    lib_dir_switch = "-L"

    tool("cc") {
        command = "gcc  -o "
        outputs = [ "/.o" ]
        description = "GCC "
    }
    tool("cxx") {
        command = "g++  -o "
        outputs = [ "/.o" ]
        description = "G++ "
    }
};

dotfile

.gn file

When gn starts, it will search the current directory and parent directories for a file called “.gn”. This indicates the source root. You can override this detection by using the –root command-line argument

当gn启动时,它将在当前目录和父目录下搜索一个名为”.gn “的文件。这表示源根。你可以通过使用 –root 命令行参数来覆盖这一检测

The .gn file in the source root will be executed. The syntax is the same as a buildfile, but with very limited build setup-specific meaning.

源根中的.gn文件将被执行。其语法与buildfile相同,但具有非常有限的构建设置的特定含义。

If you specify –root, by default GN will look for the file .gn in that directory. If you want to specify a different file, you can additionally pass –dotfile:

如果你指定了–root,默认情况下GN会在该目录下寻找.gn文件。如果你想指定一个不同的文件,你可以另外传递–dotfile。

gn gen out/Debug --root=/home/build --dotfile=/home/my_gn_file.gn

Variables

  • arg_file_template [optional]

    Path to a file containing the text that should be used as the default args.gn content when you run gn args.

    当你运行gn args时,包含文本的文件应作为默认的args.gn内容,其路径。

  • buildconfig [required]

    Path to the build config file. This file will be used to set up the build file execution environment for each toolchain.

    构建配置文件的路径。这个文件将被用来为每个工具链设置构建文件的执行环境

  • check_targets [optional]

    A list of labels and label patterns that should be checked when running “gn check” or “gn gen –check”. If unspecified, all targets will be checked. If it is the empty list, no targets will be checked. To bypass this list, request an explicit check of targets, like “//*”.

    运行 “gn check “或 “gn gen –check “时应检查的标签和标签模式的列表。如果没有指定,所有目标都将被检查。如果它是空列表,则不会检查任何目标。要绕过这个列表,请要求明确检查目标,如”//*“。

    The format of this list is identical to that of “visibility” so see “gn help visibility” for examples.

    这个列表的格式与 “可见性 “的格式相同,所以请看 “gn help visibility “的例子。

  • check_system_includes [optional]

    Boolean to control whether system style includes are checked by default when running “gn check” or “gn gen –check”. System style includes are includes that use angle brackets <> instead of double quotes “”. If this setting is omitted or set to false, these includes will be ignored by default. They can be checked explicitly by running “gn check –check-system” or “gn gen –check=system”

    布尔值用于控制在运行 “gn check “或 “gn gen –check “时是否默认检查系统风格的包含。 系统风格包含是指使用角括号<>而不是双引号”“的包含。如果这个设置被省略或设置为false,这些内容将被默认忽略。可以通过运行 “gn check –check-system “或 “gn gen –check=system “来明确检查它们。

  • exec_script_whitelist [optional]

    A list of .gn/.gni files (not labels) that have permission to call the exec_script function. If this list is defined, calls to exec_script will be checked against this list and GN will fail if the current file isn’t in the list.

    有权限调用 exec_script 函数的 .gn/.gni 文件(不是标签)的列表。如果定义了这个列表,对exec_script的调用将根据这个列表进行检查,如果当前文件不在这个列表中,GN将失败。

    This is to allow the use of exec_script to be restricted since is easy to use inappropriately. Wildcards are not supported. Files in the secondary_source tree (if defined) should be referenced by ignoring the secondary tree and naming them as if they are in the main tree.

    If unspecified, the ability to call exec_script is unrestricted.

      Example:
          exec_script_whitelist = [
          "//base/BUILD.gn",
          "//build/my_config.gni",
          ]
    

    root [optional] Label of the root build target. The GN build will start by loading the build file containing this target name. This defaults to “//:” which will cause the file //BUILD.gn to be loaded.

    script_executable [optional] Path to specific Python executable or other interpreter to use in action targets and exec_script calls. By default GN searches the PATH for Python to execute these scripts.

    If set to the empty string, the path specified in action targets
    and exec_script calls will be executed directly.
    

    secondary_source [optional] Label of an alternate directory tree to find input files. When searching for a BUILD.gn file (or the build config file discussed above), the file will first be looked for in the source root. If it’s not found, the secondary source root will be checked (which would contain a parallel directory hierarchy).

    标签的替代目录树来寻找输入文件。当搜索BUILD.gn文件(或上面讨论的构建配置文件)时,将首先在源根中寻找该文件。如果没有找到,将检查次要的源根(它将包含一个平行的目录层次结构)。
    
    This behavior is intended to be used when BUILD.gn files can't be checked in to certain source directories for whatever reason.
    
    这种行为旨在用于BUILD.gn文件因某种原因无法进入某些源代码目录检查的情况
    
    The secondary source root must be inside the main source tree.
    

    default_args [optional] Scope containing the default overrides for declared arguments. These overrides take precedence over the default values specified in the declare_args() block, but can be overriden using –args or the args.gn file.

    包含声明参数的默认覆盖值的范围。这些覆盖值优先于 declare_args() 块中指定的默认值,但可以使用 --args 或 args.gn 文件来覆盖。
    
    This is intended to be used when subprojects declare arguments with default values that need to be changed for whatever reason.
    
    当子项目声明的参数具有默认值,但由于某种原因需要改变时,就可以使用这个方法。
    

Example .gn file contents

# 设置build文件的执行环境
buildconfig = "//build/config/BUILDCONFIG.gn"

check_targets = [
    "//doom_melon/*",  # Check everything in this subtree.
    "//tools:mind_controlling_ant",  # Check this specific target.
]

root = "//:root"

secondary_source = "//build/config/temporary_buildfiles/"

default_args = {
    # Default to release builds for this project.
    is_debug = false
    is_component_build = false
}

public_configs

Configs to be applied on dependents.

要应用在dependents的配置

A list of config labels.

Targets directly depending on this one will have the configs listed in this variable added to them. These configs will also apply to the current target. Generally, public configs are used to apply defines and include directories necessary to compile this target’s header files.

直接依赖于这个变量的目标将会将这个变量中列出的配置添加到它们中。这些配置也将应用于当前目标。通常,公共配置用于应用定义并包含编译此目标头文件所需的目录。

See also “gn help all_dependent_configs”.

Propagation of public configs

公共配置的传播

Public configs are applied to all targets that depend directly on this one. These dependant targets can further push this target’s public configs higher in the dependency tree by depending on it via public_deps (see “gn help public_deps”).

公共配置被应用于所有直接依赖这个目标的目标。 这些依赖的目标可以通过public_deps(见 “gn help public_deps”)进一步将这个目标的公共配置推到依赖树的更高位置。

static_library("toplevel") {
    # This target will get "my_config" applied to it. 
    # However, since this target uses "deps" and not "public_deps", 
    # targets that depend on this one won't get it.
    # 这个目标将得到my_config应用到它
    # 然而由于此目标使用deps而不是public_deps”,因此依赖于此目标的目标将无法获得它
    deps = [ ":intermediate" ]
}

static_library("intermediate") {
    # Depending on "lower" in any way will apply "my_config" to this target. Additionall, since this target depends on "lower" via public_deps, targets that depend on this one will also get "my_config".

    # 以任何方式依赖于lowermy_config应用到这个目标
    # 另外因为这个目标依赖于lower通过public_deps目标依赖于这个也会得到my_config”。
    public_deps = [ ":lower" ]
}

static_library("lower") {
    # This will get applied to all targets that depend on this one.
    # 这将应用于所有依赖于此的目标
    public_configs = [ ":my_config" ]
}

Public config propagation happens in a second phase once a target and all of its dependencies have been resolved. Therefore, a target will not see these force-added configs in their “configs” variable while the script is running, and they can not be removed. As a result, this capability should generally only be used to add defines and include directories rather than setting complicated flags that some targets may not want.

一旦解决了目标及其所有依赖项,公共配置传播将在第二个阶段发生。因此,当脚本运行时,目标不会在其“configs”变量中看到这些强制添加的配置,并且它们不能被删除。因此,这个功能通常应该只用于添加定义和包含目录,而不是设置一些目标可能不想要的复杂标志

Public configs may or may not be propagated across toolchain boundaries depending on the value of the propagates_configs flag (see “gn help toolchain”) on the toolchain of the target declaring the public_config.

Avoiding applying public configs to this target

避免将公共配置应用到此目标

If you want the config to apply to targets that depend on this one, but NOT this one, define an extra layer of indirection using a group:

如果你想要config应用于依赖于这个config的目标,而不是这个,使用一个组定义一个额外的间接层:

# External targets depend on this group.
group("my_target") {
    # Config to apply to all targets that depend on this one.
    # Config应用于所有依赖于此的目标
    public_configs = [ ":external_settings" ]
    deps = [ ":internal_target" ]
}

# Internal target to actually compile the sources.
# 内部目标,以实际编译源
static_library("internal_target") {
    # Force all external targets to depend on the group instead of directly on this so the "external_settings" config will get applied.
    # 强制所有外部目标依赖于组,而不是直接依赖于此,因此“external_settings”配置将被应用。
    visibility = [ ":my_target" ]
    ...
}

deps

Private linked dependencies.

A list of target labels

Specifies private dependencies of a target. Private dependencies are propagated up the dependency tree and linked to dependent targets, but do not grant the ability to include headers from the dependency. Public configs are not forwarded.

指定目标的私有依赖项。私有依赖项在依赖树中向上传播并链接到依赖的目标,但不授予包含依赖项头的能力。公共配置不转发

Details of dependency propagation

依赖性传播的详细信息

Source sets, shared libraries, and non-complete static libraries will be propagated up the dependency tree across groups, non-complete static libraries and source sets.

源集、共享库和非完整静态库将在依赖树中跨组、非完整静态库和源集向上传播。

Executables, shared libraries, and complete static libraries will link all propagated targets and stop propagation. Actions and copy steps also stop propagation, allowing them to take a library as an input but not force dependents to link to it.

可执行程序、共享库和完整的静态库将链接所有传播目标并停止传播。操作和复制步骤也会停止传播,允许它们接受一个库作为输入,但不强制依赖者链接它。

Propagation of all_dependent_configs and public_configs happens independently of target type. all_dependent_configs are always propagated across all types of targets, and public_configs are always propagated across public deps of all types of targets.

all_dependent_configs和public_configs的传播独立于目标类型。All_dependent_configs总是跨所有类型的目标传播,而public_configs总是跨所有类型的目标的公共部门传播。

Data dependencies are propagated differently. See “gn help data_deps” and “gn help runtime_deps”.

数据依赖性以不同的方式传播。请参见“gn help data_deps”和“gn help runtime_deps”。

See also “public_deps”.