| # 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. |
| |
| import("//build/assembly/assembly_input_bundle.gni") |
| import("//build/assembly/bootfs_files_for_assembly.gni") |
| import("//build/assembly/package_manifests_list.gni") |
| import("//build/config.gni") |
| import("//build/dist/distribution_manifest.gni") |
| import("//build/python/python_action.gni") |
| import("//build/zbi/kernel_cmdline.gni") |
| |
| # Create a "legacy" assembly input bundle from an image assembly configuration, |
| # so that product assembly can use it to produce a matching image assembly |
| # configuration (so that the contents of the two can be validated against). |
| # |
| # These will be used to validate that product assembly is operating correctly |
| # within the build, before we cut over to it. |
| # |
| # Parameters: |
| # |
| # bundle_name [optional; default: legacy] |
| # [string] A different name for the bundle, if not the name of the target. |
| # |
| # bundles_dir [optional; default: target_out_dir] |
| # [GN file path] path to a dir to use instead of $target_out_dir as the |
| # parent of the legacy input bundle. |
| # |
| # create_package [optional; default: false] |
| # [bool] optionally create a package that contains the legacy assembly input |
| # bundle |
| # |
| # create_package_archive [optional; default: false] |
| # [bool] optionally create an archive of the legacy assembly input bundle. |
| # Implies that `create_package` is also true. |
| # |
| # include_config_data [optional; default: true] |
| # [bool] optionally omit the handling of config_data entries (for those |
| # configurations that do not have a config_data package. |
| # |
| # base_driver_packages [optional] |
| # [list of labels] The driver packages to include in the base package set. |
| # |
| # boot_driver_packages [optional] |
| # [list of labels] The driver packages to include in the bootfs package set. |
| # |
| # core_realm_definition [optional] |
| # [label] The GN label of a `core_realm_definition()` template |
| # |
| # fshost_config [optional; default: {}] |
| # [scope] Arguments to add to fshost's configuration. These arguments come |
| # before other arguments set by build args. |
| # |
| # ramdisk_in_zbi [optional; default: false] |
| # [boolean] Whether the FVM or Fxfs image should be embedded into the ZBI as |
| # a ramdisk. |
| # |
| # system_image_deps (optional) |
| # [list of labels] The objects installed in the system image. |
| # |
| # supports_blobs [required] |
| # [bool] Whether blobs are supported on this product. |
| # |
| # base_packages [required] |
| # [list of labels] The set of base packages. |
| # |
| # cache_packages [required] |
| # [list of labels] The set of cache packages. |
| # |
| # additional_boot_args [required] |
| # [list of strings] Boot args to pass to the kernel. |
| # |
| # bootfs_labels [required] |
| # [list of labels] The set of labels to walk to find bootfs files. |
| # |
| template("legacy_assembly_input_bundle") { |
| assert( |
| current_toolchain == default_toolchain, |
| "The legacy assembly input bundle can only be created in the default toolchain") |
| |
| assert(defined(invoker.supports_blobs), "Need to define supports_blobs") |
| assert(defined(invoker.base_packages), "Need to define base_packages") |
| assert(defined(invoker.cache_packages), "Need to define cache_packages") |
| |
| assert(defined(invoker.additional_boot_args), |
| "Need to define additional_boot_args") |
| assert(defined(invoker.bootfs_labels), "Need to define bootfs_labels") |
| |
| forward_variables_from(invoker, |
| [ |
| "bundles_dir", |
| "bundle_name", |
| "create_package", |
| "create_package_archive", |
| ]) |
| |
| bootfs_package_labels = [] |
| if (defined(invoker.bootfs_package_labels)) { |
| bootfs_package_labels += invoker.bootfs_package_labels |
| } |
| |
| system_image_deps = [] |
| if (defined(invoker.system_image_deps) && invoker.supports_blobs) { |
| system_image_deps += invoker.system_image_deps |
| } else { |
| not_needed(invoker, [ "system_image_deps" ]) |
| } |
| |
| if (!defined(bundles_dir)) { |
| bundles_dir = target_out_dir |
| } |
| |
| if (!defined(invoker.bundle_name)) { |
| bundle_name = "legacy" |
| } |
| |
| _include_config_data = true |
| if (defined(invoker.include_config_data)) { |
| _include_config_data = invoker.include_config_data |
| } |
| |
| _base_driver_packages = [] |
| if (defined(invoker.base_driver_packages)) { |
| _base_driver_packages = invoker.base_driver_packages |
| } |
| |
| _boot_driver_packages = [] |
| if (defined(invoker.boot_driver_packages)) { |
| _boot_driver_packages = invoker.boot_driver_packages |
| } |
| |
| _shell_command_packages = [] |
| if (defined(invoker.shell_command_packages)) { |
| _shell_command_packages = invoker.shell_command_packages |
| } |
| |
| _core_realm_definition = false |
| if (defined(invoker.core_realm_definition)) { |
| _core_realm_definition = invoker.core_realm_definition |
| } |
| |
| labels = { |
| base_package_list = "${target_name}_package_manifest_list.base" |
| cache_package_list = "${target_name}_package_manifest_list.cache" |
| extra_base_list = "${target_name}_package_manifest_list.extra_base" |
| extra_base_deps_list = |
| "${target_name}_package_manifest_list.extra_base_deps" |
| bootfs_package_list = "${target_name}_bootfs_package_list" |
| kernel_cmdline_args = "${target_name}_kernel_cmdline_args" |
| boot_args = "${target_name}_boot_args" |
| config_data = "${target_name}.config-data" |
| config_data_entries = "${config_data}_config_package_entries" |
| bootfs_files = "${target_name}.bootfs_files" |
| bootfs_files_package = "${target_name}.bootfs_files_package" |
| |
| # The AIB itself |
| assembly_input_bundle = "$target_name.bundle" |
| |
| # The assembly bundle package and archive labels |
| assembly_input_bundle_package = "${target_name}.pkg" |
| assembly_input_bundle_archive = "${target_name}.tgz" |
| base_driver_package_list = |
| "${target_name}.package_manifest_list.base_drivers" |
| driver_package_component_files = |
| "${target_name}_driver_package_component_files" |
| boot_driver_package_list = |
| "${target_name}.package_manifest_list.boot_drivers" |
| boot_driver_package_component_files = |
| "${target_name}_boot_driver_package_component_files" |
| shell_commands_manifest_list = "${target_name}.shell_commands_manifest_list" |
| core_realm_shards_list = "${target_name}.core_realm_shards_list" |
| fshost = "${target_name}.fshost" |
| } |
| |
| files = { |
| base_package_list = "$target_out_dir/package_lists/${target_name}_base" |
| cache_package_list = "$target_out_dir/package_lists/${target_name}_cache" |
| extra_base_list = "$target_out_dir/package_lists/${target_name}_extra_base" |
| extra_base_deps_list = |
| "$target_out_dir/package_lists/${target_name}_extra_base_deps" |
| bootfs_package_list = "$target_out_dir/package_lists/${target_name}_bootfs" |
| kernel_cmdline_args = |
| "$target_out_dir/${target_name}_kernel_cmdline_args.json" |
| boot_args = "$target_out_dir/${target_name}_boot_args" |
| bootfs_files_package = |
| "$target_out_dir/${labels.bootfs_files_package}/package_manifest.json" |
| assemble_system_config_data_entries = |
| "$target_out_dir/${labels.config_data_entries}" |
| |
| # Outputs |
| |
| # The directory where all the bundle contents are written to |
| assembly_input_bundle_dir = "${bundles_dir}/${bundle_name}" |
| |
| # The "official" outputs file that we create in that directory |
| assembly_input_bundle_config = |
| "${assembly_input_bundle_dir}/assembly_config.json" |
| |
| # The files that we create as book-keeping between our tasks. |
| assembly_input_bundle_depfile = "${assembly_input_bundle_dir}.d" |
| |
| # The manifest of all files in the AIB, used to create pkgs and archives. |
| assembly_input_bundle_manifest = |
| "${assembly_input_bundle_dir}.fini_manifest" |
| |
| # The AIB package's meta.far (optionally used) |
| assembly_input_bundle_package_metafar = |
| "${assembly_input_bundle_dir}.pkg/meta.far" |
| |
| # The AIB archive and the manifest used to create it (optionally used) |
| assembly_input_bundle_archive = "${assembly_input_bundle_dir}.tgz" |
| assembly_input_bundle_archive_manifest = |
| "${assembly_input_bundle_dir}.tgz.fini_manifest" |
| base_driver_package_list = |
| "${assembly_input_bundle_dir}.package_manifest_list.drivers" |
| driver_package_component_files = |
| "${target_gen_dir}/${target_name}.driver_package_component_files" |
| boot_driver_package_list = |
| "${assembly_input_bundle_dir}.package_manifest_list.boot_drivers" |
| boot_driver_package_component_files = |
| "${target_gen_dir}/${target_name}.boot_driver_package_component_files" |
| shell_command_manifests_list = |
| "${assembly_input_bundle_dir}.package_manifest_list.shell_commands" |
| core_realm_shards_list = |
| "${assembly_input_bundle_dir}.core_realm_shards_list" |
| |
| # The cmc_merge() template this is used with prepends $target_out_dir. |
| fshost_merged_cml = "${target_name}/fshost.merged.cml" |
| } |
| |
| package_manifests_list(labels.base_driver_package_list) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| filename = files.base_driver_package_list |
| deps = _base_driver_packages |
| } |
| |
| generated_file(labels.driver_package_component_files) { |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "testonly", |
| ]) |
| deps = _base_driver_packages |
| outputs = [ "${files.driver_package_component_files}" ] |
| data_keys = [ "driver_package_component_files" ] |
| walk_keys = [ "driver_package_component_files_barrier" ] |
| output_conversion = "json" |
| } |
| |
| package_manifests_list(labels.boot_driver_package_list) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| filename = files.boot_driver_package_list |
| deps = _boot_driver_packages |
| } |
| |
| generated_file(labels.boot_driver_package_component_files) { |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "testonly", |
| ]) |
| deps = _boot_driver_packages |
| outputs = [ "${files.boot_driver_package_component_files}" ] |
| data_keys = [ "boot_driver_package_component_files" ] |
| walk_keys = [ "boot_driver_package_component_files_barrier" ] |
| output_conversion = "json" |
| } |
| |
| if (_shell_command_packages != []) { |
| generated_file(labels.shell_commands_manifest_list) { |
| forward_variables_from(invoker, |
| [ |
| "deps", |
| "testonly", |
| ]) |
| deps = _shell_command_packages |
| outputs = [ "${files.shell_command_manifests_list}" ] |
| data_keys = [ "shell_commands_distribution_manifests" ] |
| walk_keys = [ "shell_commands_barrier" ] |
| output_conversion = "json" |
| } |
| } |
| |
| if (_core_realm_definition != false) { |
| generated_file(labels.core_realm_shards_list) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| deps = [ "${_core_realm_definition}" ] |
| data_keys = [ "shard_files" ] |
| outputs = [ "${files.core_realm_shards_list}" ] |
| output_conversion = "json" |
| } |
| } |
| |
| create_package_archive = |
| defined(invoker.create_package_archive) && invoker.create_package_archive |
| create_package = create_package_archive || |
| (defined(invoker.create_package) && invoker.create_package) |
| |
| # Construct a list of Base packages. |
| package_manifests_list(labels.base_package_list) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| filename = files.base_package_list |
| |
| # Don't include driver packages |
| additional_walk_keys = [ "driver_package_barrier" ] |
| if (invoker.supports_blobs) { |
| deps = invoker.base_packages |
| } |
| } |
| |
| # Construct a list of Cache packages. |
| package_manifests_list(labels.cache_package_list) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| filename = files.cache_package_list |
| if (invoker.supports_blobs) { |
| deps = invoker.cache_packages |
| } |
| } |
| |
| # Construct a list of extra packages whose files should be added to the Base Package. |
| package_manifests_list(labels.extra_base_list) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| filename = files.extra_base_list |
| deps = system_image_deps |
| } |
| |
| # Find all the extra system dependencies in the Base packages list. |
| # This list mentions several extra packages to add to the Base Package. |
| generated_file(labels.extra_base_deps_list) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| |
| data_keys = [ "system_image_extra_package_manifest" ] |
| walk_keys = [ "system_image_extra_package_manifest_barrier" ] |
| outputs = [ files.extra_base_deps_list ] |
| output_conversion = "json" |
| deps = invoker.base_packages |
| } |
| |
| # Construct a list of bootfs packages. |
| # Ignores any fuchsia_driver_packages and fuchsia_shell_packages |
| package_manifests_list(labels.bootfs_package_list) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| filename = files.bootfs_package_list |
| deps = bootfs_package_labels |
| } |
| |
| # Accumulate the list of cmdline dependencies by first taking the |
| # directly-specified arguments, creating a new metadata target, and adding it |
| # to the list of all metadata targets, then second walking the metadata to |
| # construct the final list. |
| cmdline_deps = invoker.bootfs_labels |
| if (defined(invoker.cmdline)) { |
| kernel_cmdline("${target_name}_extra_cmdline") { |
| args = invoker.cmdline |
| } |
| cmdline_deps += [ ":${target_name}_extra_cmdline" ] |
| } |
| if (defined(invoker.cmdline_deps)) { |
| cmdline_deps += invoker.cmdline_deps |
| } |
| |
| generated_file(labels.kernel_cmdline_args) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| |
| data_keys = [ "zbi_config_entry" ] |
| walk_keys = [ "zbi_input_barrier" ] |
| outputs = [ files.kernel_cmdline_args ] |
| output_conversion = "json" |
| deps = cmdline_deps |
| } |
| |
| # Create a list of boot arguments to add to additional_boot_args. |
| generated_file(labels.boot_args) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| |
| outputs = [ files.boot_args ] |
| output_conversion = "json" |
| contents = invoker.additional_boot_args |
| } |
| |
| if (_include_config_data) { |
| config_package(labels.config_data) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| package_name = "config-data" |
| deps = invoker.base_packages + invoker.cache_packages |
| } |
| } else { |
| not_needed(invoker, |
| [ |
| "cache_packages", |
| "universe_packages", |
| ]) |
| } |
| |
| # Search for BootFS files in these targets. |
| bootfs_files_for_assembly(labels.bootfs_files) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| deps = invoker.bootfs_labels |
| } |
| |
| fuchsia_package(labels.bootfs_files_package) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| deps = [ ":${labels.bootfs_files}" ] |
| } |
| |
| # Run the script that creates the out-of-tree-usable Assembly Input Bundle from |
| # an Image Assembly product configuration and the config_data package entries |
| # that go with it. |
| python_action(labels.assembly_input_bundle) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| |
| binary_label = "//build/assembly/scripts:make_legacy_config" |
| |
| # The contents of these folders is dynamic, and managed entirely by this |
| # action. Further, this action will need to delete items from these |
| # directories that are not added back (on an incremental build, if an item |
| # is removed from one of these sets) |
| # |
| # These folders would grow in size forever, if it was not cleaned out on |
| # each incremental build. |
| hermetic_action_ignored_prefixes = [ |
| "${files.assembly_input_bundle_dir}/packages", |
| "${files.assembly_input_bundle_dir}/subpackages", |
| "${files.assembly_input_bundle_dir}/blobs", |
| "${files.assembly_input_bundle_dir}/config_data", |
| "${files.assembly_input_bundle_dir}/bootfs", |
| "${files.assembly_input_bundle_dir}/kernel", |
| "${files.assembly_input_bundle_dir}/compiled_packages", |
| ] |
| |
| outputs = [ files.assembly_input_bundle_config ] |
| depfile = files.assembly_input_bundle_depfile |
| |
| args = [ |
| "--base-packages-list", |
| rebase_path(files.base_package_list, root_build_dir), |
| "--cache-packages-list", |
| rebase_path(files.cache_package_list, root_build_dir), |
| "--extra-files-packages-list", |
| rebase_path(files.extra_base_list, root_build_dir), |
| "--extra-deps-files-packages-list", |
| rebase_path(files.extra_base_deps_list, root_build_dir), |
| "--bootfs-packages-list", |
| rebase_path(files.bootfs_package_list, root_build_dir), |
| "--kernel-cmdline", |
| rebase_path(files.kernel_cmdline_args, root_build_dir), |
| "--boot-args", |
| rebase_path(files.boot_args, root_build_dir), |
| "--outdir", |
| rebase_path(files.assembly_input_bundle_dir, root_build_dir), |
| "--depfile", |
| rebase_path(files.assembly_input_bundle_depfile, root_build_dir), |
| "--base-driver-packages-list", |
| rebase_path(files.base_driver_package_list, root_build_dir), |
| "--base-driver-components-files-list", |
| rebase_path(files.driver_package_component_files, root_build_dir), |
| "--bootfs-files-package", |
| rebase_path(files.bootfs_files_package, root_build_dir), |
| "--boot-driver-packages-list", |
| rebase_path(files.boot_driver_package_list, root_build_dir), |
| "--boot-driver-components-files-list", |
| rebase_path(files.boot_driver_package_component_files, root_build_dir), |
| ] |
| |
| # If packaging or archiving the AIB, write out the fini manifest needed to |
| # do so. |
| if (create_package || create_package_archive) { |
| args += [ |
| "--export-manifest", |
| rebase_path(files.assembly_input_bundle_manifest, root_build_dir), |
| ] |
| outputs += [ files.assembly_input_bundle_manifest ] |
| } |
| |
| inputs = [ |
| files.base_package_list, |
| files.cache_package_list, |
| files.extra_base_list, |
| files.extra_base_deps_list, |
| files.bootfs_package_list, |
| files.kernel_cmdline_args, |
| files.boot_args, |
| files.base_driver_package_list, |
| files.driver_package_component_files, |
| files.bootfs_files_package, |
| files.boot_driver_package_list, |
| files.boot_driver_package_component_files, |
| ] |
| |
| deps = [ |
| ":${labels.base_driver_package_list}", |
| ":${labels.base_package_list}", |
| ":${labels.boot_args}", |
| ":${labels.boot_driver_package_component_files}", |
| ":${labels.boot_driver_package_list}", |
| ":${labels.bootfs_files_package}", |
| ":${labels.bootfs_package_list}", |
| ":${labels.cache_package_list}", |
| ":${labels.driver_package_component_files}", |
| ":${labels.extra_base_deps_list}", |
| ":${labels.extra_base_list}", |
| ":${labels.kernel_cmdline_args}", |
| ] |
| |
| if (_shell_command_packages != []) { |
| args += [ |
| "--shell-commands-packages-list", |
| rebase_path(files.shell_command_manifests_list, root_build_dir), |
| ] |
| inputs += [ files.shell_command_manifests_list ] |
| deps += [ ":${labels.shell_commands_manifest_list}" ] |
| } |
| |
| if (_core_realm_definition != false) { |
| args += [ |
| "--core-realm-shards-list", |
| rebase_path(files.core_realm_shards_list, root_build_dir), |
| ] |
| |
| inputs += [ files.core_realm_shards_list ] |
| deps += [ ":${labels.core_realm_shards_list}" ] |
| } |
| |
| if (_include_config_data) { |
| args += [ |
| "--config-data-entries", |
| rebase_path(files.assemble_system_config_data_entries, root_build_dir), |
| ] |
| inputs += [ files.assemble_system_config_data_entries ] |
| deps += [ ":${labels.config_data_entries}" ] |
| } |
| |
| metadata = { |
| # We insert these barriers to prevent the dependencies of the input bundle |
| # from leaking into images "higher up" in the dependency chain. |
| package_barrier = [] |
| config_package_barrier = [] |
| distribution_entries_barrier = [] |
| assembly_input_archives_barrier = [] |
| } |
| } |
| |
| if (create_package) { |
| assembly_input_bundle_package(labels.assembly_input_bundle_package) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| package_name = bundle_name |
| package_outdir = "${bundles_dir}/${bundle_name}.pkg" |
| manifest = files.assembly_input_bundle_manifest |
| deps = [ ":${labels.assembly_input_bundle}" ] |
| } |
| } |
| |
| if (create_package_archive) { |
| assembly_input_bundle_archive(labels.assembly_input_bundle_archive) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| archive_name = bundle_name |
| archive_outdir = bundles_dir |
| manifest = files.assembly_input_bundle_manifest |
| deps = [ ":${labels.assembly_input_bundle}" ] |
| |
| # If the package was created, include it in the archive. |
| if (create_package) { |
| meta_far = files.assembly_input_bundle_package_metafar |
| deps += [ ":${labels.assembly_input_bundle_package}" ] |
| } |
| } |
| } |
| |
| group(target_name) { |
| forward_variables_from(invoker, |
| [ |
| "testonly", |
| "visibility", |
| ]) |
| public_deps = [ ":${labels.assembly_input_bundle}" ] |
| if (create_package) { |
| public_deps += [ ":${labels.assembly_input_bundle_package}" ] |
| } |
| if (create_package_archive) { |
| public_deps += [ ":${labels.assembly_input_bundle_archive}" ] |
| } |
| } |
| } |