blob: 91e3b2678b7e2e211acc36380b66e0569aec59bc [file] [log] [blame]
# 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}" ]
}
}
}