blob: 73548525cd3b0eb3440913a3c26969656b719ea9 [file] [log] [blame]
# Copyright 2019 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.
# Generate a manifest file as used by `zbi`, `minfs`, etc.
#
# This produces a manifest file in the `TARGET=SOURCE` format where
# `SOURCE` is a host file path relative to $root_build_dir and `TARGET`
# is a path relative to some filesystem image or directory subtree being
# populated. The manifest is populated from optional fixed entries given
# in $manifest (see below) and from the dependency graph of this target.
#
# resource() targets as well as executable() et al and any targets with
# an `install_path` parameter contribute metadata to populate manifest
# files that depend on those targets. manifest_file() targets and other
# packaging steps act as dependency barriers to the manifest metadata
# collection, so if this target depends (directly or indirectly) on
# another manifest_file(), the dependencies of _that_ manifest_file()
# won't contribute entries to _this_ manifest (unless they are reached
# separately as dependencies of _this_ target by a dependency path not
# passing thruogh _that_ target).
#
# Parameters
#
# data_deps
# Optional: Has no effect on this target, but dependents will depend
# on these targets.
# Type: list(label)
#
# deps
# Optional: Dependencies examined for metadata. Transitive dependencies
# from here defining `metadata.manifest_lines` contribute to the manifest,
# pruned at targets that set `metadata.manifest_barrier`.
# Type: list(label)
#
# output_dir
# Optional: Directory where the manifest file is written.
# Type: dir
# Default: target_gen_dir
#
# output_extension
# Optional: Extension added to $output_name.
# Type: string
# Default: "manifest"
#
# output_name
# Optional: Name of the manifest file written out.
# Type: string
# Default: target_name
#
# manifest
# Optional: Fixed entries for the manifest file. These augment the
# entries collected from `manifest_lines` metadata. Each entry is
# either a string that's a literal manifest entry line, or a scope
# with $sources and $outputs like a resource() target. **Note:**
# This does not express any dependency on the $sources files;
# they will be noted in a depfile for incremental builds, but
# if they are created by the build the actions that create them
# must also be in $deps and this is not enforced by GN.
# Type: list(string or scope)
#
template("manifest_file") {
forward_variables_from(invoker,
[
"output_dir",
"output_extension",
"output_name",
])
if (!defined(output_dir)) {
output_dir = target_gen_dir
}
if (!defined(output_extension)) {
output_extension = "manifest"
}
if (!defined(output_name)) {
output_name = target_name
}
manifest_file = "$output_dir/$output_name"
if (output_extension != "") {
manifest_file += ".$output_extension"
}
manifest_target = target_name
file_target = "_manifest_file.$target_name.manifest"
# An embedded manifest contributes to metadata.manifest_lines directly.
entries = []
if (defined(invoker.manifest)) {
foreach(entry, invoker.manifest) {
if (entry == "$entry") {
# It's a literal manifest entry string.
entries += [ entry ]
} else {
# It's a manifest entry in the style of a copy() target.
foreach(source, entry.sources) {
source_path = rebase_path(source, root_build_dir)
foreach(target, process_file_template([ source ], entry.outputs)) {
entries += [ "${target}=${source_path}" ]
}
}
}
}
}
manifest_deps = []
if (defined(invoker.deps)) {
manifest_deps += invoker.deps
}
if (entries != []) {
# generated_file() doesn't collect its own metadata, so we need an
# extra group() here just to contain the explicit manifest metadata.
metadata_target = "_manifest_file.$target_name.metadata"
manifest_deps += [ ":$metadata_target" ]
group(metadata_target) {
visibility = [ ":$file_target" ]
metadata = {
manifest_lines = entries
}
}
}
# This target produces the actual manifest file.
generated_file(file_target) {
visibility = [ ":$manifest_target" ]
forward_variables_from(invoker, [ "testonly" ])
deps = manifest_deps
outputs = [
manifest_file,
]
output_conversion = "list lines"
data_keys = [ "manifest_lines" ]
walk_keys = [ "manifest_barrier" ]
metadata = {
manifest_barrier = []
}
}
# Putting $data_deps into the generated_file() would mean those all get
# visited for the metadata collection, which is not right. So we always
# have a group() target wrapping the generated_file(). For clarity we
# pass the invoker's metadata on here instead of inside the
# generated_file() though it doesn't really matter for collections.
group(manifest_target) {
forward_variables_from(invoker,
[
"data_deps",
"testonly",
"visibility",
])
deps = [
":$file_target",
]
metadata = {
images = []
if (defined(invoker.metadata)) {
# This lets the invoker add to `images`, though our implicit
# contributions will always be there too.
forward_variables_from(invoker.metadata, "*")
}
# For the //:images build_api_module().
images += [
{
label = get_label_info(":$target_name", "label_with_toolchain")
name = output_name
path = rebase_path(manifest_file, root_build_dir)
type = "manifest"
cpu = current_cpu
os = current_os
},
]
}
}
}