| # 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/components.gni") | 
 |  | 
 | # Defines a guest package. | 
 | # | 
 | # Parameters | 
 | #   zircon (string, optional) | 
 | #     Path to a Zircon kernel. Either "zircon" or "linux" must be specified. | 
 | #   linux (string, optional) | 
 | #     Path to a Linux kernel. Either "zircon" or "linux" must be specified. | 
 | #   ramdisk (string, optional) | 
 | #     Path to a ramdisk file to be loaded into the guest. | 
 | #   cmdline (string, optional) | 
 | #     Kernel cmdline string. | 
 | #   dtb_overlay (string, optional) | 
 | #     Path to a DTB overlay to be loaded for a Linux kernel. | 
 | #   block_devices (array, optional) | 
 | #     List of block devices to use. | 
 | # | 
 | template("guest_package") { | 
 |   assert(defined(invoker.zircon) || defined(invoker.linux), "") | 
 |  | 
 |   guest_config_target_name = "${target_name}_guest_config" | 
 |   guest_config_file = "${target_out_dir}/guest.cfg" | 
 |  | 
 |   action(guest_config_target_name) { | 
 |     script = "//src/virtualization/packages/generate_guest_config.py" | 
 |     outputs = [ guest_config_file ] | 
 |  | 
 |     args = [] | 
 |     if (defined(invoker.zircon)) { | 
 |       args += [ | 
 |         "--zircon", | 
 |         "data/kernel", | 
 |       ] | 
 |     } | 
 |     if (defined(invoker.linux)) { | 
 |       args += [ | 
 |         "--linux", | 
 |         "data/kernel", | 
 |       ] | 
 |     } | 
 |     if (defined(invoker.ramdisk)) { | 
 |       args += [ | 
 |         "--ramdisk", | 
 |         "data/ramdisk", | 
 |       ] | 
 |     } | 
 |     if (defined(invoker.cmdline)) { | 
 |       args += [ | 
 |         "--cmdline", | 
 |         invoker.cmdline, | 
 |       ] | 
 |     } | 
 |     if (defined(invoker.dtb_overlay)) { | 
 |       args += [ | 
 |         "--dtb-overlay", | 
 |         "data/dtb_overlay", | 
 |       ] | 
 |     } | 
 |     if (defined(invoker.block_devices)) { | 
 |       foreach(block_spec, invoker.block_devices) { | 
 |         args += [ | 
 |           "--block", | 
 |           block_spec, | 
 |         ] | 
 |       } | 
 |     } | 
 |     if (defined(invoker.cpus)) { | 
 |       args += [ | 
 |         "--cpus", | 
 |         invoker.cpus, | 
 |       ] | 
 |     } | 
 |     if (defined(invoker.memory)) { | 
 |       args += [ | 
 |         "--memory", | 
 |         invoker.memory, | 
 |       ] | 
 |     } | 
 |     args += [ rebase_path("$guest_config_file", root_build_dir) ] | 
 |   } | 
 |  | 
 |   guest_resource_target_name = "${target_name}_guest_resource" | 
 |   resource(guest_resource_target_name) { | 
 |     deps = [ ":$guest_config_target_name" ] | 
 |     sources = [ guest_config_file ] | 
 |     outputs = [ "data/guest.cfg" ] | 
 |   } | 
 |   resources = [ ":$guest_resource_target_name" ] | 
 |  | 
 |   if (defined(invoker.zircon)) { | 
 |     kernel = invoker.zircon | 
 |   } else if (defined(invoker.linux)) { | 
 |     kernel = invoker.linux | 
 |   } | 
 |   if (defined(kernel)) { | 
 |     kernel_resource_target_name = "${target_name}_kernel_resource" | 
 |     resource(kernel_resource_target_name) { | 
 |       forward_variables_from(invoker, | 
 |                              [ | 
 |                                "deps", | 
 |                                "testonly", | 
 |                                "visibility", | 
 |                              ]) | 
 |       sources = [ kernel ] | 
 |       outputs = [ "data/kernel" ] | 
 |     } | 
 |     resources += [ ":$kernel_resource_target_name" ] | 
 |   } | 
 |  | 
 |   if (defined(invoker.ramdisk)) { | 
 |     ramdisk_resource_target_name = "${target_name}_ramdisk_resource" | 
 |     resource(ramdisk_resource_target_name) { | 
 |       forward_variables_from(invoker, | 
 |                              [ | 
 |                                "deps", | 
 |                                "testonly", | 
 |                                "visibility", | 
 |                              ]) | 
 |       sources = [ invoker.ramdisk ] | 
 |       outputs = [ "data/ramdisk" ] | 
 |     } | 
 |     resources += [ ":$ramdisk_resource_target_name" ] | 
 |   } | 
 |  | 
 |   if (defined(invoker.dtb_overlay)) { | 
 |     dtb_resource_target_name = "${target_name}_dtb_resource" | 
 |     resource(dtb_resource_target_name) { | 
 |       forward_variables_from(invoker, | 
 |                              [ | 
 |                                "deps", | 
 |                                "testonly", | 
 |                                "visibility", | 
 |                              ]) | 
 |       sources = [ invoker.dtb_overlay ] | 
 |       outputs = [ "data/dtb_overlay" ] | 
 |     } | 
 |     resources += [ ":$dtb_resource_target_name" ] | 
 |   } | 
 |  | 
 |   # Rewrite old-style package#resources as new-style resource() targets. | 
 |   # Invokers can alternatively define resource() targets and add to deps. | 
 |   if (defined(invoker.resources)) { | 
 |     foreach(invoker_resource, invoker.resources) { | 
 |       invoker_resource_target_name = | 
 |           "${target_name}_invoker_resource_${invoker_resource.dest}" | 
 |       resource(invoker_resource_target_name) { | 
 |         forward_variables_from(invoker, | 
 |                                [ | 
 |                                  "deps", | 
 |                                  "testonly", | 
 |                                  "visibility", | 
 |                                ]) | 
 |         sources = [ invoker_resource.path ] | 
 |         outputs = [ "data/${invoker_resource.dest}" ] | 
 |       } | 
 |       resources += [ ":$invoker_resource_target_name" ] | 
 |     } | 
 |   } | 
 |  | 
 |   component_target_name = "${target_name}_component" | 
 |   component_name = target_name | 
 |   fuchsia_component(component_target_name) { | 
 |     forward_variables_from(invoker, | 
 |                            [ | 
 |                              "testonly", | 
 |                              "visibility", | 
 |                            ]) | 
 |     component_name = component_name | 
 |     manifest = "//src/virtualization/packages/meta/guest_package.cmx" | 
 |     deps = resources | 
 |   } | 
 |  | 
 |   fuchsia_package(target_name) { | 
 |     forward_variables_from(invoker, | 
 |                            [ | 
 |                              "testonly", | 
 |                              "metadata", | 
 |                              "visibility", | 
 |                            ]) | 
 |     deps = [ ":${component_target_name}" ] | 
 |   } | 
 | } | 
 |  | 
 | # Defines a guest prebuilt. | 
 | # | 
 | # Parameters | 
 | #   source (string, required) | 
 | #   output (string, required) | 
 | template("guest_prebuilt") { | 
 |   assert(defined(invoker.source), "") | 
 |   assert(defined(invoker.output), "") | 
 |   action(target_name) { | 
 |     script = "//src/virtualization/packages/check_image.sh" | 
 |  | 
 |     # If the input file exists, we want to copy it to the output. | 
 |     # Otherwise, we want to generate an empty file. | 
 |     # | 
 |     # GN has no way to specify an "optional input" -- we can either | 
 |     # specify an input (causing GN to error out if the file doesn't | 
 |     # exist); or not specify an input (meaning that GN will not rebuild | 
 |     # when the input image changes). | 
 |     # | 
 |     # We work around this by not specifying the input file as | 
 |     # a dependency explicitly, but having the "check_image.sh" script | 
 |     # out a depfile the first time it is run. This gives the script | 
 |     # a chance to run and generate a fake empty image file the first | 
 |     # time it runs, and after that, GN will correctly rebuild when | 
 |     # required. | 
 |     depfile = "${invoker.output}.d" | 
 |  | 
 |     args = [ | 
 |       rebase_path(invoker.source, root_build_dir), | 
 |       rebase_path(invoker.output, root_build_dir), | 
 |       rebase_path(depfile, root_build_dir), | 
 |     ] | 
 |  | 
 |     outputs = [ invoker.output ] | 
 |   } | 
 | } |