积分300 / 贡献0

提问5答案被采纳4文章45

[经验分享] gn help 翻译 原创

润开鸿_闻飞 显示全部楼层 发表于 2024-5-17 14:04:53

itopen组织 1、提供OpenHarmony优雅实用的小工具 2、手把手适配riscv + qemu + linux的三方库移植 3、未来计划riscv + qemu + ohos的三方库移植 + 小程序开发 4、一切拥抱开源,拥抱国产化

gn help import

    import: 将文件导入到当前作用域。
    import命令将加载执行给定的文件的规则和变量进入当前作用域。
    按照惯例,导入的文件以.gni扩展名命名。
    导入不同于c++的“include”。导入的文件在来自导入命令调用者的独立环境执行。
    此执行的结果被缓存用于导入相同.gni文件的其他文件。
    不能导入一个在构建中使用的BUILD.gn文件。被导入文件的作用域会和在执行import命令的地方进行合并。如果被导入文件中的一些变量或者规则和当前作用域中有同样的变量或规则,仅仅值不相同,这就会产生冲突,从而在运行时报错。
    考虑以下划线'_'开头的变量和模板私有的,不会被导入。导入的文件可以使用这样的变量内部计算,不影响其他文件。

    Examples
    import("//build/rules/idl_compilation_rule.gni")
    import("my_vars.gni")

gn help declare_args

    declare_args: 声明构建参数。
    如果命令行或者工具链参数都没有指定值,那么就会用declare_args设置的默认值,这个默认值无法覆盖命令行的值。
    请参阅“gn help buildargs”以获得概述。
    declare args的精确行为是:
    1. declare_args()执行,那么在这个闭包({} 代码块之间)中定义的值都是可以读的,而在这个之前定义的值都不可以。
    2. 执行完这个块作用域,在里面设置的变量就会被保存,这些变量称之为"默认值"。一经保存,这些值就可以通过args.gn文件来重写。
    3. "gn args"可以重写默认值,在文件中的代码可以使用那些变量。

    在declare_args() { ... }这个块作用域中不用执行复杂的工作,因为这是设置默认值的,复杂的工作可能会被忽视。尤其是,不要用exec_script()去设置默认值,如果你想用脚本设置默认值,你应该在declare_args()这个块作用域之后再设置,而且应该是设置一些没被定义的值,比如 [],"",或者-1。
    因为你不能在同一个块作用域中读定义的变量,如果你想用一个被定义的默认值去定义另一个变量,那么你可以写两个declare_args() { ... } 块:

    declare_args ():

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

    Example

    declare_args() {
    enable_teleporter = true
    enable_doom_melon = false
    }

    如果你想覆盖(默认禁用)Doom Melon:  
    gn --args="enable_doom_melon=true enable_teleporter=true"
    这也设置传送器,但它已经默认为打开,所以它会没有效果。

gn help defined

返回ture如果所给的参数被定义了。

例子:

template("mytemplate") {

To help users call this template properly...

assert(defined(invoker.sources), "Sources must be defined")

# If we want to accept an optional "values" argument, we don't
# want to dereference something that may not be defined.
if (defined(invoker.values)) {
  values = invoker.values
} else {
  values = "some default value"
}

}

gn help exec_script

同步执行一个脚本,返回输出。

exec_script(filename, arguments = [], input_conversion = "", file_dependencies = [])

如果脚本不存在,返回非零错误码。 filename:

要执行的脚本名称,如果filename不是绝对路径,则会被当成相对于当前目录的路径。可以用rebase_path()改变路径,这个函数经常用到,只要你用文件了,可能就要用用它转换路径。

arguments:

作为参数传递给脚本。可以为空,表示没有参数。

input_conversion:

控制文件如何读取或者解析。可以查看io_conversion的帮助。(gn help io_conversion)

file_dependencies(可选的):

脚本读取或者依赖的一个文件列表,这些依赖会被添加到构建结果中,如果这些依赖有改变,构建就会重新生成,脚本也会再运行。

例子:

all_lines = exec_script( "myscript.py", [some_input], "list lines", [ rebase_path("data_file.txt", root_build_dir) ])

This example just calls the script with no arguments and discards the

result.

exec_script("//foo/bar/myscript.py")

gn help exec_script

exec_script: 同步执行一个脚本并返回输出。
    exec_script(filename,
    arguments = [],
    input_conversion = "",
    file_dependencies = [])

    运行给定的脚本,返回脚本的标准输出。如果脚本不存在或返回一个非零退出,生成将失败代码。
    执行脚本时的当前目录将是根构建。如果要传递文件名,则需要使用
    Rebase_path()函数创建与此路径相关的文件名(参见“gn help rebase_path”)。
    默认的脚本解释器是Python 

    Arguments:
    filename:
    要执行的脚本的文件名。非绝对名称将被视为相对于当前目录的路径。

    arguments:
    要作为参数传递给脚本的字符串列表。可以是未指定或空列表,这意味着没有参数。

    input_conversion:
    控制如何读取和解析文件。请参见“gn help io_conversion”。

        “”(默认)
                input:放弃结果并返回None。
                output:如果value是一个列表,那么“列表行”;否则“value”。

        "list lines"
                input:
                以列表的形式返回文件内容,每行使用一个字符串。的换行符不会出现在结果中。最后一不要以换行符结束。
                拆分后,每个单独的行将在上面修剪空白两端。

                output:
                将值内容呈现为列表,每行使用一个字符串。的换行符不会出现在结果中。最后一行将以换行符。

        “scope”
                input:
                将代码块作为GN代码执行,并返回一个带有结果的作用域值。如果输入为:
                a = [ "hello.cc", "world.cc" ]
                b = 26
                然后你将结果读入一个名为val的变量,然后你就可以在val上访问"."操作符:
                sources = val.a
                some_count = val.b

                output:
                将值内容呈现为GN代码块,反转输入上面的结果。

        “字符串”
                input:将文件内容返回到单个字符串中。

                output:
                将值内容呈现为单个字符串。
                输出是:
                用引号呈现的字符串,例如。“power”  
                整数呈现为字符串化的整数,例如。“6”
                一个布尔值呈现为相关的字符串,例如。“true”
                列表呈现为其内容的表示形式,例如。“(\“str \”,6)”
                将作用域呈现为其值的GN代码块。

                如果Value为:值val;
                val.a = [ "hello.cc", "world.cc" ];
                val.b = 26
                输出结果:
                "{
                a = [ \"hello.cc\", \"world.cc\" ]
                b = 26
                }"


        “value”
                input:
                把输入当作构建文件中的右值来解析。
                使用此模式的典型程序输出的列子:
                        ["foo", "bar"]            (结果将是一个列表)
                        foo bar                    (result将是一个字符串)
                        5                          (结果将是一个整数)
                注意,如果输入是空的,结果将是一个空值将产生一个错误
                output:
                将值内容呈现为文字右值。字符串没有引号呈现。

        “json”
                input:将输入解析为JSON,并将其转换为等价的GN右值。
                output:将Value转换为等效的JSON值。
                数据类型映射为:
                JSON中的字符串映射到GN中的字符串
                JSON中的整数映射到GN中的整数
                不支持JSON中的浮点数,将导致错误
                JSON中的对象映射到GN中的作用域
                JSON中的数组映射到GN中的列表
                JSON中的布尔映射到GN中的布尔
                JSON中不支持null,将导致错误
                输入字典键必须是有效的GN标识符
                否则它们将产生一个错误。

        “trim……”(输入)
                处理前在任何其他转换前面加上“trim”will导致空格从开始和结束被修剪结果。
                例如:“修剪字符串”或“修剪列表行”,注意:“修剪值”是没有用的,因为值解析器会跳过空格。

    file_dependencies(可选的):

    脚本读取或者依赖的一个文件列表,这些依赖会被添加到构建结果中,如果这些依赖有改变,构建就会重新生成,脚本也会再运行。
    脚本本身是一个隐式依赖项
    Example
        all_lines = exec_script("myscript.py", [some_input], "list lines",[ rebase_path("data_file.txt", root_build_dir) ])
        #这个例子只是调用没有参数的脚本并丢弃
        # result.
        exec_script("//foo/bar/myscript.py")

gn help rebase_path

