| # 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 = "${clang_prefix}/../lib" |
| |
| # Path to rustc lib directory. |
| rustc_lib_dir = "${rustc_prefix}/../lib" |
| |
| # Extra args to globally apply to the manifest generation script. |
| extra_manifest_args = [] |
| } |
| |
| # Rebased versions of `clang_lib_dir` and `rustc_lib_dir`. |
| # Note that this operation also replaces '.../bin/../lib' in |
| # the paths with '.../lib' |
| rebased_clang_lib_dir = rebase_path(clang_lib_dir, root_build_dir) |
| rebased_rustc_lib_dir = rebase_path(rustc_lib_dir, 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 ] |
| |
| # 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 = "${temp_manifest}.rsp" |
| write_file( |
| response_file, |
| [ |
| "--cwd=.", |
| "--manifest=" + |
| rebase_path(runtime_deps_manifest, root_build_dir), |
| |
| # Note that after the first '--output' argument, further `--manifest` or |
| # `--entry` arguments in invoker.args will contribute to the output manifest. |
| "--output=" + rebase_path(outputs[0], root_build_dir), |
| "--cwd=.", |
| ] + invoker.args) |
| inputs += [ response_file ] |
| |
| 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", root_build_dir), |
| "--toolchain-lib-dir=" + rebased_clang_lib_dir, |
| "--toolchain-lib-dir=" + rebased_rustc_lib_dir, |
| "@" + rebase_path(response_file, root_build_dir), |
| ] |
| } |
| |
| 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", |
| ] |
| } |
| } |