blob: f3136b21212ffc9bdb47bb894e93709d25b2428e [file] [log] [blame]
# Copyright 2018 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.
import("//build/config/clang/clang.gni")
import("//build/dist/distribution_manifest.gni")
import("//build/dist/verify_manifest_elf_binaries.gni")
import("//build/rust/config.gni")
import("//build/toolchain/runtime/toolchain_runtime_deps.gni")
declare_args() {
# Path to Clang lib directory.
clang_lib_dir = rebase_path("${clang_prefix}/../lib", root_build_dir)
# Path to rustc lib directory.
rustc_lib_dir = rebase_path("${rustc_prefix}/../lib", root_build_dir)
# Extra args to globally apply to the manifest generation script.
extra_manifest_args = []
}
# Action target that generates a response file in GN's "shlex" format.
#
# Parameters
#
# output_name (optional, default: target_name)
# [path] Response file to write (if relative, relative to target_out_dir).
#
# response_file_contents (required)
# data_deps (optional)
# deps (optional)
# metadata (optional)
# public_deps (optional)
# testonly (optional)
# visibility (optional)
# Same as for any GN `action()` target.
#
template("generate_response_file") {
action(target_name) {
forward_variables_from(invoker,
[
"data_deps",
"deps",
"metadata",
"output_name",
"public_deps",
"response_file_contents",
"testonly",
"visibility",
])
if (!defined(output_name)) {
output_name = target_name
}
outputs = [ "$target_out_dir/$output_name" ]
assert(
defined(response_file_contents),
"generate_response_file(\"${target_name}\") must define response_file_contents")
script = "/bin/cp"
args = [ "-f" ]
if (response_file_contents == []) {
# GN doesn't allow an empty response file.
args += [ "/dev/null" ]
} else {
args += [ "{{response_file_name}}" ]
}
args += rebase_path(outputs, root_build_dir)
}
}
# Action target that generates a manifest file in the `target=/abs/file`
# format used by `zbi`, `blobfs`, etc. ELF files in the manifest have
# their dynamic linking details examined and other necessary ELF files
# implicitly added to the manifest.
# Outputs: $target_out_dir/$target_name, $target_out_dir/$target_name.ids.txt
#
# Parameters
#
# args (required)
# [list of strings] Additional arguments to finalize_manifests.py;
# `sources` should list any files directly referenced.
#
# output_name (optional, default: target_name)
# [string] Root name of the output manifest file.
#
# deps (optional)
# sources (optional)
# testonly (optional)
# visibility (optional)
# Same as for any GN `action()` target.
#
template("generate_manifest") {
assert(defined(invoker.args),
"generate_manifest(\"${target_name}\") requires args")
# Generate a manifest containing all runtime deps.
runtime_deps_manifest_target = "${target_name}.runtime_deps"
runtime_deps_manifest = "$target_gen_dir/${target_name}.runtime_deps.manifest"
toolchain_runtime_deps_manifest(runtime_deps_manifest_target) {
forward_variables_from(invoker,
[
"deps",
"data_deps",
"public_deps",
"testonly",
])
outputs = [ runtime_deps_manifest ]
}
temp_manifest_action = "${target_name}.temp"
temp_manifest = "$target_gen_dir/${target_name}.temp"
action(temp_manifest_action) {
forward_variables_from(invoker,
[
"deps",
"public_deps",
"sources",
"testonly",
"visibility",
])
if (!defined(sources)) {
sources = []
}
if (!defined(deps)) {
deps = []
}
depfile = "${temp_manifest}.d"
stripped_dir = "${temp_manifest}.stripped"
script = "//build/images/finalize_manifests.py"
inputs = rebase_path([
"elfinfo.py",
"manifest.py",
"variant.py",
],
"",
"//build/images")
outputs = [ temp_manifest ]
args = extra_manifest_args + [
"--depfile=" + rebase_path(depfile, root_build_dir),
"--stripped-dir=" + rebase_path(stripped_dir, root_build_dir),
"--build-id-dir=" + rebase_path("$root_build_dir/.build-id"),
"--toolchain-lib-dir=" + clang_lib_dir,
"--toolchain-lib-dir=" + rustc_lib_dir,
"@{{response_file_name}}",
]
response_file_contents = []
# First the Zircon manifests are pure auxiliaries:
# they just supply libraries that might satisfy dependencies.
sources += [ runtime_deps_manifest ]
deps += [ ":${runtime_deps_manifest_target}" ]
response_file_contents += [
"--cwd=.",
"--manifest=" + rebase_path(runtime_deps_manifest),
]
# Note that after the first '--output' argument, further `--manifest` or
# `--entry` arguments in invoker.args will contribute to the output manifest.
response_file_contents +=
[
"--output=" + rebase_path(outputs[0], root_build_dir),
"--cwd=.",
] + invoker.args
}
verify_manifest_action = "${target_name}.verify"
verify_manifest_elf_binaries(verify_manifest_action) {
forward_variables_from(invoker, [ "testonly" ])
manifest = temp_manifest
deps = [ ":$temp_manifest_action" ]
check_debug_files = true
}
if (defined(invoker.output_name)) {
manifest_file = "$target_out_dir/${invoker.output_name}"
} else {
manifest_file = "$target_out_dir/$target_name"
}
# NOTE: Other targets wants to use get_target_outputs() on $target_name
# to retrieve the path of the generated manifest. Meanwhile, we also need
# to verify its content _after_ creating it. A copy() is ideal here since
# it is cheap (it just creates a hard-link) and allows us to add the right
# dependencies.
copy(target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
sources = [ temp_manifest ]
outputs = [ manifest_file ]
deps = [
":$temp_manifest_action",
":$verify_manifest_action",
]
}
}