rebase_path:  把一个文件或者目录相对于另一个位置进行路径转换。
    converted = rebase_path(input,
              new_base = "",
              current_base = ".")

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

        new_base
          如果这个值是空的(默认值),那么所有路径都会转换为系统绝对路径(路径的格式取决于本地风格,windows风格?Linux风格?),这个对于调用外部程序是有用的。

        current_base
    表示输入中相对路径的基的目录,也就是输入的文件或者目录名字目前是基于<current_base>而找到的。
    如果不是绝对路径,它就会被当作相对于当前build文件而言。使用"."(默认值)从当前build文件目录去转换路径。
返回值类型和输入类型一样,要么是字符串,要么是字符串列表。所有相对和源绝对路径文件名都将被转换成相对于所请求的不会改变的输出系统绝对路径。

输入路径末尾有没有斜杠取决于输入的时候有还是没有,如果输入的时候路径末尾没有"/",那么输出的文件路径也不会有;如果输入的时候末尾有"/",那么输出的文件路径末尾也会有"/"。

Return value 返回值的类型将与输入值相同(可以是字符串或字符串列表)。所有的相对源,绝对文件名系统绝对路径将被转换为相对于请求的输出 输出路径是否以斜杠结尾将匹配对应的输入路径以斜杠结尾。它将返回"."或"./"(取决于输入是否以斜杠结尾)以避免返回空 字符串。这意味着如果您希望根路径("//"或"/")不是以斜杠,你可以添加一个点("//.")。

    Example

            #将当前目录中的文件转换为与build相关的文件
            #目录(执行编译器和脚本时的当前目录)。
            foo = rebase_path("myfile.txt", root_build_dir)
            可能会生成“../../project/myfile.txt”。
            将文件转换为系统绝对文件:
            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") {
            #可能在Windows上生成“D:\\source\\project\\myfile.txt”
            # "/home/you/source/project/myfile.txt"
            转换到脚本的构建目录的典型用法。
            sources = [ "foo.txt", "bar.txt" ]

            手动传递的额外文件参数需要显式转换
            相对于构建目录:
            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)
            }

gn help assert

    assert: 在生成时断言一个表达式为真。与C语言assert一样。

    assert(<condition> [, <error string>])

    如果条件为false,构建将失败并出现错误。如果提供了可选的第二个参数,输出第二个参数的内容。

    Examples

    assert(is_win)
    assert(defined(sources), "Sources must be defined");

gn help string_join

string_join: 用分隔符连接字符串列表。
      result = string_join(separator, strings)

      将字符串列表与中间出现的分隔符连接起来。

    Examples

        string_join("", ["a", "b", "c"])    --> "abc"
        string_join("|", ["a", "b", "c"])   --> "a|b|c"
        string_join(", ", ["a", "b", "c"])  --> "a, b, c"
        string_join("s", ["", ""])          --> "s" 

gn help config

config:  声明一个config对象
    配置对象可以应用于目标并指定编译器集标志、头文件路径,变量或宏定义(defines)等等。

    这个配置可以像target一样通过它自己的标签来被引用。

    以如下顺序生成:一个用于应用configs的目标

    1. 使用本目标中直接被定义的值。
    2. 使用“configs”指定的配置。
    3. 根据Public_configs的指定,遍历依赖查找配置。
    4. 根据all_dependent_config的指定,遍历依赖查找配置。

    在配置定义中有效的变量

    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, swiftflags
    Nested configs: configs

    用于应用配置的目标上的变量

    all_dependent_configs, configs, public_configs

    Example

        config("myconfig") {
        include_dirs = [ "include/common" ]
        defines = [ "ENABLE_DOOM_MELON" ]
        }

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

Gn help cflags

cflags*:传递给C编译器的标志。字符串列表。
        “cflags”传递给C、c++、Objective C和客观的c++编译器。
        要分别瞄准这些变体中的一个,使用"cflags_c", "cflags_cc","cflags_objc"和"cflags_objcc"。这些variant-specific
        版本的cflags*将被附加在编译器命令行后面“cflags”。
        参见"asmflags"了解汇编语言文件的标志和"swiftflags"快速文件。
        标志和值的排序
        1. 那些设置在当前目标上(不是在配置中)。
        2. 在目标的"configs"上设置配置显示在列表中。
        3.这些设置在目标的“all_dependent_configs”上配置会出现在列表中。
        4. 在目标的"public_configs"上设置这些配置会出现在列表中。
        5. 从依赖项中提取的All_dependent_configs,顺序为“deps”列表。这是递归的。如果出现一个配置如果多次出现,则只使用第一个出现项。
        6. 从依赖项中提取的Public_configs,按“deps”列表。如果一个依赖项是公共的,它们将被应用递归。

gn help asmflags asmflags: 传递给汇编程序的标志。

    字符串列表。“asmflags”被传递给任何使用.asm或.S参数的工具调用 作为输入

    标志和值的排序

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

gn help executable

生成可执行文件目标。目标的生成要取决于这个目标中的源文件是用什么编程语言,一个目标不可以有多种编译语言,比如一个target可以包含C和C++源文件,但不可以有C和Rust源文件。

可用变量:

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, swiftflags 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

gn help generated_file

声明一个generated_file类型的目标。在解析式将数据写到磁盘。

这个目标类型反映了write_file()函数的一些功能,也具有从它的依赖中手机metadata的能力。

<outputs>变量表示输出到的文件名,它必须是一个包含单个元素的列表。

<output_conversion>变量表示写数据值的格式。

<contents>和<data_keys>必须被指定其中的一个,使用<data>就会把值的内容写到文件,而使用<data_keys>就会触发metadata的收集。

例子:

Given the following targets defined in //base/BUILD.gn, where A depends on B and B depends on C and D:

group("a") {
  metadata = {
    doom_melon = [ "enable" ]
    my_files = [ "foo.cpp" ]

    # Note: this is functionally equivalent to not defining `my_barrier`
    # at all in this target's metadata.
    my_barrier = [ "" ]
  }

  deps = [ ":b" ]
}

group("b") {
  metadata = {
    my_files = [ "bar.cpp" ]
    my_barrier = [ ":c" ]
  }

  deps = [ ":c", ":d" ]
}

group("c") {
  metadata = {
    doom_melon = [ "disable" ]
    my_files = [ "baz.cpp" ]
  }
}

group("d") {
  metadata = {
    my_files = [ "missing.cpp" ]
  }
}

If the following generated_file target is defined:

generated_file("my_files_metadata") {
  outputs = [ "$root_build_dir/my_files.json" ]
  data_keys = [ "my_files" ]

  deps = [ "//base:a" ]
}

