| # 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. |
| |
| import("//build/config.gni") |
| import("//build/config/fuchsia/zbi.gni") |
| import("//build/config/fuchsia/zircon.gni") |
| import("//build/images/collect_blob_manifest.gni") |
| import("//build/images/fvm.gni") |
| import("//build/images/pkgfs.gni") |
| import("//build/images/shell_commands.gni") |
| |
| # Assembles a Fuchsia system. |
| # |
| # Given base, cache, and universe packages, assembles a Fuchsia system |
| # containing those packages. |
| # |
| # Parameters |
| # |
| # base_packages (required) |
| # [list of labels] The packages to include in the base package set. |
| # |
| # cache_packages (optional) |
| # [list of labels] The packages to cache in the images. |
| # |
| # universe_packages (optional) |
| # [list of labels] The packages to build in addition to the base and cache |
| # sets. These packages do not contribute to the produced images directly, |
| # however they may contribute to the config-data and shell-commands meta |
| # packages. |
| # |
| # netboot (default: false) |
| # [boolean] Whether the generated ZBI should contain the entire system. |
| # |
| # devmgr_config (default: []) |
| # [list of strings] List of arguments to add to /boot/config/devmgr. |
| # These arguments come after synthesized arguments to configure blobfs and |
| # pkgfs. |
| # |
| # cmdline (optional) |
| # [list of strings] Kernel command line text. |
| # |
| # cmdline_inputs (optional) |
| # [list of files] Input files treated as kernel command line text. |
| # |
| # compress_blobs (default: true) |
| # [boolean] Whether the blobs added to the blobfs image should be compressed. |
| # |
| # output_dir (optional; default: target_out_dir) |
| # [string] The output directory into which the final system ZBI is written. |
| template("assemble_system") { |
| base_packages = invoker.base_packages |
| cache_packages = [] |
| universe_packages = [] |
| if (defined(invoker.cache_packages)) { |
| cache_packages = invoker.cache_packages |
| } |
| if (defined(invoker.universe_packages)) { |
| universe_packages = invoker.universe_packages |
| } |
| |
| # Must be unique among assembled systems. |
| image_name = target_name |
| |
| netboot = false |
| if (defined(invoker.netboot)) { |
| netboot = invoker.netboot |
| } |
| |
| compress_blobs = true |
| if (defined(invoker.compress_blobs)) { |
| compress_blobs = invoker.compress_blobs |
| } |
| |
| devmgr_config = [] |
| if (defined(invoker.devmgr_config)) { |
| devmgr_config = invoker.devmgr_config |
| } |
| |
| shell_commands("${target_name}_shell-commands") { |
| package_name = "shell-commands" |
| testonly = true |
| visibility = [ ":*" ] |
| deps = base_packages + cache_packages + universe_packages |
| } |
| |
| config_package("${image_name}_config-data") { |
| package_name = "config-data" |
| testonly = true |
| visibility = [ ":*" ] |
| deps = base_packages + cache_packages + universe_packages |
| } |
| |
| group("${image_name}_base_packages") { |
| testonly = true |
| visibility = [ ":*" ] |
| deps = base_packages + [ |
| ":${image_name}_config-data", |
| ":${image_name}_shell-commands", |
| pkgfs_package_label, |
| ] |
| } |
| |
| meta_far_merkle_index = "$target_out_dir/${image_name}_meta_far_merkle_index" |
| package_metadata_list("${image_name}_meta_far_merkle_index") { |
| testonly = true |
| visibility = [ ":*" ] |
| outputs = [ meta_far_merkle_index ] |
| data_keys = [ "meta_far_merkle_index_entries" ] |
| deps = [ ":${image_name}_base_packages" ] |
| } |
| |
| action("${image_name}_pkgsvr_index") { |
| visibility = [ ":*" ] |
| testonly = true |
| inputs = [ meta_far_merkle_index ] |
| outputs = [ "$target_out_dir/${target_name}" ] |
| deps = [ ":${image_name}_meta_far_merkle_index" ] |
| script = "//build/images/manifest_content_expand.sh" |
| args = rebase_path(inputs, root_build_dir) + |
| rebase_path(outputs, root_build_dir) |
| } |
| |
| system_image_manifest_args = |
| "$target_out_dir/${image_name}_system_image.manifest_args" |
| generated_file("${image_name}_system_image.manifest_args") { |
| visibility = [ ":*" ] |
| testonly = true |
| outputs = [ system_image_manifest_args ] |
| data_keys = [ "system_image_rsps" ] |
| walk_keys = [ "package_barrier" ] |
| deps = [ ":${image_name}_base_packages" ] |
| } |
| |
| boot_manifest = "$target_out_dir/boot.manifest" |
| |
| generate_manifest("${image_name}_system_image.manifest") { |
| visibility = [ ":*" ] |
| testonly = true |
| |
| bootfs_manifest = boot_manifest |
| bootfs_zircon_groups = "all" |
| bootfs_allowlist = [] |
| if (defined(invoker.bootfs_allowlist)) { |
| bootfs_allowlist = invoker.bootfs_allowlist |
| } |
| |
| deps = [ |
| ":${image_name}_pkgsvr_index", |
| ":${image_name}_system_image.manifest_args", |
| ] |
| json = "//build/images/system_meta_package.json" |
| pkgsvr_index = get_target_outputs(":${image_name}_pkgsvr_index") |
| |
| sources = [ |
| json, |
| pkgsvr_index[0], |
| system_image_manifest_args, |
| ] |
| args = [ |
| "@" + rebase_path(system_image_manifest_args, root_build_dir), |
| "--entry=meta/package=" + rebase_path(json, root_build_dir), |
| "--entry=data/static_packages=" + |
| rebase_path(pkgsvr_index[0], root_build_dir), |
| ] |
| |
| # Inject virtcon into the system image. |
| # TODO(41410): Remove when unified build exists. |
| deps += [ "//src/bringup/virtcon:virtual-console" ] |
| args += [ "--entry=bin/virtual-console=" + |
| rebase_path("$root_build_dir/virtual-console", root_build_dir) ] |
| } |
| |
| system_manifest_outputs = |
| get_target_outputs(":${image_name}_system_image.manifest") |
| assert(boot_manifest == system_manifest_outputs[2]) |
| |
| pm_build_package("${image_name}_system_image.meta") { |
| visibility = [ ":*" ] |
| testonly = true |
| manifest = ":${image_name}_system_image.manifest" |
| package_name = "system_image" |
| } |
| |
| blob_manifest = "$target_out_dir/${image_name}_blob.manifest" |
| collect_blob_manifest("${image_name}_blob.manifest") { |
| testonly = true |
| visibility = [ ":*" ] |
| outputs = [ blob_manifest ] |
| deps = [ |
| ":${image_name}_base_packages", |
| ":${image_name}_system_image.meta", |
| pkgfs_package_label, |
| ] |
| } |
| |
| zircon_tool_action("${image_name}_blob.blk") { |
| visibility = [ ":*" ] |
| testonly = true |
| deps = [ ":${image_name}_blob.manifest" ] |
| blob_image_path = "$target_out_dir/$target_name" |
| blob_size_list = "$target_out_dir/${image_name}_blob.sizes" |
| outputs = [ blob_image_path ] |
| depfile = blob_image_path + ".d" |
| inputs = [ blob_manifest ] |
| tool = "blobfs" |
| args = [ |
| "--depfile", |
| "--sizes", |
| rebase_path(blob_size_list, root_build_dir), |
| ] |
| if (compress_blobs) { |
| args += [ "--compress" ] |
| } |
| args += [ |
| rebase_path(blob_image_path, root_build_dir), |
| "create", |
| "--manifest", |
| rebase_path(blob_manifest, root_build_dir), |
| ] |
| } |
| |
| zircon_tool_action("${image_name}_data.blk") { |
| data_image_path = "$target_out_dir/${target_name}" |
| visibility = [ ":*" ] |
| testonly = true |
| outputs = [ data_image_path ] |
| tool = "minfs" |
| args = [ |
| rebase_path(data_image_path, root_build_dir), |
| "create", |
| ] |
| } |
| |
| generate_fvm("${image_name}_fvm.blk") { |
| # Referenced by guest_package. |
| testonly = true |
| output_name = "$target_out_dir/$target_name" |
| args = fvm_create_args |
| partitions = [ |
| { |
| type = "blob" |
| dep = ":${image_name}_blob.blk" |
| }, |
| { |
| type = "data" |
| dep = ":${image_name}_data.blk" |
| }, |
| ] |
| } |
| |
| action("${image_name}_devmgr_config.txt") { |
| visibility = [ ":*" ] |
| testonly = true |
| script = "//build/images/manifest.py" |
| outputs = [ "$target_out_dir/devmgr_config.txt" ] |
| args = [ "--output=" + rebase_path(outputs[0], root_build_dir) ] |
| sources = [] |
| deps = [ ":${image_name}_system_image.manifest" ] |
| |
| pkgfs = "bin/" + pkgfs_binary_name |
| pkgfs_label = pkgfs_package_label |
| pkgfs_pkg_out_dir = get_label_info(pkgfs_label, "target_out_dir") + "/" + |
| get_label_info(pkgfs_label, "name") |
| pkgfs_blob_manifest = "$pkgfs_pkg_out_dir/meta/contents" |
| system_image_merkleroot = |
| "$target_out_dir/${image_name}_system_image.meta/meta.far.merkle" |
| |
| deps += [ |
| ":${image_name}_system_image.meta", |
| pkgfs_label, |
| ] |
| |
| sources += [ |
| pkgfs_blob_manifest, |
| system_image_merkleroot, |
| ] |
| |
| args += [ |
| "--entry=devmgr.require-system=true", |
| |
| "--contents", |
| "--rewrite=*=zircon.system.pkgfs.cmd={target}+{source}", |
| "--entry=${pkgfs}=" + |
| rebase_path(system_image_merkleroot, root_build_dir), |
| "--no-contents", |
| "--reset-rewrite", |
| |
| "--rewrite=*=zircon.system.pkgfs.file.{target}={source}", |
| "--manifest=" + rebase_path(pkgfs_blob_manifest, root_build_dir), |
| "--reset-rewrite", |
| ] |
| |
| foreach(entry, devmgr_config) { |
| args += [ "--entry=$entry" ] |
| } |
| |
| # If there were any ASan drivers in the build, bin/devhost.asan |
| # should have been brought into the boot manifest. devmgr needs to |
| # be told to use it in case there are ASan drivers in /system but |
| # none in /boot. If there were any non-ASan drivers in the build, |
| # bin/devhost.asan will load them and needs to know to moderate the |
| # checking for interacting with uninstrumented code. |
| sources += [ boot_manifest ] |
| args += [ |
| "--include=bin/devhost", |
| "--manifest=" + rebase_path(boot_manifest, root_build_dir), |
| ] |
| } |
| |
| component_manager_label = |
| "//src/sys/component_manager:component_manager.bootfs" |
| component_manager_target_dir = |
| get_label_info(component_manager_label, "target_out_dir") |
| component_manager_target_name = |
| get_label_info(component_manager_label, "name") |
| component_manager_manifest = |
| component_manager_target_dir + "/" + component_manager_target_name |
| |
| coordinator_label = "//src/devices:devices.bootfs" |
| coordinator_target_dir = get_label_info(coordinator_label, "target_out_dir") |
| coordinator_target_name = get_label_info(coordinator_label, "name") |
| coordinator_manifest = coordinator_target_dir + "/" + coordinator_target_name |
| |
| root_manifests_label = "//src/sys/bootstrap:root_manifests.bootfs" |
| root_manifests_target_dir = |
| get_label_info(root_manifests_label, "target_out_dir") |
| root_manifests_target_name = get_label_info(root_manifests_label, "name") |
| root_manifests_manifest = |
| root_manifests_target_dir + "/" + root_manifests_target_name |
| |
| zbi(image_name) { |
| metadata = { |
| # We insert a package barrier because the packages inside this ZBI |
| # shouldn't leak to targets that depend on the ZBI. For example, |
| # suppose we store this ZBI inside a package() that is assembled into |
| # another Fuchsia system. We don't want the parent system to incorporate |
| # the packages from the ZBI into its own package list. |
| package_barrier = [] |
| config_package_barrier = [] |
| |
| if (defined(invoker.metadata)) { |
| forward_variables_from(invoker.metadata, "*") |
| } |
| } |
| |
| output_dir = target_out_dir |
| if (defined(invoker.output_dir)) { |
| output_dir = invoker.output_dir |
| } |
| |
| forward_variables_from(invoker, |
| [ |
| "cmdline", |
| "cmdline_inputs", |
| ]) |
| |
| testonly = true |
| deps = [ |
| ":${image_name}_devmgr_config.txt", |
| ":${image_name}_fvm.blk", |
| ":${image_name}_system_image.manifest", |
| component_manager_label, |
| coordinator_label, |
| root_manifests_label, |
| ] |
| inputs = [ |
| boot_manifest, |
| component_manager_manifest, |
| coordinator_manifest, |
| root_manifests_manifest, |
| zircon_kernel_zbi, |
| ] |
| manifest = [ |
| { |
| outputs = [ "config/devmgr" ] |
| sources = get_target_outputs(":${image_name}_devmgr_config.txt") |
| }, |
| ] |
| |
| if (netboot) { |
| ramdisk_inputs = get_target_outputs(":${image_name}_fvm.blk") |
| } |
| } |
| } |