| # Copyright 2022 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| # A set of GN templates to expose Ninja-generated output files as inputs |
| # to bazel_action() targets. The latter run a `bazel build` command in |
| # the Bazel workspace setup by the platform build, which cannot access |
| # the Ninja output directory directly. |
| # |
| # A bazel_input_xxx() target defines a mapping from Ninja-generated outputs |
| # as Bazel filegroups) targets. For historical reasons two distinct |
| # mechanisms exist: |
| # |
| # For full documentation, see the dedicated section in //build/bazel/README.md |
| # |
| # - First mechanism: use bazel_input_file() and/or bazel_input_directory() |
| # to expose output files or even directories. |
| # |
| # These templates populate the special @gn_targets// external repository |
| # with filegroup() targets named "@gn_targets//{gn_dir}:{gn_name} |
| # where {gn_dir} and {gn_name} reflect the directory and name of the |
| # bazel_input_xxx() target. |
| # |
| # For example, consider an action //src/lib:gen_foo that generates some |
| # outputs that needs to be exposed to the Bazel graph. This would look like: |
| # |
| # # //src/lib/BUILD.bazel |
| # action("gen_foo") { # generating action |
| # outputs = [ ... ] |
| # } |
| # |
| # bazel_input_file("foo_outputs") { # expose outputs to Bazel |
| # generator = ":gen_foo" |
| # } |
| # |
| # Here the "foo_outputs" targets doesn't generate anything, it just records |
| # information about the output files and what generates them. |
| # |
| # Next, one can define a Bazel target that accesses the output files directly |
| # using the @gn_targets//<gn_label> notation, where <gn_label> matches |
| # the GN label of the bazel_input_file() target above, as in: |
| # |
| # # //src/bar/BUILD.bazel |
| # process_file( |
| # name = "process_foo", |
| # input = "@gn_targets//src/lib:foo_outputs", # use outputs. |
| # output = "foo_processed_by_bazel", |
| # ) |
| # |
| # Invoking Bazel from GN can be done with a bazel_action() target, which must |
| # list "foo_outputs" as part of its dependencies. For example: |
| # |
| # # //src/bar/BUILD.gn |
| # bazel_action("process_foo_with_bazel") { |
| # command = "build" |
| # deps = [ "//src/lib:foo_outputs "] |
| # copy_outputs = { |
| # bazel = "{{BAZEL_TARGET_OUT_DIR}}/foo_processed_by_bazel" |
| # ninja = "foo_final" |
| # } |
| # } |
| # |
| # Then trying to `fx build //src/bar:process_foo_with_bazel` will do the following: |
| # |
| # - Ensure the outputs of //src/lib:gen_foo are up-to-date. |
| # - Update the content of the @gn_targets repository _before_ launching Bazel. |
| # - Invoke Bazel with something equivalent to `fx bazel build //src/bar:process_foo` |
| # - Copy the Bazel build artifact into its final location $BUILD_DIR/obj/src/bar/foo_final |
| # - Generate Ninja depfile dependencies from the Bazel build graph to ensure that if |
| # anything changes in the Bazel build graph, Ninja will properly re-invoke Bazel |
| # if needed. |
| # |
| # - Legacy mechanism: use bazel_input_resource() or bazel_input_resource_directory(). |
| # |
| # This mechanism exists for historical reason and is deprecated. It relies on a different |
| # pair of GN templates that also expose Ninja outputs to the Bazel build graph, with some |
| # rather important differences: |
| # |
| # - They use a different Bazel external namespace, named @legacy_ninja_build_outputs// |
| # to expose outputs. |
| # |
| # - They allow the exposition target to specify an arbitrary destination location |
| # for the Bazel filegroup() under @legacy_ninja_build_outputs//, which can lead |
| # to conflicts. |
| # |
| # For example: |
| # |
| # # //src/foo/BUILD.gn |
| # bazel_input_resource("foo_outputs") { |
| # deps = [ ":gen_foo" ] |
| # sources = get_target_outputs(":gen_foo") |
| # outputs = [ "foo_outputs" ] |
| # } |
| # |
| # Would expose the outputs as `@legacy_ninja_build_outputs//:foo_outputs` directly. |
| # |
| # - *every* bazel_input_resource() or bazel_input_resource_directory() *must* be |
| # reachable from the global list of labels |
| # |
| # - bazel_input_resource() and bazel_input_resource_directory() must be listed through |
| # the special `bazel_inputs` argument of bazel_action() targets. |
| # |
| # |
| # |
| # named @legacy_ninja_build_outputs. |
| # |
| # For example, to expose the files generated by an action `foo` as a |
| # filegroup() with Bazel label @legacy_ninja_build_outputs//:foo_files, one |
| # can use the following definition: |
| # |
| # ```gn |
| # # Expose all outputs generated by :foo in Bazel. |
| # bazel_input_resource("foo_files") { |
| # deps = [ ":foo" ] |
| # sources = get_target_outputs(":foo") |
| # outputs = [ "{{source_file_part}}" ] |
| # } |
| # |
| # IMPORTANT: Simply defining a bazel_input_xxx() target is NOT ENOUGH, it must |
| # ALSO be part of the transitive dependencies listed from one of the lists |
| # defined in //build/bazel/legacy_ninja_build_outputs.gni |
| # |
| # There is no way to enforce that with GN at the moment. |
| # |
| |
| # Used internally by bazel_input_file() and bazel_input_directory() |
| template("_bazel_input_entry") { |
| _main_target_name = target_name |
| |
| if (invoker.entry_type == "file") { |
| _output_files = rebase_path(invoker.outputs, root_build_dir) |
| } else if (invoker.entry_type == "directory") { |
| _output_dir = rebase_path(invoker.output_directory, root_build_dir) |
| } else { |
| assert(false, "Unknown _bazel_input_entry type: ${invoker.entry_type}") |
| } |
| |
| # The Bazel package is the generator's GN directory, with an optional |
| # 'toolchain_<name>' prefix if it does not belong to the default toolchain. |
| # For example: |
| # |
| # generator = "//src/lib/foo" |
| # bazel_package = "src/lib/foo" |
| # bazel_name = "foo" |
| # final_label = "@gn_targets//src/lib/foo:foo" |
| # |
| # generator = "//zircon/tools/zbi(//build/toolchain:host_x64) |
| # bazel_package = "toolchain_host_x64/zircon/tools/zbi" |
| # bazel_name = "zbi" |
| # final_label = "@gn_targets//toolchain_host_x64/zircon/tools/zbi:zbi" |
| # |
| _bazel_package = get_label_info(invoker.generator, "dir") |
| _bazel_package = string_replace(_bazel_package, "//", "") |
| if (current_toolchain != default_toolchain) { |
| _toolchain_name = get_label_info(current_toolchain, "name") |
| _bazel_package = "toolchain_${_toolchain_name}/${_bazel_package}" |
| } |
| |
| if (defined(invoker.gn_targets_name)) { |
| _bazel_name = invoker.gn_targets_name |
| } else { |
| _bazel_name = get_label_info(invoker.generator, "name") |
| } |
| |
| group(_main_target_name) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| |
| deps = [ invoker.generator ] |
| |
| metadata = { |
| # Used by generate_gn_targets_repository_manifest() template, which |
| # is part of the new scheme to expose Ninja outputs as Bazel inputs. |
| gn_targets_repository_entries = [ |
| { |
| generator_label = |
| get_label_info(invoker.generator, "label_with_toolchain") |
| bazel_package = _bazel_package |
| bazel_name = _bazel_name |
| if (invoker.entry_type == "file") { |
| output_files = _output_files |
| } else if (invoker.entry_type == "directory") { |
| output_directory = _output_dir |
| } |
| }, |
| ] |
| gn_targets_repository_entries_barrier = [] |
| } |
| } |
| } |
| |
| # Expose a set of GN target output files to Bazel. |
| # |
| # Calling this template does not build anything, but the resulting |
| # target should be in the dependencies of any bazel_action() target |
| # that needs to access these files from the Bazel graph. |
| # |
| # They will be exposed through a single filegroup() defined as |
| # @gn_targets//{target_dir}:{generator_name} in the Bazel graph, |
| # where {target_dir} matches the directory of the current target, |
| # and {generator_name} is the name of the generator target ( |
| # which could be defined in a different directory). |
| # |
| # For example: |
| # |
| # ``` |
| # # From //src/lib/BUILD.gn |
| # bazel_input_file("foo.bazel_inputs") { |
| # generator = ":foo" |
| # } |
| # ``` |
| # |
| # Will expose the outputs of the `//src/lib:foo` target in the Bazel |
| # filegroup named `@gn_targets/src/lib:foo`. |
| # |
| # It is possible to change the name of the Bazel filegroup by setting |
| # the `gn_targets_name` argument. For example: |
| # |
| # ``` |
| # bazel_input_file("foo.bazel_inputs") { |
| # generator = ":foo" |
| # gn_targets_name = "foo_files" |
| # } |
| # ``` |
| # |
| # Will create a filegroup() named `@gn_targets//src/lib:foo_files` |
| # instead. |
| # |
| # Note: only the filegroup name can be change, not its package which is |
| # hard-coded to @gn_targets//{target_dir}. |
| # |
| # If no 'outputs' argument is provided, *and* the generator and target |
| # are defined in the same BUILD.gn file and toolchain, then |
| # get_target_outputs(generator) will be used to expose all outputs |
| # from the generator target. |
| # |
| # If the generator and target are in different BUILD.gn file, or |
| # different toolchain contexts, the 'outputs' argument is required. |
| # |
| # When an 'outputs' argument is specified, it doesn't need to list all |
| # outputs from the generator, only those that need to be exposed. |
| # |
| # It is an error to expose a directory through 'outputs', as Bazel |
| # will complain when trying to access its content later. Use |
| # bazel_input_directory() to handle this use case. |
| # |
| # Arguments: |
| # generator: GN label of target that generates the output files. |
| # This can also be the label of a group() that depends on multiple |
| # generating targets. In this case, the 'outputs' argument will be |
| # required to list the output files from said dependencies to be |
| # exposed. |
| # |
| # outputs: Optional. List of output files for this target that will be exposed |
| # to Bazel. This argument is required if this target and the generator are |
| # defined in different directories or toolchains. |
| # |
| # gn_target_name: Optional. Name of Bazel filegroup() used to expose the |
| # output files. If not provided, this will use the name of the generator |
| # target. |
| # |
| # testonly, visibility: Usual GN meaning. |
| # |
| template("bazel_input_file") { |
| assert(defined(invoker.generator), |
| "bazel_input_file() requires a generator argument!") |
| |
| # Auto-compute 'outputs' value if not provided, and the right conditions are checked. |
| if (!defined(invoker.outputs)) { |
| _target_dir = get_label_info(":$target_name", "dir") |
| _generator_dir = get_label_info(invoker.generator, "dir") |
| assert( |
| _target_dir == _generator_dir, |
| "bazel_input_file() requires an 'outputs' argument if target and generator are from different directories (${_target_dir} != ${_generator_dir}") |
| |
| _target_toolchain = get_label_info(":$target_name", "toolchain") |
| _generator_toolchain = get_label_info(invoker.generator, "toolchain") |
| assert( |
| _target_toolchain == _generator_toolchain, |
| "bazel_input_file() requires an 'outputs' argument if target and generator are from different toolchains (${_target_toolchain} != ${_generator_toolchain}") |
| invoker.outputs = get_target_outputs(invoker.generator) |
| } |
| |
| _bazel_input_entry(target_name) { |
| entry_type = "file" |
| forward_variables_from(invoker, "*") |
| } |
| } |
| |
| # Expose a GN target output directory to Bazel. |
| # |
| # This is similar to bazel_input_file() but allows exposing an output |
| # directory, for the rare case where a GN target generates one. |
| # |
| # Note that only a single directory can be specified per instance. |
| # The directory will be exposed as a Bazel filegroup() with the |
| # name `@gn_targets//{gn_dir}:{gn_target}`. The filegroup's |
| # sources will be grabbed with a `glob()` statement and will thus |
| # contain all files and directories contained in it. |
| # |
| # Arguments: |
| # generator: GN label of target that generates the output files. |
| # |
| # output_directory: GN path to output directory populated by the generator. |
| # This argument can be omitted if all conditions apply: |
| # - The target and the generator are defined in the same BUILD.gn file. |
| # - The target and the generator are defined in the same GN toolchain context. |
| # - The generator only produces a single output (from GN's point of view). |
| # |
| # gn_targets_name: Optional. Name of Bazel filegroup() used to expose the |
| # output files. If not provided, this will use the name of the generator |
| # target. |
| # |
| # testonly, visibility: Usual GN meaning. |
| # |
| template("bazel_input_directory") { |
| assert(defined(invoker.generator), |
| "bazel_input_directory() requires a generator argument!") |
| |
| if (!defined(invoker.output_directory)) { |
| assert(defined(invoker.generator), |
| "bazel_input_directory() requires a 'generator' argument") |
| _target_dir = get_label_info(":$target_name", "dir") |
| _generator_dir = get_label_info(invoker.generator, "dir") |
| assert( |
| _target_dir == _generator_dir, |
| "bazel_input_file() requires an 'outputs' argument if target and generator are from different directories (${_target_dir} != ${_generator_dir}") |
| |
| _target_toolchain = get_label_info(":$target_name", "toolchain") |
| _generator_toolchain = get_label_info(invoker.generator, "toolchain") |
| assert( |
| _target_toolchain == _generator_toolchain, |
| "bazel_input_file() requires an 'outputs' argument if target and generator are from different toolchains (${_target_toolchain} != ${_generator_toolchain}") |
| |
| _outputs = get_target_outputs(invoker.generator) |
| assert( |
| _outputs != [] && _outputs == [ _outputs[0] ], |
| "bazel_input_directory() requires an 'output_directory' argument if the generator produces more than one output: ${_outputs}") |
| invoker.output_directory = _outputs[0] |
| } |
| assert(defined(invoker.output_directory), |
| "Missing output_directory argument.") |
| assert("${invoker.output_directory}" == invoker.output_directory, |
| "output_directory argument must be a path string.") |
| _bazel_input_entry(target_name) { |
| entry_type = "directory" |
| forward_variables_from(invoker, "*") |
| } |
| } |
| |
| # DEPRECATED: Use bazel_input_file() instead! |
| # |
| # Expose a set of Ninja output files as a corresponding Bazel filegroup() |
| # of prebuilt input sources for the Bazel build. |
| # |
| # This template works like copy() or resource(). |
| # |
| # ```gn |
| # # Expose all outputs generated by :foo in Bazel. |
| # bazel_input_resource("foo_files") { |
| # deps = [ ":foo" ] |
| # sources = get_target_outputs(":foo") |
| # outputs = [ "{{source_file_part}}" ] |
| # } |
| # |
| # ... |
| # |
| # Make sure this is reachable from the transitive dependencies listed in |
| # //build/bazel/legacy_ninja_build_outputs.gni, e.g.: |
| # |
| # ``` |
| # gn_labels_for_bazel_inputs += [ "//src/foo:foo_files" ] |
| # ``` |
| # |
| # Assuming that :foo generates the following files: |
| # |
| # out/default/gen/src/foo/foo.h |
| # out/default/gen/src/foo/foo.cc |
| # |
| # Then this will generate something like that @legacy_ninja_build_outputs/BUILD.bazel: |
| # |
| # ```bazel |
| # filegroup("foo_files") { |
| # srcs = [ |
| # "foo.h", |
| # "foo.cc", |
| # ] |
| # ) |
| # ``` |
| # |
| # After creating the symlinks as: |
| # |
| # $BAZEL_TOPDIR/output_base/external/legacy_ninja_build_outputs/ |
| # foo.h --> ../../../../../src/foo/foo.h |
| # foo.cc --> ../../../../../src/foo/foo.cc |
| # |
| # Arguments: |
| # name: (optional) |
| # Bazel filegroup name for the set of files covered by this target. |
| # If not specified, defaults to target_name. Note that the filegroup() |
| # will be part of the top-level BUILD.bazel file generated by the |
| # build)_inputs_workspace() dependent. This name cannot contain a |
| # directory separator or colon. |
| # Type: string |
| # |
| # sources |
| # Required: List of output files that become sources in the Bazel |
| # workspace. Technically works with Ninja source files as well, but these |
| # are already exposed to Bazel by default, and don't need to be |
| # listed in a bazel_input_resource() target. See copy() for details. |
| # Type: list(file) |
| # |
| # outputs |
| # Required: List of one runtime path. This must be a relative path (no |
| # leading `/`). It can use placeholders based on $sources; see copy() |
| # and `gn help source_expansion`. |
| # Type: list(path) |
| # |
| # deps |
| # Optional: Targets that produce $sources. Any files listed in |
| # $sources that are produced by the build should be produced by a |
| # target listed here. |
| # Type: list(label) |
| # |
| # gn_targets_name |
| # Optional: Name of the filegroup target that will be defined in the |
| # @gn_targets repository for this set of files. Default is target_name |
| # with any "_bazel_inputs" suffix removed. |
| # Type: string |
| # |
| template("bazel_input_resource") { |
| _name = target_name |
| if (defined(invoker.name)) { |
| _name = invoker.name |
| assert(string_replace(_name, "/", "") == _name, |
| "name cannot contain directory separators: $_name") |
| assert(string_replace(_name, ":", "") == _name, |
| "name cannot contain colon: $_name") |
| } |
| |
| _sources = rebase_path(invoker.sources, root_build_dir) |
| _dest = process_file_template(invoker.sources, invoker.outputs) |
| |
| foreach(dst_path, _dest) { |
| assert( |
| rebase_path(dst_path, "//") != dst_path, |
| "`outputs` in bazel_input_resource() cannot start with /: ${dst_path}") |
| } |
| |
| _gn_label = get_label_info(":$target_name", "label_with_toolchain") |
| |
| # _generator_target is not empty if there is a single dependency that |
| # defines the outputs. |
| _generator_target = "" |
| if (defined(invoker.deps)) { |
| _deps = invoker.deps |
| if (_deps != [] && _deps == [ _deps[0] ]) { |
| _generator_target = _deps[0] |
| |
| _gn_targets_package = get_label_info(_generator_target, "dir") |
| _gn_targets_package = string_replace(_gn_targets_package, "//", "") |
| if (current_toolchain != default_toolchain) { |
| _toolchain_name = get_label_info(current_toolchain, "name") |
| _gn_targets_package = |
| "toolchain_${_toolchain_name}/${_gn_targets_package}" |
| } |
| } |
| } |
| |
| # NOTE: Unlike bazel_input_file(), the default target name is the name |
| # of the bazel_input_resource() target, not the name of the generator, |
| # with an optional `_bazel_inputs` suffix removed. |
| if (defined(invoker.gn_targets_name)) { |
| _gn_targets_name = invoker.gn_targets_name |
| } else { |
| _gn_targets_name = target_name |
| } |
| |
| # Remove optional '_bazel_inputs" suffix. |
| _gn_targets_name_no_suffix = |
| string_replace("${_gn_targets_name}##", "_bazel_inputs##", "##") |
| if (_gn_targets_name_no_suffix != "${_gn_targets_name}##") { |
| _gn_targets_name = string_replace(_gn_targets_name_no_suffix, "##", "") |
| } |
| |
| group(target_name) { |
| forward_variables_from(invoker, |
| "*", |
| [ |
| "metadata", |
| "name", |
| "outputs", |
| "sources", |
| ]) |
| |
| metadata = { |
| # Used by bazel_inputs_manifest() template. |
| # See its documentation for the metadata schema. |
| bazel_inputs = [ |
| { |
| name = _name |
| sources = _sources |
| destinations = _dest |
| gn_label = _gn_label |
| gn_targets_name = _gn_targets_name |
| }, |
| ] |
| bazel_inputs_barrier = [] |
| |
| if (_generator_target != "") { |
| # Used by generate_gn_targets_repository_manifest(), this makes |
| # bazel_input_resource() behave like bazel_input_file() |
| gn_targets_repository_entries = [ |
| { |
| generator_label = |
| get_label_info(_generator_target, "label_no_toolchain") |
| bazel_name = _gn_targets_name |
| bazel_package = _gn_targets_package |
| output_files = rebase_path(invoker.sources, root_build_dir) |
| }, |
| ] |
| } |
| gn_targets_repository_entries_barrier = [] |
| } |
| } |
| } |
| |
| # DEPRECATED: Use bazel_input_directory() instead. |
| # |
| # bazel_input_resource_directory() is used to expose the content of a Ninja |
| # output directory as a Bazel input filegroup. Instead of passing a list of |
| # source files, `source_root` source point to a directory whose content will |
| # be symlinks into a bazel_build_inputs_workspace(). |
| # |
| # IMPORTANT: This is not hermetic, and can lead to incorrect results during |
| # incremental builds, unless the directory's content is always cleared |
| # before the Ninja action that generates its content is run. |
| # |
| # For example: |
| # |
| # bazel_input_resource_directory"my-generated-resources") { |
| # source_dir = get_label_info(":resource-generator", "target_gen_dir") |
| # dest_dir = "data/resources" |
| # deps = [ ¨:resource-generator" ] |
| # } |
| # |
| # Parameters |
| # name: (optional) |
| # Bazel filegroup name for the set of files covered by this target. |
| # If not specified, defaults to target_name. Note that the filegroup() |
| # will be part of the top-level BUILD.bazel file generated by the |
| # build)_inputs_workspace() dependent. This name cannot contain a |
| # directory separator or colon. |
| # Type: string |
| # |
| # source_dir |
| # Required: GN path to the source directory that contains all outputs |
| # files to be exposed as a Bazel filegroup(). |
| # Type: string(path) |
| # |
| # dest_dir |
| # Required: Destination path where all sources are exposed. |
| # Cannot start with a "/". Use an empty string to expose files directly |
| # to the workspace's top-level directory. |
| # Type: string(path) |
| # |
| # deps |
| # Optional: Targets that produce $sources. Any files listed in |
| # $sources that are produced by the build should be produced by a |
| # target listed here. |
| # Type: list(label) |
| # |
| # gn_targets_name |
| # Optional: Name of the filegroup target that will be defined in the |
| # @gn_targets repository for this set of files. Default is target_name |
| # with any "_bazel_inputs" suffix removed. |
| # Type: string |
| # |
| template("bazel_input_resource_directory") { |
| _name = target_name |
| if (defined(invoker.name)) { |
| _name = invoker.name |
| assert(string_replace(_name, "/", "") == _name, |
| "name cannot contain directory separators: $_name") |
| assert(string_replace(_name, ":", "") == _name, |
| "name cannot contain colon: $_name") |
| } |
| assert(defined(invoker.dest_dir), "dest_dir is required") |
| dest_dir = invoker.dest_dir |
| if (dest_dir != "") { |
| assert(rebase_path(dest_dir, "foo") != dest_dir, |
| "dest_dir cannot start with /: $dest_dir") |
| assert(dest_dir != "." && dest_dir != ".." && |
| string_replace(dest_dir, "./", "") == dest_dir, |
| "dest_dir cannot contain . or .. path elements: $dest_dir") |
| |
| # Add trailing directory separator. |
| dest_dir = string_replace(dest_dir + "//", "//", "/") |
| } |
| |
| _generator_target = "" |
| if (defined(invoker.deps)) { |
| _deps = invoker.deps |
| if (_deps != [] && _deps == [ _deps[0] ]) { |
| _generator_target = get_label_info(_deps[0], "label_no_toolchain") |
| |
| _gn_targets_package = get_label_info(_generator_target, "dir") |
| _gn_targets_package = string_replace(_gn_targets_package, "//", "") |
| if (current_toolchain != default_toolchain) { |
| _toolchain_name = get_label_info(current_toolchain, "name") |
| _gn_targets_package = |
| "toolchain_${_toolchain_name}/${_gn_targets_package}" |
| } |
| } |
| } |
| |
| # NOTE: Unlike bazel_input_directory(), the default target name is the name |
| # of the bazel_input_resource_directory() target, not the name of the generator, |
| # with an optional `_bazel_inputs` suffix removed. |
| if (defined(invoker.gn_targets_name)) { |
| _gn_targets_name = invoker.gn_targets_name |
| } else { |
| _gn_targets_name = target_name |
| } |
| |
| # Remove optional '_bazel_inputs" suffix. |
| _gn_targets_name_no_suffix = |
| string_replace("${_gn_targets_name}##", "_bazel_inputs##", "##") |
| if (_gn_targets_name_no_suffix != "${_gn_targets_name}##") { |
| _gn_targets_name = string_replace(_gn_targets_name_no_suffix, "##", "") |
| } |
| |
| group(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "testonly", |
| "visibility", |
| ]) |
| metadata = { |
| # Used by bazel_inputs_manifest() template. |
| bazel_inputs = [ |
| { |
| name = _name |
| source_dir = rebase_path(invoker.source_dir, root_build_dir) |
| dest_dir = dest_dir |
| gn_label = get_label_info(":$target_name", "label_with_toolchain") |
| gn_targets_name = _gn_targets_name |
| }, |
| ] |
| bazel_inputs_barrier = [] |
| |
| if (_generator_target != "") { |
| # Used by generate_gn_targets_repository_manifest(), this makes |
| # bazel_input_resource_directory() behave like bazel_input_directory() |
| gn_targets_repository_entries = [ |
| { |
| generator_label = |
| get_label_info(_generator_target, "label_with_toolchain") |
| bazel_package = _gn_targets_package |
| bazel_name = _gn_targets_name |
| output_directory = rebase_path(invoker.source_dir, root_build_dir) |
| }, |
| ] |
| } |
| gn_targets_repository_entries_barrier = [] |
| } |
| } |
| } |
| |
| # Generate a manifest file describing the content of the Bazel inputs |
| # repository that will be used by the Bazel workspace to read Ninja outputs |
| # as sources / prebuilts. |
| # |
| # Args: |
| # output: |
| # Path to generated manifest file. |
| # |
| # inputs_deps: |
| # A list of targets, all transitive dependencies which are bazel_input_xxx() |
| # target will generate one entry in the manifest. |
| # |
| template("generate_bazel_inputs_manifest") { |
| # Generate a single manifest file that collects all bazel_input_xxx() |
| # resources. Each metadata entry is a scope that describes a single |
| # Bazel filegroup() target that will appear at the top of the |
| # auto-generated workspace. |
| # |
| # There are two types of entries: |
| # |
| # ## REGULAR ENTRIES |
| # |
| # These entries expose an explicit list of files, they look like: |
| # |
| # name: (required) |
| # Bazel filegroup name. |
| # Type: string |
| # |
| # destinations: (required) |
| # List of input files, relative to the top of the generated workspace. |
| # Each one will appear in the `srcs` list of the corresponding |
| # filegroup. |
| # |
| # sources: (required) |
| # List of source files for the filegroup. Must have the same |
| # size as the `destinations` list. |
| # Type: list of paths relative to the root_build_dir |
| # |
| # gn_label: |
| # GN label of target that defines this entry. |
| # Type: GN label string |
| # |
| # They should generate Bazel targets that look like: |
| # |
| # filegroup( |
| # name = "<name>", |
| # srcs = [ |
| # <destination_1>, |
| # <destination_2>, |
| # ... |
| # ], |
| # ) |
| # |
| # Where <destination_N> is the N-th entry in `destinations`, and will be |
| # the path to a symlink (in the repository) to the corresponding |
| # <sources_N> file. |
| # |
| # ## DIRECTORY ENTRIES |
| # |
| # These entries expose all files under a given output directory as |
| # a single filegroup() using the glob() function. IMPORTANT: For |
| # correctness, only use these when it is 100% sure that the content |
| # of the source directory is re-created properly during incremental |
| # builds. These look like: |
| # |
| # name: (required) |
| # Bazel filegroup name. |
| # Type: string |
| # |
| # source_dir: (required) |
| # A source directory path, relative to the Ninja build output |
| # directory, which will contain all input files for the Bazel |
| # filegroup(). |
| # |
| # dest_dir: (required) |
| # A directory prefix for all input files, relative to the top of |
| # the generated workspace. This will be a symlink to source_dir, |
| # and the filegroup() will use a glob(["<dest_dir>/*"]) call to get all |
| # files in it. |
| # |
| # gn_label: (optional) |
| # GN label of target that defines this entry. |
| # Type: GN label string |
| # |
| # They should generate Bazel targets that look like: |
| # |
| # filegroup( |
| # name = "<name>", |
| # srcs = glob(["<dest_dir>/**]), |
| # ) |
| # |
| # Where <dest_dir> is a repository symlink that points to source_dir. |
| # |
| generated_file(target_name) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| outputs = [ invoker.output ] |
| data_keys = [ "bazel_inputs" ] |
| walk_keys = [ "bazel_inputs_barrier" ] |
| deps = invoker.inputs_deps |
| output_conversion = "json" |
| } |
| } |
| |
| # Generate a manifest file describing the content of the @gn_targets |
| # repository. Only used internally by the Fuchsia platform build. |
| # This should not be invoked by regular BUILD.gn files. |
| # |
| # Arguments: |
| # deps: List of root dependencies to walk from to collect all metadata. |
| # output: Output file path. Defaults to $target_gen_dir/$target_name.json |
| # |
| template("generate_gn_targets_repository_manifest") { |
| if (defined(invoker.output)) { |
| _output = invoker.output |
| } else { |
| _output = "$target_gen_dir/$target_name.json" |
| } |
| |
| # There are two types of entries: |
| # |
| # ## REGULAR ENTRIES |
| # |
| # These entries expose an explicit list of files, as a single file group, |
| # they look like: |
| # |
| # bazel_name: (required) |
| # Bazel filegroup name. |
| # Type: Bazel target name string |
| # |
| # bazel_package: (required) |
| # Bazel package name (without leading // prefix). |
| # Type: Bazel label string |
| # |
| # generator_label: (required) |
| # GN target label that generates the file, must include toolchain. |
| # Type: GN label string |
| # |
| # output_files: (required) |
| # List of Ninja build artifacts, relative to the Ninja build directories. |
| # These will appear in the 'srcs' attribute of the filegroup. |
| # Type: list of paths relative to the root_build_dir |
| # |
| # They should generate Bazel targets in @gn_targets//<bazel_package>/BUILD.bazel |
| # that look like: |
| # |
| # # From <generator_label> |
| # filegroup( |
| # name = "<bazel_name>", |
| # srcs = [ |
| # "_files/<output_file_1>", |
| # "_files/<output_file_2>", |
| # ... |
| # ], |
| # ) |
| # |
| # Where <output_file_N> is the N-th entry in `output_files`, and will be |
| # the path to a symlink (in the repository) into the special @gn_targets//_files |
| # package. |
| # |
| # ## DIRECTORY ENTRIES |
| # |
| # These entries expose all files under a given Ninja output directory as |
| # a single filegroup() using the glob() function. IMPORTANT: For |
| # correctness, only use these when it is 100% sure that the content |
| # of the source directory is re-created properly during incremental |
| # builds. These look like: |
| # |
| # bazel_name: (required) |
| # Bazel filegroup name. |
| # Type: Bazel target name string |
| # |
| # bazel_package: (required) |
| # Bazel package name (without leading // prefix). |
| # Type: Bazel label string |
| # |
| # generator_label: (required) |
| # GN target label that generates the file, must include toolchain. |
| # Type: GN label string |
| # |
| # output_directory: (required) |
| # Path to the directory containing Ninja output files, relative to the Ninja build directories. |
| # Type: directory path relative to the root_build_dir |
| # |
| # They should generate Bazel targets in @gn_targets//<bazel_package>/BUILD.bazel |
| # that look like: |
| # |
| # # From <generator_label> |
| # filegroup( |
| # name = "<bazel_name>", |
| # srcs = glob(["_files/<output_directory>/**]), |
| # ) |
| # |
| generated_file(target_name) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| outputs = [ _output ] |
| data_keys = [ "gn_targets_repository_entries" ] |
| walk_keys = [ "gn_targets_repository_entries_barrier" ] |
| deps = invoker.deps |
| output_conversion = "json" |
| } |
| } |