Simplify GN logic by creating a target for prebuilt Linux

The `initrd` GN template currently supports two different ways of
specifying a primary VM image - name of a target or a path to a prebuilt
image. These use different target properties (as GN has no mechanism of
classifying a string as either a target or a path).

Simplify this in anticipation of using different Linux targets for
different HW boards in platform args by creating a target for each
prebuilt image. The `linux_kernel` template accepts a `prebuilt` path
and creates a "${target_name}__prebuilt" target which copies the image
into the out folder. As a side effect, this more closely ties the image
to the source code in the GN file.

Change-Id: I2afa295e666581393e9a80c311d7d8fe56d4fbba
diff --git a/build/image/image.gni b/build/image/image.gni
index 61a407a..fbaf14b 100644
--- a/build/image/image.gni
+++ b/build/image/image.gni
@@ -150,9 +150,8 @@
 
 # Build the initial RAM disk for the hypervisor.
 template("initrd") {
-  assert(
-      defined(invoker.primary_vm) || defined(invoker.primary_vm_prebuilt),
-      "initrd() must specify a \"primary_vm\" or \"primary_vm_prebuilt\" value")
+  assert(defined(invoker.primary_vm),
+         "initrd() must specify a \"primary_vm\" value")
 
   action(target_name) {
     forward_variables_from(invoker, [ "testonly" ])
@@ -162,24 +161,22 @@
     initrd_file = "${initrd_base}.img"
     initrd_staging = "${initrd_base}"
 
-    deps = []
+    # Cannot get target outputs here as they are defined in a different file.
+    primary_vm_image = get_label_info(invoker.primary_vm, "target_out_dir") +
+                       "/" + get_label_info(invoker.primary_vm, "name") + ".bin"
 
-    if (defined(invoker.primary_vm_prebuilt)) {
-      primary_vm_output = invoker.primary_vm_prebuilt
-    } else {
-      primary_vm_output =
-          get_label_info(invoker.primary_vm, "target_out_dir") + "/" +
-          get_label_info(invoker.primary_vm, "name") + ".bin"
-      deps += [ invoker.primary_vm ]
-    }
+    deps = [
+      invoker.primary_vm,
+    ]
     args = [
       "--primary_vm",
-      rebase_path(primary_vm_output),
+      rebase_path(primary_vm_image),
       "--staging",
       rebase_path(initrd_staging),
       "--output",
       rebase_path(initrd_file),
     ]
+
     if (defined(invoker.primary_initrd)) {
       deps += [ invoker.primary_initrd ]
       primary_initrd_outputs = get_target_outputs(invoker.primary_initrd)
diff --git a/build/linux/linux.gni b/build/linux/linux.gni
index b675813..6ac0b8a 100644
--- a/build/linux/linux.gni
+++ b/build/linux/linux.gni
@@ -31,6 +31,7 @@
 template("linux_kernel") {
   source_target = "${target_name}__source"
   defconfig_target = "${target_name}__defconfig"
+  prebuilt_target = "${target_name}__prebuilt"
 
   # Args to build/make.py to start the Linux build.
   shared_args = [
@@ -90,6 +91,18 @@
       ":${source_target}",
     ]
   }
+
+  # Subtarget for a prebuilt image, if defined.
+  if (defined(invoker.prebuilt)) {
+    copy(prebuilt_target) {
+      sources = [
+        invoker.prebuilt,
+      ]
+      outputs = [
+        "${target_out_dir}/${prebuilt_target}.bin",
+      ]
+    }
+  }
 }
 
 template("linux_kernel_module") {
diff --git a/test/linux/BUILD.gn b/test/linux/BUILD.gn
index 57ea451..13bd807 100644
--- a/test/linux/BUILD.gn
+++ b/test/linux/BUILD.gn
@@ -43,7 +43,7 @@
 initrd("linux_test") {
   testonly = true
 
-  primary_vm_prebuilt = "//prebuilts/linux-aarch64/linux/vmlinuz"
+  primary_vm = "//third_party:linux__prebuilt"
   primary_initrd = ":linux_test_initrd"
 }
 
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn
index 9751f25..6dfa3b9 100644
--- a/third_party/BUILD.gn
+++ b/third_party/BUILD.gn
@@ -58,4 +58,5 @@
 
 linux_kernel("linux") {
   kernel_dir = "linux"
+  prebuilt = "//prebuilts/linux-aarch64/linux/vmlinuz"
 }