The following will be written to "$root_build_dir/my_files.json" (less the comments): [ "baz.cpp", // from //base:c via //base:b "missing.cpp" // from //base:d via //base:b "bar.cpp", // from //base:b via //base:a "foo.cpp", // from //base:a ]

Alternatively, as an example of using walk_keys, if the following generated_file target is defined:

generated_file("my_files_metadata") { outputs = [ "$root_build_dir/my_files.json" ] data_keys = [ "my_files" ] walk_keys = [ "my_barrier" ]

deps = [ "//base:a" ]

}

The following will be written to "$root_build_dir/my_files.json" (again less the comments): [ "baz.cpp", // from //base:c via //base:b "bar.cpp", // from //base:b via //base:a "foo.cpp", // from //base:a ]

If rebase is used in the following generated_file target:

generated_file("my_files_metadata") { outputs = [ "$root_build_dir/my_files.json" ] data_keys = [ "my_files" ] walk_keys = [ "my_barrier" ] rebase = root_build_dir

deps = [ "//base:a" ]

}

The following will be written to "$root_build_dir/my_files.json" (again less the comments) (assuming root_build_dir = "//out"): [ "../base/baz.cpp", // from //base:c via //base:b "../base/bar.cpp", // from //base:b via //base:a "../base/foo.cpp", // from //base:a ] 变量:

contents data_keys rebase walk_keys output_conversion Deps: data_deps, deps, public_deps Dependent configs: all_dependent_configs, public_configs

gn help copy

copy: 声明一个复制文件的目标
    File name handling

    所有输出文件必须位于构建的输出目录中。
    你会通常使用|$target_out_dir|或|$target_gen_dir|,这两个分别生成目标的最终目录以及生成的中间文件目录。

    “source”和“output”都必须指定。source可以包括尽可能多的文件,但在输出列表中只能有一个项

    如果有多个文件输入,那么就要用源扩展。(可以查看sources_expansion用法)
可以看看占位符"{undefined{source_name_part}}"的用法。

    Examples

            # 编写将签入DLL复制到输出目录的规则。
            copy("mydll") {
            sources = [ "mydll.dll" ]
            outputs = [ "$target_out_dir/mydll.dll" ]
            }

            # 编写一条规则,将多个文件复制到目标生成的文件目录中。
            copy("myfiles") {
            sources = [ "data1.dat", "data2.dat", "data3.dat" ]

            #使用源展开生成对应文件的输出文件 在gen目录中的#名称。这只会复制每个文件
            outputs = [ "$target_gen_dir/{{source_file_part}}" ]
            }

gn help group

group:声明一组的目标。
         此目标类型允许您创建元目标,它只将一组依赖项收集到一个命名的目标中。组还可以指定适用于其依赖项的配置。
        变量
        Deps: data_deps, Deps, public_deps
        Dependent:all_dependent_configs, public_configs
        例子
        group("all") {
            deps = [
              "//project:runner",
              "//project:unit_tests",
            ]

gn help shared_library

声明一个共享库目标。Linux平台会生成一个.so文件,也就是动态库。

变量:

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, swiftflags 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

gn help source_set

声明一个源集类型目标。目前只支持C语言的源集。(也就是类C风格,比如C,C++)

变量:

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, swiftflags 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

gn help static_library

生成一个静态库。

变量:

complete_static_lib 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, swiftflags 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

gn help target

target:使用给定的类型声明目标。
        Target (target_type_string, target_name_string){…}
        函数的作用是调用内置的目标或模板在运行时确定的类型。
        控件只支持模板和内置目标函数target_type_string参数。
        example:
        target (“source_set”、“doom_melon”){
        等价于:
        source_set (doom_melon) {
        例子
        if (foo_build_as_shared) {
        my_type = " shared_library "
        else}{
        my_type = " source_set "
        }
        target(my_type,“foo”){
        ...
        }

gn help forward_variables_from

forward_variable_from:从不同的作用域复制变量。
    forward_variables_from (from_scope variable_list_or_star,variable_to_not_forward_list = [])

from_scope:
    给定的作用域。 也就是将从这个作用域中拷贝变量。
variable_list_or_star:
    要拷贝的变量列表。可以给定一个变量(variable)列表,或者给定一个星号(*)。
将给定的变量从给定的作用域复制到局部作用域存在。
variable_to_not_forward_list:
    不拷贝的变量列表。当 "variable_list_or_star" 设置为 "*" 的时候这个很有用。

从给定的作用域将变量拷贝到当前作用域中如果变量存在。(这个用法在<template>中很常用)
如果要拷贝的变量没有找到,那就在当前作用域中把该变量当作未定义处理。
"*"会拷贝在给定的作用域定义的变量,不在里面直接定义的不包括。
如果要拷贝的变量在当前作用域已经存在了,那就会出错。
如果要拷贝的变量是"*",那么当前作用域的变量就会被废掉,也就是使用给定作用域的变量。
如果你想自己也定义变量呢? 可以判断给定作用域的变量是否存在,如果存在就用 "+=" 来添加,不存在就直接为当前作用域的变量定义。(可以看一些例子就是这样)

forward_variables_from(invoker(" foo "))

等价于:

assert(!defined(foo)) if(defined(invoker.foo)) { foo = invoker.foo }

这是一个常见的动作模板。它将调用一个给定的脚本

参数,并希望使用各种类型的deps和可见性

如果已经定义,则从调用者中获取#。它还注入了一个额外的依赖项

指向所有目标。

template(“my_test”){ action(target_name) { forward_variable_from (invoker, ["data_deps", "deps", “public_deps”、“visibility”) 添加我们的测试代码到依赖项。

"deps"可能在这里定义,也可能没有定义。

if(defined(deps)) { Deps += ["//tools/doom_melon"] 其他}{ Deps = ["//tools/doom_melon"] } } } 这是一个围绕目标的模板,目标的类型依赖于一个全局变量。

它从调用者转发所有值。

template("my_wrapper") { target(my_wrapper_target_type, target_name) { forward_variables_from(invoker, "*") } } 包装另一个模板。它在此基础上添加行为

变量,并将所有其他内容转发给嵌套的目标。

template("my_ios_test_app") {     ios_test_app(target_name) {       forward_variables_from(invoker, "*", ["test_bundle_name"])       if (!defined(extra_substitutions)) {         extra_substitutions = []       }       extra_substitutions += [ "BUNDLE_ID_TEST_NAME=$test_bundle_name" ]     }   }

        extra_substitutions += ["BUNDLE_ID_TEST_NAME=$test_bundle_name"]
        }
        }

gn help template

模板定义了一个自定义名称,其作用类似于函数。
        example
            template(“my_idl”){
        通过检查变量来帮助调用者调试问题。
        #你也可以使用define()给变量默认值,由调用者指定。
        assert(defined(invoker.sources),"Need sources in $target_name listing the idl files.")

        #执行gen代码的中间目标的名称合并目标名称,使其在模板中是唯一的
        Code_gen_target_name = target_name + "_code_gen"

        #中间目标转换IDL到C源代码。注意,名称是基于模板调用者指定的名称。
        这样,当模板被调用时,我们得到一个唯一的中间操作名称(因为所有目标名称都在全局作用域中)。
        action_foreach (code_gen_target_name) {

        #通过隐式的“invoker”访问调用者定义的范围,变量。
        sources = invoker.sources

        #注意,我们需要一个脚本文件名的绝对路径。执行此代码时,当前目录将是调用者的目录,
        这就是为什么我们可以直接使用上面的“资源”而不需要rebase所有路径)。
        但是如果我们需要引用一个脚本在模板文件中,我们需要使用绝对路径。
        script = "//tools/idl/idl_code_generator.py"

        #告诉GN如何扩展给定源的输出名称。#查看“gn help source_expansion”了解更多信息。
        outputs = [ "$target_gen_dir/{{source_name_part}}.cc",
                          "$target_gen_dir/{{source_name_part}}.h" ]
        }

            #将源设置命名为与模板调用相同的名称这个模板生成了其他目标可以链接到的东西
            # deps。
        source_set (target_name) {

            #生成源列表,我们从action_foreach中得到这些
        sources = get_target_outputs(":$code_gen_target_name")

            这个目标依赖于上面代码生成的文件。
        deps = [":$code_gen_target_name"]
        }
        }

gn help action

action: 声明一个只运行一次脚本的目标。
    允许运行一次脚本生成一个或多个的输出文件。
    如果想每个文件都执行一次脚本,使用action_foreach”。  
    Inputs
          在<action>中"sources"和"inputs"效果一样。如果你想把"sources"传递给脚本,你需要在"args"中包含它。
        由于没有对路径进行处理,GN不知道哪些参数是路径,哪些参数不是路径,所以需要用rebase_path()函数对路径进行处理,这个函数可以将路径转换成相对于root_build_dir(当前命令执行的路径)的路径。  
        如果命令行的参数太长,你可以用响应文件(response file)来传递参数给你的脚本。(查看 gn help response_file_contents的用法)

         推荐你把要传给脚本的输入放在"sources"变量中,而需要运行你这个脚本的其它python文件放在"inputs"变量中。

    因为<deps>和<public_deps>总是在<action>执行之前就完成,所以<action>可以依赖前面步骤所输出的东西作为依赖。

    GN可以为所有<action>命令设置ninja的"restat"的标志,将其设置为"restat = 1",那么ninja就会在<action>执行完成后检查输出(文件或别的什么)的时间戳,如果这个时间戳不变,那就意味着不需要重新构建相关的东西,这样也减少了不必要的构建。

Outputs <outputs> 可以指定脚本输出的名字。

        File name handling
            所有输出文件必须位于构建的输出目录中。  您通常会使用|$target_out_dir|或|$target_gen_dir| to  引用输出或生成的中间文件目录。  

        Variables
        args, data, data_deps, depfile, deps, inputs, metadata, outputs*, pool,
        response_file_contents, description, script*, sources
        * = required

    Example

        action("run_this_guy_once") {
        script = "doprocessing.py"
        sources = [ "my_configuration.txt" ]
        outputs = [ "$target_gen_dir/insightful_output.txt" ]

        # 我们的脚本导入了这个Python文件,所以我们想要在它发生变化时重新构建它。  
        inputs = [ "helper_library.py" ]

        #注意,我们必须手动将源代码传递给脚本  #脚本需要它们作为输入。  
        args = [ "--out", rebase_path(target_gen_dir, root_build_dir) ] +
        rebase_path(sources, root_build_dir)
        }

gn help action_foreach

遍历<sources>中的文件,每个文件都会执行一次脚本。

如果你有额外的数据需要传给脚本,比如一个共享配置或者一个python脚本,你应该把它放入<inputs>变量。

{undefined{source_name_part}} 是输入文件的名字,比如 "foo.idl"的名字就是"foo"

两个大括号 "{undefined{ }}" 表示的是占位符,可以了解一下GN中的占位符用法,有哪些占位符可以使用。

例子:

Runs the script over each IDL file. The IDL script will generate both a .cc

and a .h file for each input.

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/{{source_name_part}}.h",
            "$target_gen_dir/{{source_name_part}}.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 = [
  "{{source}}",
  "-o",
  rebase_path(relative_target_gen_dir, root_build_dir) +
    "/{{source_name_part}}.h" ]

}

gn help foreach

foreach: 迭代一个列表。
    foreach(<loop_var>, <list>) {
    <loop contents>
    }
    对列表中的每个项执行循环内容块,并分配  依次循环_var到每个项。  
    该循环将遍历<list>的副本  所以在循环中改变它不会影响迭代。  
    循环变量将临时隐藏任何现有变量。循环结束后,变量将不再在范围内,而以前的值(如果有的话)在范围内将恢复。  

    Example
        mylist = [ "a", "b", "c" ]
        foreach(i, mylist) {
        print(i)
        }

        Prints:
        a
        b
        c

gn help dotfile

.gn file
    当gn启动时,它将搜索当前目录和父目录 对于一个名为“.gn”的文件。 这表示源根。
如果您想指定一个不同的文件,
    您可以另外通过  :
        gn gen out/Debug --root=/home/build --dotfile=/home/my_gn_file.gn
    Variables
      arg_file_template [optional]
          当运行gn args 文本路径作为默认参数使用
      buildconfig [required]
          构建配置文件的路径。 此文件将用于设置  为每个工具链构建文件执行环境。
check_targets [optional]
         运行时应该检查的标签和标签模式的列表  "gn check"或"gn gen——check"。 如果既不是check_targets也不是
指定了No_check_targets(见下面),将检查所有目标。  同时指定check_targets和no_check_targets是错误的。 如果它
是空列表,没有目标将被检查。 为了绕过这个列表,  请求一个明确的目标检查,比如"//*"。
  no_check_targets [optional]
     标签和标签模式的列表,当应该*不*检查  运行“gn check”或“gn gen——check”。 所有其他目标都会被检查。  
     如果既没有指定check_targets(参见上面)也没有指定no_check_targets,则所有  目标将被检查。 同时指定check_targets和是错误的   

  check_system_includes [optional]
      布尔值用于控制默认情况下是否检查系统样式包含  当运行"gn check"或"gn gen——check"时。 系统样式包括  
      包括用尖括号<>代替双引号""。 如果这  设置被省略或设置为false时,这些包含将被忽略  违约。 可以通过运行显式地检查它们  
      "gn check --check-system" or "gn gen --check=system"

  exec_script_whitelist [optional]
     一个.gn/的列表。 具有调用的权限的Gni文件(不是标签)  
    如果定义了这个列表,则调用exec_script  
    如果当前文件不是,则GN将失败 。  
    这是为了允许对exec_script的使用进行限制,因为它很容易 使用不当。 不支持通配符。  
      Example:
        exec_script_whitelist = [
          "//base/BUILD.gn",
          "//build/my_config.gni",
        ]

      root [optional]
         根构建目标的标签。 GN将构建包含此目标名称的文件。  请注意,build_file_extension 也适用于默认情况。  
      script_executable [optional]
         中使用的特定Python可执行文件或其他解释器的路径  操作目标和exec_script调用。 
        如果设置为空字符串,则操作目标中指定的路径exec_script调用将直接执行。

        secondary_source [optional]
        用于查找输入文件的替代目录树的标签,build.gn文件(或上面讨论的构建配置文件),该文件  将首先在源根中查找。 如果没有找到,那么  
        将检查次要源根(其中将包含一个并行程序)  目录层次结构)。  

      default_args [optional]
         包含已声明实参的默认重写的范围。

      build_file_extension [optional]
         如果设置为非空字符串,则将其添加到所有构建文件的名称中加载。GN将查找名为“build .$build_file_extension.gn”的构建文件。  

      ninja_required_version [optional]
        设定时指定ninja所需的最低版本,默认的所需版本是1.7.2。 指定更高的版本可能会启用  使用一些更新的特性来提高构建的效率

    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
      }

