[sdk] Add a "device profile" element type.

This new type will be used to convey information about supported devices
configurations when working with SDKs.
Add a few profiles to the Core SDK.

Bug: DX-981
Bug: DX-1269
Change-Id: I7622b7c8bb2e176f72cca8013bc4ab3b55ec72d0
diff --git a/build/sdk/meta/BUILD.gn b/build/sdk/meta/BUILD.gn
index 777393e..a9d3501 100644
--- a/build/sdk/meta/BUILD.gn
+++ b/build/sdk/meta/BUILD.gn
@@ -13,6 +13,7 @@
   "cc_source_library.json",
   "common.json",
   "dart_library.json",
+  "device_profile.json",
   "documentation.json",
   "fidl_library.json",
   "host_tool.json",
diff --git a/build/sdk/meta/device_profile.json b/build/sdk/meta/device_profile.json
new file mode 100644
index 0000000..fb7c53cb
--- /dev/null
+++ b/build/sdk/meta/device_profile.json
@@ -0,0 +1,48 @@
+{
+  "$schema": "http://json-schema.org/draft-04/schema#",
+  "id": "http://fuchsia.com/schemas/sdk/device_profile.json",
+  "description": "A supported device configuration for SDK development",
+  "type": "object",
+  "allOf": [
+    {
+      "$ref": "common.json#/definitions/sdk_element"
+    },
+    {
+      "properties": {
+        "type": {
+          "allOf": [
+            {
+              "$ref": "common.json#/definitions/type"
+            },
+            {
+              "enum": [
+                "device_profile"
+              ]
+            }
+          ]
+        },
+        "description": {
+          "description": "A description of the device's configuration",
+          "type": "string"
+        },
+        "images_url": {
+          "description": "GCS URL of the archive containing system images",
+          "type": "string"
+        },
+        "packages_url": {
+          "description": "GCS URL of the archive containing a package repository",
+          "type": "string"
+        }
+      },
+      "required": [
+        "description",
+        "images_url",
+        "packages_url",
+
+        "name",
+        "type"
+      ],
+      "additionalProperties": false
+    }
+  ]
+}
diff --git a/build/sdk/sdk_device_profile.gni b/build/sdk/sdk_device_profile.gni
new file mode 100644
index 0000000..023f60d
--- /dev/null
+++ b/build/sdk/sdk_device_profile.gni
@@ -0,0 +1,55 @@
+# Copyright 2019 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/sdk/sdk_atom.gni")
+
+# Declares a device profile supported for SDK development.
+#
+# Parameters
+#
+#   category (required)
+#     Publication level of the document set in SDKs.
+#     See //build/sdk/sdk_atom.gni.
+#
+#   description (required)
+#     Description of the profile.
+#
+#   images (required)
+#     GCS URL of the archive containing system images.
+#
+#   packages (required)
+#     GCS URL of the archive containing a complementary package repository.
+
+template("sdk_device_profile") {
+  assert(defined(invoker.category), "Must define an SDK category")
+  assert(defined(invoker.description), "Must define a description")
+  assert(defined(invoker.images), "Must define an images archive")
+  assert(defined(invoker.packages), "Must define a packages archive")
+
+  name = target_name
+  if (defined(invoker.name)) {
+    name = invoker.name
+  }
+
+  sdk_atom(target_name) {
+    forward_variables_from(invoker, [ "category" ])
+
+    id = "sdk://device/$name"
+
+    # This atom does not contain any actual files, only metadata.
+    files = []
+
+    meta = {
+      schema = "device_profile"
+      dest = "device/$name.json"
+      value = {
+        type = "device_profile"
+        name = name
+        description = invoker.description
+        images_url = invoker.images
+        packages_url = invoker.packages
+      }
+    }
+  }
+}
diff --git a/scripts/sdk/merger/merge.py b/scripts/sdk/merger/merge.py
index 4ab598a..9cfcc90 100755
--- a/scripts/sdk/merger/merge.py
+++ b/scripts/sdk/merger/merge.py
@@ -131,6 +131,9 @@
             arch_files[arch] = contents
     elif type == 'documentation':
         common_files.update(element_meta['docs'])
+    elif type == 'device_profile':
+        # This type is pure metadata.
+        pass
     else:
         raise Exception('Unknown element type: ' + type)
     return (common_files, arch_files)
@@ -215,7 +218,8 @@
         if 'target_files' in meta_two:
             meta['target_files'].update(meta_two['target_files'])
     elif (type == 'cc_source_library' or type == 'dart_library' or
-          type == 'fidl_library' or type == 'documentation'):
+          type == 'fidl_library' or type == 'documentation' or
+          type == 'device_profile'):
         # These elements are arch-independent, the metadata does not need any
         # update.
         meta = meta_one
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index a835343..7d8dc62 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -167,6 +167,7 @@
   }
 }
 
+# TODO(DX-1667): break this target down into smaller chunks.
 sdk("core") {
   id = sdk_id
 
@@ -180,6 +181,7 @@
     ":musl_license",
     ":open_source",
     ":vulkan_license",
+    "devices",
     "docs",
     "tools:dev_finder_sdk($host_toolchain)",
     "tools:symbolize_sdk($host_toolchain)",
diff --git a/sdk/core.api b/sdk/core.api
index 94c245e..88dd5c1 100644
--- a/sdk/core.api
+++ b/sdk/core.api
@@ -1,3 +1,7 @@
+sdk://device/generic-arm64
+sdk://device/generic-x64
+sdk://device/qemu-arm64
+sdk://device/qemu-x64
 sdk://docs/low_level
 sdk://docs/metadata_schemas
 sdk://docs/musl_license
diff --git a/sdk/devices/BUILD.gn b/sdk/devices/BUILD.gn
new file mode 100644
index 0000000..0222496
--- /dev/null
+++ b/sdk/devices/BUILD.gn
@@ -0,0 +1,51 @@
+# Copyright 2019 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/sdk/sdk_device_profile.gni")
+import("//build/sdk/sdk_molecule.gni")
+import("//sdk/config.gni")
+
+template("device") {
+  sdk_device_profile(target_name) {
+    category = "partner"
+
+    description = invoker.description
+
+    images = "gs://fuchsia/development/$sdk_id/images/$target_name.tgz"
+
+    packages = "gs://fuchsia/development/$sdk_id/packages/$target_name.tar.gz"
+  }
+}
+
+devices = [
+  {
+    name = "generic-arm64"
+    description = "A generic arm64 device"
+  },
+  {
+    name = "generic-x64"
+    description = "A generic x64 device"
+  },
+  {
+    name = "qemu-arm64"
+    description = "arm64 images runnable on QEMU"
+  },
+  {
+    name = "qemu-x64"
+    description = "x64 images runnable on QEMU"
+  },
+]
+
+all_devices = []
+
+foreach(device, devices) {
+  device(device.name) {
+    description = device.description
+  }
+  all_devices += [ ":${device.name}" ]
+}
+
+sdk_molecule("devices") {
+  deps = all_devices
+}