首页 > 解决方案 > 测试文件是否存在于 GN 元构建中

问题描述

关于操作输入的GN 参考:

对于 action 和 action_foreach 目标,输入应该是不变的脚本输入。这些应该是脚本通过导入使用的所有 .py 文件(主脚本本身将是操作的隐式依赖项,因此不需要列出)。

对于动作目标,输入和源被视为相同,但从样式角度来看,建议遵循与 action_foreach 相同的规则,并将帮助文件放在输入中,并将脚本使用的数据(如果有)放在源中。

请注意,从动作声明输入依赖项的另一种方法是让动作写入 depfile(请参阅“gn help depfile”)。这允许脚本动态写入输入依赖项,在实际执行脚本之前可能不知道。这比在运行 GN 以确定输入时进行处理更有效,并且比硬编码列表更容易保持同步。

在我的情况下,输入之一是可选的,所以我只想在它存在时将它添加到列表中。我看不到在 GN 本身中对此进行测试的方法。我可以使用 depfiles,但这是唯一的选择吗?

标签: gn

解决方案


Build args are one solution, if whatever's invoking GN "knows" whether the optional input file is present:

BUILD.gn:

declare_args() {
  have_some_optional_input_file = false
}

action("my_action") {
  inputs = [ ... ] # list of your required inputs
  if (have_some_optional_input_file) {
    inputs += [ "my_optional_input.whatever" ]
  }
  ...
}

If it's truly unknowable, there's always the exec_script "escape hatch": https://gn.googlesource.com/gn/+/master/docs/reference.md#func_exec_script

This lets you run an arbitrary script at configuration time, and GN will parse the output as if you'd written it in the BUILd.gn file directly.

Since GN needs to know your exact inputs for every build, you could do something like this:

BUILD.gn:

action("my_action") {
  inputs = [ ... ] + exec_script("find_optional_inputs.py", [], "list lines")
}

Write your find_optional_inputs.py such that it returns a newline-delimited list of all files you want it to add to the input set.

Be careful, though, your exec_script statements will run every time you invoke GN, even if it's just for a non-mutating subcommand like desc or ls. Additionally, if your script is in a template, it will run once per instantiation. Your script will also run once per toolchain where it is referenced. You can add the --time argument to GN itself to see how long it takes, so at least you can keep an eye on it!


推荐阅读