gn help set_defaults

set_defaults: Set default values for a target type.
      set_defaults(<target_type_name>) { <values...> }
      设置给定目标类型的默认值。 所有定义这种类型的地方都会把默认值拷贝进去。

     当使用目标类型时,变量复制是非常严格的。 如果一个具有该名称的变量已经在作用域中,构建将失败错误。  

    Set_defaults可以用于内置的目标类型("可执行文件",  "shared_library"等)和通过"template"命令定义的自定义函数。  
    它可以被多次调用,并且在任何范围中最近的调用将被调用 应用,但无法引用以前的默认值并修改它们  
    每次调用set_defaults都必须提供一个包含所有默认值的完整列表  希望)。 如果您想共享默认值,请将它们存储在单独的变量中。  

    Example

      set_defaults("static_library") {
        configs = [ "//tools/mything:settings" ]
      }

      static_library("mylib") {
        # The configs will be auto-populated as above. You can remove it if
        # you don't want the default for a particular default:
        configs -= [ "//tools/mything:settings" ]
      }

gn help filter_exclude

filter_exclude(values, exclude_patterns)
        values:
        必须是一个字符串列表。

    exclude_patterns:

        用于匹配的文件模式列表。(也就是过滤规则)

    [values]这列表中的值,如果在[exclude_patterns]中可以匹配到,那么就要被过滤掉。

    也就是按照 [exclude_patterns] 的规则来筛选 [values] 里面的值。

    可以总结为: 匹配到就过滤。

    example:
              values = [ "foo.cc", "foo.h", "foo.proto" ]
              result = filter_exclude(values, [ "*.proto" ])
              # result will be [ "foo.cc", "foo.h" ]

gn help filter_include

filter_include(values, include_patterns)
        与<filter_exclude>作用相反。
    [values]这列表中的值,如果在[include_patterns]中可以匹配到,那么就要被保留。

    可以总结为: 匹配到就保留。

            例子:

              values = [ "foo.cc", "foo.h", "foo.proto" ]
              result = filter_include(values, [ "*.proto" ])
              # result will be [ "foo.proto" ]

gn help get_label_info

get_label_info(target_label, what) 给定一个目标的标签,返回那个目标的属性。

target_label:

目标标签。

[what] 可能的值:

"name":

    目标的名字。会匹配目标中定义的<target_name>变量。例如 对于 label "//foo/far:baz"将返回 "baz"

"dir":

    目标定义所在的目录。(末尾不带斜杠) 例如 对于 label "//foo/far:baz"将返回 "//foo/far"

"target_gen_dir":

    目标构建过程中生成的中间文件的路径。它会匹配目标声明的<target_gen_dir>变量。

"root_gen_dir":

    目标构建过程中生成的中间文件的根路径。它会匹配目标声明的<root_gen_dir>变量。

"target_out_dir":

    目标输出目录。它会匹配目标声明的<target_out_dir>变量。

"root_out_dir":

    目标输出的根目录。它会匹配目标声明的<root_out_dir>变量。

"label_no_toolchain":

    返回不包含工具链的标签。 例如 ":bar" 可能返回 "//foo:bar"

"label_with_toolchain":

    返回包含工具链的标签。 例如 ":bar" 可能返回 "//foo:bar(//toolchain:x64)"

    每个label后面都可以指定toolchain,用括号包含,这种是显式指定,那些没有括号的都是隐式指定采用默认的工具链。

"toolchain":

    匹配在该目标中声明的<current_toochain>变量。

