| # 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/package_manifests_list.gni") |
| import("//build/dist/distribution_manifest.gni") |
| import("//build/python/python_action.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: |
| # |
| # image_assembly_label [required] |
| # [label] GN label for the image assembly to use as a basis for the "legacy" |
| # assembly input bundle. |
| # |
| # 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. |
| # |
| # core_realm_definition [optional] |
| # [label] The GN label of a `core_realm_definition()` template |
| # |
| template("legacy_assembly_input_bundle") { |
| assert( |
| current_toolchain == default_toolchain, |
| "The legacy assembly input bundle can only be created in the default toolchain") |
| |
| forward_variables_from(invoker, |
| [ |
| "image_assembly_label", |
| "bundles_dir", |
| "bundle_name", |
| "create_package", |
| "create_package_archive", |
| ]) |
| |
| assert(defined(image_assembly_label), |
| "The image assembly configuration must be specified for: " + |
| get_label_info(target_name, "label_with_toolchain")) |
| |
| 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 |
| } |
| |
| _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 = { |
| # Extract the assembly label's dir and name components: |
| image_assembly_name = get_label_info(image_assembly_label, "name") |
| image_assembly_dir = get_label_info(image_assembly_label, "target_out_dir") |
| |
| # Compute the assembly config and config_data labels that are generated within |
| # generated_image_assembly_config() |
| assemble_system_config_data = |
| "${image_assembly_label}.config-data_config_package_entries" |
| |
| # 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" |
| shell_commands_manifest_list = "${target_name}.shell_commands_manifest_list" |
| core_realm_shards_list = "${target_name}.core_realm_shards_list" |
| core_realm_includes = "${target_name}.core_realm_includes" |
| core_realm_default_includes = "${target_name}.core_realm_default_includes" |
| core_realm_main_cml = "${target_name}.core_realm_main_cml" |
| core_realm_proxy_manifest = "${target_name}.core_realm_proxy_manifest" |
| } |
| |
| files = { |
| image_assembly_config = |
| "${labels.image_assembly_dir}/${labels.image_assembly_name}.json" |
| |
| assemble_system_config_data_entries = "${labels.image_assembly_dir}/${labels.image_assembly_name}.config-data_config_package_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" |
| 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" |
| core_realm_includes = "${assembly_input_bundle_dir}.core_realm_includes" |
| core_realm_proxy_manifest = |
| "${assembly_input_bundle_dir}.core_realm_proxy_distribution_manifest" |
| } |
| |
| 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" |
| } |
| |
| 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) { |
| # Legacy list of includes used by core realm shards. |
| core_shard_includes = [ |
| "//src/sys/core/meta/svc_for_sys.core_shard.cml", |
| "//src/sys/core/meta/core_proxy.core_shard.cml", |
| "//src/intl/intl_services/meta/intl.core_shard.base.cml", |
| "//src/media/audio/audio_core/meta/audio_core.core_shard.base.cml", |
| "//src/settings/service/meta/setui_service_base.core_shard.cml", |
| "//src/testing/sl4f/meta/sl4f.core_shard.cml", |
| "//src/testing/sl4f/meta/sl4f_base.core_shard.cml", |
| "//src/recovery/system/meta/core_shards/base.shard.cml", |
| "//src/recovery/system/meta/core_shards/ui.shard.cml", |
| |
| # Required for workstation |
| "//src/connectivity/bluetooth/profiles/bt-a2dp/meta/bt-a2dp-common.core_shard.cml", |
| "//src/session/bin/session_manager/meta/all_products_capabilities.core_shard.cml", |
| "//src/session/bin/session_manager/meta/some_products_capabilities.core_shard.cml", |
| "//src/session/bin/session_manager/meta/terminal_capabilities.core_shard.cml", |
| "//src/ui/meta/ui_routes_base.shard.cml", |
| "//src/session/bin/session_manager/meta/session.smart.from_platform.core_shard.cml", |
| "//src/security/bin/tee_manager/meta/tee_manager.core_shard.base.cml", |
| ] |
| |
| # Include the default core cml in the legacy AIB |
| group(labels.core_realm_main_cml) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| deps = [] |
| metadata = { |
| shard_files = |
| [ rebase_path("//src/sys/core/meta/core.cml", root_build_dir) ] |
| } |
| } |
| |
| generated_file(labels.core_realm_shards_list) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| deps = [ |
| ":${labels.core_realm_main_cml}", |
| "${_core_realm_definition}", |
| ] |
| data_keys = [ "shard_files" ] |
| outputs = [ "${files.core_realm_shards_list}" ] |
| output_conversion = "json" |
| } |
| |
| distribution_manifest(labels.core_realm_proxy_manifest) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| deps = [ "//src/sys/core:core_proxy" ] |
| outputs = [ files.core_realm_proxy_manifest ] |
| } |
| |
| # Include files needed by the default core cml in the legacy AIB |
| # The source of a core realm include file is its location |
| # relative to the root_build_dir, while the destination |
| # is its location relative to the fuchsia root. |
| # Assembly doesn't know about the fuchsia root but components reference |
| # absolute includes relative to the fuchsia root dir, so we lay them |
| # out in the AIB in the same way they are laid out in fuchsia.git. |
| group(labels.core_realm_default_includes) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| metadata = { |
| shard_includes = [ |
| { |
| #TODO(115630): Add the sdk directory to the include paths |
| source = rebase_path("//sdk/lib/syslog/offer.shard.cml") |
| destination = "syslog/offer.shard.cml" |
| }, |
| ] |
| |
| foreach(core_shard_include, core_shard_includes) { |
| shard_includes += [ |
| { |
| source = rebase_path(core_shard_include, root_build_dir) |
| destination = rebase_path(core_shard_include, "//") |
| }, |
| ] |
| } |
| } |
| } |
| |
| generated_file(labels.core_realm_includes) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| deps = [ |
| ":${labels.core_realm_default_includes}", |
| "${_core_realm_definition}", |
| ] |
| data_keys = [ "shard_includes" ] |
| outputs = [ "${files.core_realm_includes}" ] |
| 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) |
| |
| # 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 = [ |
| "--image-assembly-config", |
| rebase_path(files.image_assembly_config, 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), |
| ] |
| |
| # 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_driver_package_list, |
| files.driver_package_component_files, |
| files.image_assembly_config, |
| ] |
| |
| deps = [ |
| ":${labels.base_driver_package_list}", |
| ":${labels.driver_package_component_files}", |
| image_assembly_label, |
| ] |
| |
| 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), |
| "--core-realm-includes-list", |
| rebase_path(files.core_realm_includes, root_build_dir), |
| "--core-package-contents-list", |
| rebase_path(files.core_realm_proxy_manifest, root_build_dir), |
| ] |
| |
| inputs += [ |
| files.core_realm_shards_list, |
| files.core_realm_includes, |
| files.core_realm_proxy_manifest, |
| ] |
| deps += [ |
| ":${labels.core_realm_includes}", |
| ":${labels.core_realm_proxy_manifest}", |
| ":${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.assemble_system_config_data ] |
| } |
| |
| 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 = [] |
| } |
| } |
| |
| 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}" ] |
| } |
| } |
| } |