例子:

get_label_info(":foo", "name")

Returns string "foo".

get_label_info("//foo/bar:baz", "target_gen_dir")

Returns string "//out/Debug/gen/foo/bar".

gn help get_path_info

get_path_info(input, what) input:

是一个文件或者目录名的字符串,或者是一个字符串列表。如果是一个列表,那么就会对列表中的每一项都处理,然后把结果以列表形式返回。

[what] 可能的值:

"file":

    返回路径最后一个斜杠后面的字符串。(包含名字和后缀)

    例如:

        "foo/bar.txt" => "bar.txt"

        "bar.txt" => "bar.txt" 

         "/" => ""

         "" => ""

"name":

    返回不包含后缀的文件名。

    例如:

        "foo/bar.txt" => "bar"

        "foo/bar" => "bar" 

         "foo/" => ""

"extension":

    返回最后一个斜杆后面的点后面的字符串。

    例如:

        "foo/bar.txt" => "txt"

        "foo/bar" => "" 

"dir":

    返回名字部分的目录,不包含斜杠。

    例如:

        "foo/bar.txt" => "foo"

        "//foo/bar" => "//foo" 

         "foo" => "."

"out_dir":

    返回与给定文件路径对应的输出文件目录,不包含末尾斜杠。

    例如:

        "//foo/bar/bar.txt" => "//out/Debug/obj/foo/bar"

"gen_dir":

    返回与给定文件路径对应的生成文件目录,不包含末尾斜杠。

    例如:

        "//foo/bar/bar.txt" => "//out/Debug/gen/foo/bar"

"abspath":

    返回一个全路径。

    如果输入的是绝对路径,那就把这个路径返回。

    如果输入的是相对路径,那么就转换为源绝对路径。(GN中把"//"开头成为源绝对路径,".gn"文件所在的路径)

    例如:

        "foo/bar.txt" => "//mydir/foo/bar.txt"

        "foo/" => "//mydir/foo/" 

         "//foo/bar" => "//foo/bar"  (已经是源绝对路径)

         "/usr/include" => "/usr/include"  (绝对路径)

如果想让路径相对于另一个路径,那就用 rebase_path()。

例子:

sources = [ "foo.cc", "foo.h" ] result = get_path_info(source, "abspath")

result will be [ "//mydir/foo.cc", "//mydir/foo.h" ]

result = get_path_info("//foo/bar/baz.cc", "dir")

result will be "//foo/bar"

Extract the source-absolute directory name,

result = get_path_info(get_path_info(path, "dir"), "abspath")

gn help get_target_outputs

get_target_outputs(target_label) 返回给定目标标签的输出文件列表。在这个函数调用之前,这个目标标签必须在这个文件中已经被定义了。

只有<copy>,<generated_file>,<action>这样的目标标签才被支持。

返回一个list,里面的路径都是源绝对路径(以"//"形式开头的路径)。

对于<copy>,<generated_file>,<action>这几个目标(target)标签,会返回他们在target中定义的<outputs>变量指定的文件。

例子:

Say this action generates a bunch of C source files.

action_foreach("my_action") { sources = [ ... ] outputs = [ ... ] }

Compile the resulting source files into a source set.

source_set("my_lib") { sources = get_target_outputs(":my_action") }

gn help getenv

value = getenv(env_var_name) 获取环境变量的值。(区分大小写)

例子:

home_dir = getenv("HOME")

not_needed: not_needed(variable_list_or_star, variable_to_ignore_list = []) not_needed(from_scope, variable_list_or_star, variable_to_ignore_list = []) 在当前作用域或者给定作用域中,将变量标记为“不需要的”,这样对于这样未被使用的变量就不会出错。

variable_list_or_star:

需要被标记的变量列表或者通配符 "*" 。

variable_to_ignore_list:

当第一个参数<variable_list_or_star>是通配符 "*" 时,<variable_to_ignore_list>可以将一些变量排除在外,不被标记为“不需要的”。

例子:

not_needed("", [ "config" ]) => 除了"config"不被标记,其它的都标记。 not_needed([ "data_deps", "deps" ]) => "data_deps"被标记。 not_needed(invoker, "", [ "config" ]) => 标记<invoker>作用域中所有变量,除了"config"。 not_needed(invoker, [ "data_deps", "deps" ]) => 标记<invoker>作用域中"data_deps"变量。

gn help pool

Pool 对象可以应用到一个可以限制构建并行性的工具上。

这个对象只有一个属性<depth>,它表示了可以同时运行的任务数量。

由于包含pool定义的文件可能会在多个工具链(toolchain)的上下文中执行,因此,当你在定义和引用一个pool对象的时候,推荐你显式的指定一个toolchain工具链。

在根构建文件中定义一个名为"console"的pool对象,这个对象就代表了Ninja的console pool。使用这个pool对象的目标(targets)都可以访问console的标准输入(stdin)和标准输出(stdout),这个特殊的pool必须有一个为1的depth值。

不是在root下面定义的pool对象不可以命名为"console"。

console pool 只能为默认的工具链(default_toolchain)定义。

pool对象可以像一个目标一样通过它自己的标签来被引用。

例子:

if (current_toolchain == default_toolchain) { pool("link_pool") { depth = 1 } }

toolchain("toolchain") { tool("link") { command = "..." pool = ":link_pool($default_toolchain)" } }

gn help print

打印到控制台上面显示。主要用于debug。

例子:

print("Hello world")

print(sources, deps)

gn help process_file_template

process_file_template(source_list, template) 用模板来处理文件。

source_list:

文件列表。

template:

模板列表。

返回结果就是每个模板处理的每个文件。

如果模板是一个列表,那么列表中的每个模板都会处理这个文件列表。也就是说,每个文件输入之后都会使用模板列表中的所有模板。

比较典型的用法就是根据输入文件来计算输出文件的名字。

与get_target_outputs()功能一样,在没有target或者target在别的构建文件中定义的时候就可以使用process_file_template()来处理。

模板可以使用源扩展(source expansion),用法查看 "gn help source_expansion"

例子:

sources = [ "foo.idl", "bar.idl", ] myoutputs = process_file_template( sources, [ "$target_gen_dir/{{source_name_part}}.cc", "$target_gen_dir/{{source_name_part}}.h" ])

The result in this case will be: [ "//out/Debug/foo.cc" "//out/Debug/foo.h" "//out/Debug/bar.cc" "//out/Debug/bar.h" ]

gn help read_file

read_file(filename, input_conversion) 把文件读入到一个变量中。如果文件不能打开就会出错。

filename:

要读的文件名称。

input_conversion:

控制文件怎么读和解析。

详解 gn help io_conversion

input_conversion / output_conversion 可能的值:

(

解释一下下面的用法,有的人可能看不太懂。就拿第二个用法来解释说明:

"list lines":

    input: 

    output: 

当<input>,也就是read_file中的<input_conversion>值为"list lines"时,对应的用法解释是 "input: "的内容。

当<output>,也就是write_file中的<output_conversion>值为"list lines"时,对应的用法解释是 "output: "的内容。

)

""(默认):

    input: 忽略结果,返回None。

    output: 如果值是一个列表就"list lines";否则 "value"。

"list lines":

    input: 

        把文件内容作为列表返回,每行用一个string字符串表示。新行不会在结果中展示。

        拆分好之后,把每行两端的空白字符去掉。

    output:

        把值的内容作为一个列表,每个string字符串为一行。新行不会在结果中展示。

        最后一行要以新行结尾。

"scope":

    input: 

        把这个块当作GN代码执行,将结果以scope的方式返回。

        如果输入是: a = ["hello.cc", "world.cc"]; b = 26

        把这个输入读到一个变量val中,那么就可以用"."的方式来读取内容:

        sources = val.a ; some_count = val.b

    output:  与上面相反。

"string":

    input: 将文件内容放到一个string字符串中。

    output: 

        将值的内容放进一个string字符串中。输出如下:

        字符串用双引号: "str"

        整数: "6"

        布尔值: "true"

        列表就显示内容: "[\"str\", 6]"

        区块:

            如果值是: Value val; val.a = ["hello.cc", "world.cc"]; val.b = 26

            输出就是: a = [\"hello.cc\", \"world.cc\"]; b = 26

"value":

    input: 

        输入 ["foo", "bar"] ,处理结果就是一个list列表。

        输入 "foo bar", 处理结果就是一个string字符串。

        输入 5,处理结果就是一个整数。

        如果输入是空的,那么就会把null赋值给变量,这就会出错。

    output: 把值内容作为文字形式的右值,字符串要转义双引号。

"json":

    input: 将输入当作JSON对象,把它转换成等价的GN右值。

    output: 将值转换成等价的JSON值。

    数据类型映射:

        JSON字符串 => GN字符串

        JOSN证书 => GN 整数

        JOSN浮点数 => GN不支持,会出错

        JOSN对象 =>GN 区块 (也就是{}形式)

        JOSN数组 => GN list表

        JOSN布尔 => GN布尔

        JOSN中的null => GN不支持,会出错误。

    注意:输入的值需要是GN支持的类型,不然就会出错。

"trim ..." (只输入):

    以"trim"为前缀的其它转换,在处理前都会被去掉空白字符。

    例如: "trim string" 或者 "trim list lines"

    "trim value"是没用的,因为value解析的时候会自动跳过空白字符

gn help set_default_toolchain

set_default_toolchain(toolchain_label) 设置默认的工具链。

toolchain_label:

用来识别工具链的标签,由toolchain("mytoolchain")指定。

所有的目标都会默认只用这个toolchain,除非有的目标指定了别的。

例子:

Set default toolchain only has an effect when run in the context of the

default toolchain. Pick the right one according to the current CPU

architecture.

if (target_cpu == "x64") { set_default_toolchain("//toolchains:64") } else if (target_cpu == "x86") { set_default_toolchain("//toolchains:32") }

gn help set_sources_assignment_filter

设置一个模式(pattern)来过滤源文件。

如果传递一个[]空模式,那么就不会过滤。

set_sources_assignment_filter([])会清除过滤模式。

例子:

Filter out all _win files.

set_sources_assignment_filter([ "_win.cc", "_win.h" ]) sources = [ "a.cc", "b_win.cc" ] print(sources)

Will print [ "a.cc" ]. b_win one was filtered out.

gn help split_list

result = split_list(input, n) 把一个列表分割到不同的子列表中。

n表示将input分割成几个子列表,分割时会让每个列表大小差不多。

如果n大于input列表里面的元素个数,那么会填充空列表。

例子:

The code: mylist = [1, 2, 3, 4, 5, 6] print(split_list(mylist, 3))

Will print: [[1, 2], [3, 4], [5, 6]

gn help string_replace

result = string_replace(str, old, new[, max]) 替换所给字符串中的子字符串。

例子:

The code: mystr = "Hello, world!" print(string_replace(mystr, "world", "GN"))

Will print: Hello, GN!

gn help string_split

以指定分隔符将字符串分割到一个字符串列表中。

例子:

string_split("") --> [] string_split("a") --> ["a"] string_split(" aa bb") --> ["aa", "bb"] string_split("", "|") --> [""] string_split(" a b ", " ") --> ["", "", "a", "b", "", ""] string_split("aa+-bb+-c", "+-") --> ["aa", "bb", "c"]

gn help toolchain

定义一个工具链。

工具链是一个用来编译源代码的命令和构建标志的集合。toolchaind()函数可以定义这些命令。

函数和变量:

tool():

    这个函数调用指定为给定步骤运行的命令。使用方面看上面 ↑

toolchain_args[scope]:

    调用工具链时覆盖要传递给工具链的构建参数。这是一个"scope"类型的变量,里面的变量名要和declare_args()中相对应。

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

    任何默认的系统参数或通过“gn args”传入的参数也将被传递给备用调用,除非被toolchain_args显式覆盖。

    当工具链被定义为默认的时候,toolchain_args就会被忽略。

propagates_configs [boolean, default=false]:

    确定这个工具链中的public_configs和all_dependent_configs是否传播到其他工具链中的目标。false, 不能传;true,可以传。

deps[string list]:

    这个工具链的依赖。在任何使用这个工具链编译的目标之前,依赖都会被解决。为了避免循环依赖,这些必须是在另一个工具链中定义的目标。

    这是一个目标列表,通常这些目标会指定一个工具链:

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

工具链定义实例:

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

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

}

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

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

} 交叉工具链依赖实例:

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

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") {
    ...
  }
}    

gn help write_file

write_file(filename, data, output_conversion = "") 写一个文件到磁盘。

filename: 要写的文件名。

data:要写的数据。

output_conversion: 写入的方式。 查看上面read_file里面关于 io_conversion详解。

gn help check_includes

是个布尔值。

false:不检查目标中的文件。(#include 引入的文件)

true: 检查目标中的文件。

例子:

source_set("busted_includes") {

This target's includes are messed up, exclude it from checking.

check_includes = false
    ...
}

gn help data

运行时数据文件依赖。

data_deps: Non-linked dependencies. 通常使用是为了plugins或者目标在运行时需要用到的helper程序。

例子:

executable("foo") { deps = [ "//base" ] data_deps = [ "//plugins:my_runtime_plugin" ] } data_keys: Keys from which to collect metadata.

gn help defines

定义的变量会被C编译器使用,类似于C语言的#defines。

可以为C/C++文件定义宏,如果有需要可以用"="为变量赋值。

例如:

defines = [ "AWESOME_FEATURE", "LOG_LEVEL=3" ] depfile: [string] File name for input dependencies for actions. 为<action> <action_foreach>使用,这两个行为的输入项的依赖项。

<action> 或者 <action_foreach>会生成 ".d" 后缀的文件,这个文件包含了输入项的依赖项。

文件的格式就是makefile的格式。

例子:

action_foreach("myscript_target") { script = "myscript.py" sources = [ ... ]

# Locate the depfile in the output directory named like the
# inputs but with a ".d" appended.
depfile = "$relative_target_output_dir/{{source_name}}.d"

# Say our script uses "-o <d file>" to indicate the depfile.
args = [ "{{source}}", "-o", depfile ]

}

gn help deps

私有依赖 不能从依赖中#include头文件,公开配置也无法被传递。

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.

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

See also "public_deps".

gn help friend

允许目标包含私有头文件 正常情况,当一个目标中把一些头文件放进了 "public"列表里,那么其余的头文件就被隐性的认为是私有的(private),而其它目标是不可以包含私有头文件的,即使你是公共继承的。

<friend>的声明就可以让一个或者多个目标包含私有头文件。

而没有依赖关系的目标依旧是不可以包含私有头文件的。

<friend>无法在依赖直接被传递,也不影响<visibility>。

例子:

static_library("lib") {

This target can include our private headers.

friend = [ ":unit_tests" ]

public = [
  "public_api.h",  # Normal public API for dependent targets.
]

# Private API and sources.
sources = [
  "a_source_file.cc",

  # Normal targets that depend on this one won't be able to include this
  # because this target defines a list of "public" headers. Without the
  # "public" list, all headers are implicitly public.
  "private_api.h",
]

}

executable("unit_tests") { sources = [

This can include "private_api.h" from the :lib target because it

depends on that target and because of the friend annotation.

"my_test.cc", ]

deps = [
  ":lib",  # Required for the include to be allowed.
]

}

gn help include_dirs

目标引用头文件的搜索路径。会在这写目录下面查找要使用的头文件。

例子:

include_dirs = [ "src/include", "//third_party/foo" ]

gn help ldflags

传给链接器的标志 大部分目标不需要使用这个,相反地,会使用<libs> 和 <lib_dirs>。

<lfflags>不会被推给依赖项,因此把这个标志传递给<source_set>和<static_library>是不可行的。

如果你想把这个标志传递给依赖项,你可以把它放在<config>中,然后把<config>放入<all_dependent_configs> 或者<public_configs>中。

lib_dirs: 用于链接器搜索所需要的库的路径。

如果不是绝对路径,那么就会被转换成相对于当前build文件的路径。

例子:

lib_dirs = [ "/usr/lib/foo", "lib/doom_melon" ] libs: 其它要链接的库。

<libs>的类型:

文件路径:

    包含"/"的值将被当作对文件的引用。

    那些在构建中生成的库,就用GN的依赖方式来使用它们。

系统库:

    不包含"/"的值会被当作系统库名字。这些值会不做任何修改与"lib_switch"属性作为前缀直接传给链接器。

    通常你要设置<lib_dirs>为了这些库可以被找到。

    在你的BUILD.gn文件中不应该指定switch(像"-l"这样的): 这将被编码在<tool>的<lib_switch>中。

例子:

On Windows: libs = [ "ctl3d.lib" ]

On Linux: libs = [ "ld" ]

gn help output_dir

要放入输出文件的目录。

最后的输出通常会在<root_out_dir>或者其子目录下。

如果这个变量未定义或者是空值,那么就会使用默认的位置。

一般toolchain都会为库和可执行文件指定好输出目录。

例子:

shared_library("doom_melon") { output_dir = "$root_out_dir/plugin_libs" ... }

gn help output_extension

输出文件的扩展名。

通常情况下,一个目标的扩展名取决于目标的类型和操作系统,但是极少情况下你需要重写这个扩展名。

比如在Linux系统上,用 "libfreetype.so.6"代替 "libfreetype.so"

这个值不应该以"."开头。如果未定义,那么就会使用<tool>定义的默认值。如果设置成空,就表示没有扩展名要用。

这个变量值将会用来设置"{undefined{output_extension}}"。

例子:

shared_library("freetype") { if (is_linux) {

Call the output "libfreetype.so.6"

output_extension = "so.6" } ... }

On Windows, generate a "mysettings.cpl" control panel applet. Control panel

applets are actually special shared libraries.

if (is_win) { shared_library("mysettings") { output_extension = "cpl" ... } }

gn help output_prefix_override

不要为输出名称使用前缀。布尔值,默认是false。

一些系统会为最终输出的文件加上前缀。例如Linux系统上面,目标名为"foo",生成"libfoo.so"

给定目标类型的前缀是由链接器工具指定的。有时候这个前缀是不被渴望出现的。

例子:

shared_library("doom_melon") {

//Normally this will produce "libdoom_melon.so" on Linux. Setting this flag

//will produce "doom_melon.so".

output_prefix_override = true
    ...
}

gn help public

为目标声明公共头文件。

其它目标可以#include的文件列表。这些允许被检查(查看gn help check)。

如果没有<public>被声明,那么其它目标都可以#include当前目标<sources>中的文件(前提是visibility,可以查看<visibility>用法)。如果这个变量被定义了,那么其它目标就只能#include它指定的文件,除非依赖项被标记为"friend"。(查看<friend>用法)

头文件权限也受可见性(<visibility>)的影响。一个目标必须对另一个目标是可见,那个目标才能包括当前目标中的任意文件,而<public>只是指定了当前目标中的哪些文件可以被引用。

而public的文件是可以通过依赖关系传递的。因此,如果有这样一个依赖关系 A -> B -> C,然后A可以包含C的公开头文件。但是,对于可见性来说,情况并非如此,因此,除非A在C的可见性列表中,否则引用将被拒绝。

GN只认识在目标的<sources>和<public>部分声明的文件。如果include了构建不知道的文件,那么它将被允许。

测试目标要引入私有头文件是很普遍的情况,对于这种情况,你想要include哪个目标的私有文件,那么你就在那个目标的<friend>列表中把测试目标列进去,这样测试目标就可以包含那个目标的私有文件了。

当一个二进制目标没有显式或者隐式的定义公开头文件时("public"列表定义了,但是空的),GN会假定这个目标不能沿着依赖树传递任何编译时依赖关系。在这种情况下,构建可以更有效地并行化。

假设有依赖关系:

A (shared library) -> B (shared library) -> C (action).

正常情况下,C需要在A中的任何源文件被编译前就要完成(因为可能会有<action>产生的文件被包含)。但是当B显式地声明没有公开头文件(public headers)时,那么C就可以和A的编译步骤同时并行执行。C仍然必须在任何依赖的链接之前完成。

例子:

These exact files are public: public = [ "foo.h", "bar.h" ]

No files are public (no targets may include headers from this one):
    // This allows starting compilation in dependent targets earlier.
    public = []

gn help public_configs

Configs to be applied on dependents.

这个变量中的配置将会被应用到直接依赖当前目标的目标上。当前目标同样会使用这个变量中声明的配置。

假如 A中声明了"public_configs",如果B继承了A(不管是私有继承(deps)还是公共继承(public_deps)),那么B中都会包含在A中声明的"public_configs"。接下来,如果C继承了B,如果是通过公共继承的方式,那么C中也会包含这个"public_configs",但是如果是私有继承就不会包含这个配置了。以此类推,可以D继承C,E继承D。

例子:

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.
  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".
  public_deps = [ ":lower" ]
}

static_library("lower") {
  # This will get applied to all targets that depend on this one.
  public_configs = [ ":my_config" ]
}

Avoiding applying public configs to this target: 如果你想把"public_configs"应用到依赖当前目标的目标上,但并不应用到当前目标上,使用组(<group>)定义额外的间接层:

# External targets depend on this group.
group("my_target") {
  # Config to apply to all targets that depend on this one.
  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.
  visibility = [ ":my_target" ]
  ...
}

gn hellp public_deps

声明公共依赖。

公共依赖类似于私有依赖(参见“gn help deps”),但是附加地表示当前目标将列出的deps作为其公共API的一部分公开。

如果有三个目标: A -> B -> C,C的可见性(<visibility>)允许B依赖它但不允许A,这样A就无法包括任何来自于A的头文件,而C的"public_configs"也只能用于B。

如果B的<public_deps>而不是<deps>把C放进去了,那么A就继承了C的"public_configs",也可以使用C中的头文件。

例子:

//This target can include files from "c" but not from

//"super_secret_implementation_details".

executable("a") { deps = [ ":b" ] }

shared_library("b") { deps = [ ":super_secret_implementation_details" ] public_deps = [ ":c" ] }

gn help sources

目标的源文件。

Sources for binary targets:

对于二进制目标(如source sets, executables, and libraries),这些已知文件的类型会用相关的工具来编译。而未知的文件类型和头文件会被跳过。但是,你仍然应该列出C/C++的头文件,所以GN知道这些文件的存在就是是为了文件引入检查(include check,可以查看 gn help check,检查头文件的引入合法性)的目的。

特殊情况,以".def"为后缀的文件会被当作Windows module 定义文件,在".def"文件前面加上"/DEF:",然后再被追加给链接行。例如: "/DEF:test.def"

目标中最多只能有一个.def文件,而且它们不跨越依赖边界(因此在静态库或源集中指定.def文件对它们链接到的可执行文件或共享库没有影响)。

Sources for non-binary targets(对于非二进制的目标):

<action_foreach>

    "sources"就是脚本要遍历执行的输入项,"sources"中的每个文件都会执行一次脚本。

<action>

    "sources"和"inputs"一样。可以查看 "gn help inputs"。

<copy>

    "sources"就是要拷贝的文件。

gn help testonly

声明的目标只能用于测试。

默认值时false。

如果一个目标中定义了"testonly = true",那么这个目标就只能依赖那些同样定义了"testonly = true"的目标。否则,GN就会出现一个依赖不允许的错误。

这个特性的目的是防止在最终产品中把测试代码错误性地交付出去。

例子:

source_set("test_support") { testonly = true ... } visibility: A list of labels that can depend on a target. 如果这个变量未被定义,则默认就是公开的,也就是所有目标都可见。

如果变量被定义,那么只有那些在<visibility>中被声明的目标才可以依赖当前目标。如果定义为空值,那么就表示任何目标都不可以依赖当前目标。

提示:如果你想在BUILD文件中的所有目标具有同样的可见性,那么你可以把<visibility>定义在文件的顶端,定义在任何目标的外面,这些目标就会继承那个作用范围并且引用定义。

目标声明

(输入"gn help <function>"以获得更多帮助):

action: 声明一个只运行一次脚本的目标。 action_foreach: 声明一个在一组文件上运行脚本的目标。 bundle_data: [iOS/macOS] 声明一个没有输出的目标 copy: 声明一个复制文件的目标 create_bundle: [iOS/macOS] 构建一个iOS或macOS捆绑包。 executable: 声明一个可执行的目标 generated_file: 声明一个generated_file类型目标。 group: 声明一个命名的目标组。 loadable_module: 声明一个可加载的模块目标。 rust_library: 声明一个Rust库目标。 rust_proc_macro: 声明一个Rust过程的宏目标。 shared_library: 声明一个共享库目标。Linux平台会生成一个.so文件,也就是动态库。 source_set: 声明一个源集类型目标。目前只支持C语言的源集。(也就是类C风格,比如C,C++)。 static_library: 声明一个静态库目标。 target: 用给定的编程类型声明一个目标。

构建文件函数

(输入"gn help <function>"以获得更多帮助): assert: 在生成时断言一个表达式为真。 config: 定义配置对象。 declare_args: 声明构建参数 defined: 返回ture如果所给的参数被定义了。 exec_script: 同步运行脚本并返回输出。 filter_exclude: 删除匹配一组模式的值。 filter_include: 删除不匹配一组模式的值。 foreach: 迭代一个列表。 forward_variables_from: 从不同的作用域复制变量 get_label_info: 从目标的标签获取属性。 get_path_info: 提取部分文件或目录名。 get_target_outputs: [file list] 从目标中得到输出列表 getenv: 得到一个环境变量 import: 导入一个文件到当前作用域 not_needed: 将范围中的变量标记为不需要的。 pool: 定义pool对象。 print: 打印到控制台。 process_file_template: 对文件列表进行模板扩展。 read_file: 将文件读入变量。 rebase_path: 将一个文件或目录重新base到另一个位置。 set_default_toolchain: 设置默认的工具链名。 set_defaults: 设置目标类型的默认值。 split_list: 将一个列表分成N个不同的子列表。 string_join: 用分隔符连接字符串列表。 string_replace: 替换给定字符串中的子字符串。 string_split: 将字符串拆分为字符串列表。 template: 定义模板规则。 tool:指定工具链工具的参数。 toolchain: 定义了一个工具链。 write_file: 将文件写入磁盘。

内置预定义变量

(输入"gn help <variable>"以获得更多帮助): current_cpu: [string] 当前工具链的处理器架构。 current_os: [string] 操作系统的当前工具链。 current_toolchain: [string] 当前工具链的标签。 default_toolchain: [string] 默认工具链的标签。 gn_version: [number] gn的版本。 host_cpu: [string] 运行GN的处理器架构。 host_os: [string] GN运行的操作系统。 invoker: [string] 模板内的调用作用域。 python_path: [string] Python的绝对路径。 root_build_dir: [string] 运行构建命令的目录。 root_gen_dir: [string] 用于存放工具链生成文件的目录。 root_out_dir: [string] 工具链输出文件的根目录。 target_cpu: [string] 构建所需的cpu架构。 target_gen_dir: [string] 目标生成文件的目录. target_name: [string]当前目标的名称。 target_os: [string] 构建所需的操作系统。 target_out_dir: [string]目标输出文件的目录。

在目标中设置的变量

(输入"gn help <variable>"以获得更多帮助): aliased_deps: [scope] Set of crate-dependency pairs. all_dependent_configs: [label list] 配置在从属关系上强制执行。 allow_circular_includes_from: [label list] 允许包含来自这些依赖 arflags: [string list] Arguments passed to static_library archiver. args: [string list]传递给运行的参数。 asmflags: [string list] 传递给汇编程序的标志。 assert_no_deps: [label pattern list] 确保没有对这些目标的依赖。 bridge_header: [string] C/Objective-C兼容头文件的路径。 bundle_contents_dir: Expansion of {{bundle_contents_dir}} in create_bundle. bundle_deps_filter: [label list]被过滤掉的标签列表。 bundle_executable_dir: Expansion of {{bundle_executable_dir}} in create_bundle bundle_resources_dir: Expansion of {{bundle_resources_dir}} in create_bundle. bundle_root_dir: Expansion of {{bundle_root_dir}} in create_bundle. cflags: [string list] 传递给所有C编译器变体的标志。. cflags_c: [string list] 传递给C编译器的标志。 cflags_cc: [string list] 传递给所有C++编译器的标志。 cflags_objc: [string list] 传递给客观C编译器的标志。 cflags_objcc: [string list] 传递给客观C++编译器的标志。 check_includes: [boolean] 控制是否检查目标的文件。 code_signing_args: [string list] 参数传递给代码签名脚本。 code_signing_outputs: [file list] 代码签名步骤的输出文件。 code_signing_script: [file name] 用于代码签名的脚本。 code_signing_sources: [file list] 源代码的代码签名步骤。 complete_static_lib: [boolean] 链接所有的deps到一个静态库。 configs: [label list] 配置应用于此目标或配置。 contents: 要写入文件的内容。 crate_name: [string] The name for the compiled crate. crate_root: [string] 二进制文件或库的根源文件。 crate_type: [string] 在shared_library上使用的链接类型。 data: [file list] 运行时数据文件依赖关系。 data_deps: [label list] Non-linked依赖性。 data_keys: [string list] 用于收集元数据的键。 defines: [string list] C预处理器定义。 depfile: [string] 操作的输入依赖项的文件名。 deps: [label list] Private linked dependencies. description: [string] 动作的命令描述。 externs: [scope] Set of Rust crate-dependency pairs. framework_dirs: [directory list] 额外的框架搜索目录。 frameworks: [name list]必须链接的框架的名称。 friend: [label pattern list] 允许目标包含私有头文件。 include_dirs: [directory list] 其他包括目录。 inputs: [file list] 额外的编译时依赖项。 ldflags: [string list] 传递给链接器的标志。 lib_dirs: [directory list]额外的库目录。 libs: [string list] 要链接的其他库。 metadata: [scope] 此目标的元数据。 module_name: [string] 编译模块的名称。 output_conversion: 生成的文件目标的数据格式。 output_dir: [directory] 目录放置输出文件。 output_extension: [string]用于输出文件扩展名的值。 output_name: [string] 输出文件的名称,而不是默认值。 output_prefix_override: [boolean] 不要使用前缀作为输出名称。 outputs: [file list] 输出文件的行动和复制目标。 partial_info_plist: [filename] Path plist from asset catalog compiler. pool: [string] Label of the pool used by the action. precompiled_header: [string] 预编译头文件。 precompiled_header_type: [string] "gcc" or "msvc". precompiled_source: [file name] 预编译的源文件 product_type: [string] Product type for Xcode projects. public: [file list] 给一个目标声明公共的头文件 public_configs: [label list]应用于依赖项的配置。 public_deps: [label list] 声明公共的依赖 rebase: [boolean] 将收集的元数据重新base为文件。 response_file_contents: [string list] 用于操作的.rsp文件内容。 script: [file name] 运行的脚本文件 sources: [file list] 目标的源文件 swiftflags: [string list] 传递给swift编译器的标志。 testonly: [boolean]声明一个目标必须只用于测试。 visibility: [label list] 可以依赖于目标的标签列表。 walk_keys: [string list] 用于管理元数据收集遍历的键。 weak_frameworks: [name list]必须弱链接的框架名称。 write_runtime_deps: 将目标的runtime_deps写入给定的路径。 xcasset_compiler_flags: [string list] 传递给xcassets编译器的标志 xcode_extra_attributes: [scope] Xcode项目的额外属性。 xcode_test_application_name: [string] Xcode测试目标的名称。

其他帮助主题

all: 立即打印所有的帮助 buildargs: 构建参数如何工作。 dotfile: 关于顶层.gn文件的信息。 execution:构建图和执行概述。 grammar: GN构建文件的语言和语法。 input_conversion: 处理来自exec_script和read_file的输入。 file_pattern:匹配多个文件。 label_pattern:匹配多个标签 labels: 关于标签。 metadata_collection: 关于元数据及其集合。 ninja_rules: Ninja 如何构建命名的规则 nogncheck: 注释包含用于检查。 output_conversion: 指定如何将值转换为输出。 runtime_deps: 运行时依赖计算如何工作。 source_expansion: 将sources映射到脚本的输出。 switches: 显示可用的命令行开关。

命令

(输入"gn help <command>"以获得更多帮助): analyze: 分析哪些目标受到文件列表的影响。 args: 显示或配置生成声明的参数。 check: 检查头文件依赖 clean: 清除输出目录 clean_stale: 清除输出目录中残留的文件 desc: 显示关于目标或配置的大量深刻信息。 format: gn格式文件。 gen: 生成 ninja files. help: 想什么 ls:列表匹配的目标。 meta: 列出目标元数据收集结果。 outputs: sources/目标生成哪些文件。 path: 找到两个目标之间的路径。 refs: 查找引用目标或文件的内容。

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部