|  | # 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/compiled_action.gni") | 
|  | import("//build/json/validate_json.gni") | 
|  | import("config.gni") | 
|  | import("meta/version.gni") | 
|  | import("sdk_molecule.gni") | 
|  |  | 
|  | # A collection of elements to be published in an SDK. | 
|  | # | 
|  | # Parameters | 
|  | # | 
|  | #   name (optional) | 
|  | #     Name of the SDK. | 
|  | #     Defaults to the target's name. | 
|  | # | 
|  | #   id (optional) | 
|  | #     An opaque identifier for the SDK. | 
|  | #     Defaults to the empty string. | 
|  | # | 
|  | #   api (required) | 
|  | #     Path to the file representing the canonical contents of this SDK. | 
|  | #     This file is used to ensure modifications to the SDK contents are | 
|  | #     explicitly acknowledged. | 
|  | #     Mandatory for "public" or "partner" SDKs. | 
|  | # | 
|  | #   category (required) | 
|  | #     Describes the minimum category that atoms in this SDK must have. | 
|  | #     See //build/sdk/sdk_atom.gni for possible values. | 
|  | # | 
|  | #   export (optional) | 
|  | #     Whether to export the contents of this SDK to the output directory. | 
|  | #     This is useful when an SDK-like file structure is needed as part of the | 
|  | #     build, for example to port a language runtime which would otherwise rely | 
|  | #     on an official SDK. | 
|  | #     Defaults to false. | 
|  |  | 
|  | template("sdk") { | 
|  | assert(defined(invoker.category), "Must define an SDK category") | 
|  |  | 
|  | if (invoker.category == "public" || invoker.category == "partner") { | 
|  | assert(defined(invoker.api), "API file required for public/partner SDKs") | 
|  | } | 
|  |  | 
|  | main_target_name = target_name | 
|  | generation_target_name = "${target_name}_molecule" | 
|  | verify_api_target_name = "${target_name}_verify_api" | 
|  | copy_target_name = "${target_name}_copy" | 
|  | verification_target_name = "${target_name}_manifest_verify" | 
|  | meta_target_name = "${target_name}_meta" | 
|  | verify_meta_target_name = "${target_name}_meta_verify" | 
|  | archive_manifest_target_name = "${target_name}_archive_manifest" | 
|  | archive_target_name = "${target_name}_archive" | 
|  | fidl_json_target_name = "${target_name}_fidl_json" | 
|  |  | 
|  | if (!is_fuchsia) { | 
|  | assert(false, "SDKs can only target Fuchsia") | 
|  | } | 
|  | target_triple = target_cpu | 
|  | if (host_cpu == "x64") { | 
|  | host_triple_cpu = "x86_64" | 
|  | } else if (host_cpu == "arm64") { | 
|  | host_triple_cpu = "aarch64" | 
|  | } else { | 
|  | assert(false, "Unrecognized host CPU: $host_cpu") | 
|  | } | 
|  | if (host_os == "linux") { | 
|  | host_triple_os = "linux-gnu" | 
|  | } else if (host_os == "mac") { | 
|  | host_triple_os = "apple-darwin" | 
|  | } else if (host_os == "fuchsia") { | 
|  | host_triple_os = "fuchsia" | 
|  | } else { | 
|  | assert(false, "Unrecognized host OS: $host_os") | 
|  | } | 
|  | host_triple = "$host_triple_cpu-$host_triple_os" | 
|  |  | 
|  | sdk_name = target_name | 
|  | if (defined(invoker.name)) { | 
|  | sdk_name = invoker.name | 
|  | } | 
|  |  | 
|  | # Generates the manifest. | 
|  | sdk_molecule(generation_target_name) { | 
|  | # Do not expose this molecule to other targets. Depending directly on the | 
|  | # contents of an SDK foregoes API verification, which is not desirable. | 
|  | visibility = [ ":$verify_api_target_name" ] | 
|  |  | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "assert_no_deps", | 
|  | "category", | 
|  | "deps", | 
|  | "testonly", | 
|  | ]) | 
|  |  | 
|  | if (!defined(deps)) { | 
|  | deps = [] | 
|  | } | 
|  | deps += [ "//build/sdk/meta" ] | 
|  | } | 
|  |  | 
|  | intermediate_manifest_file = "$target_gen_dir/$generation_target_name.sdk" | 
|  |  | 
|  | computed_api_file = "$root_out_dir/sdk/api/$sdk_name" | 
|  |  | 
|  | # Verify that the contents of the SDK have not changed. | 
|  | action(verify_api_target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | script = "//build/sdk/verify_sdk_api.py" | 
|  |  | 
|  | inputs = [ intermediate_manifest_file ] | 
|  |  | 
|  | outputs = [ computed_api_file ] | 
|  |  | 
|  | args = [ | 
|  | "--manifest", | 
|  | rebase_path(intermediate_manifest_file), | 
|  | "--updated", | 
|  | rebase_path(computed_api_file), | 
|  | ] | 
|  |  | 
|  | # TODO(fxbug.dev/5535): always set this argument. | 
|  | if (defined(invoker.api)) { | 
|  | inputs += [ invoker.api ] | 
|  | args += [ | 
|  | "--reference", | 
|  | rebase_path(invoker.api), | 
|  | ] | 
|  | } | 
|  |  | 
|  | if (warn_on_sdk_changes) { | 
|  | args += [ "--warn" ] | 
|  | } | 
|  |  | 
|  | public_deps = [ ":$generation_target_name" ] | 
|  | } | 
|  |  | 
|  | final_manifest_file = "$root_out_dir/sdk/manifest/$sdk_name" | 
|  |  | 
|  | # Copies the manifest to a central location. | 
|  | copy(copy_target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | sources = [ intermediate_manifest_file ] | 
|  |  | 
|  | outputs = [ final_manifest_file ] | 
|  |  | 
|  | deps = [ ":$verify_api_target_name" ] | 
|  | } | 
|  |  | 
|  | # Verifies that the manifest is valid. | 
|  | validate_json(verification_target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | data = final_manifest_file | 
|  |  | 
|  | schema = "//build/sdk/manifest_schema.json" | 
|  |  | 
|  | deps = [ ":$copy_target_name" ] | 
|  | } | 
|  |  | 
|  | sdk_meta_file = "$target_gen_dir/$sdk_name.sdk_meta.json" | 
|  |  | 
|  | # Generates a metadata file describing the various parts of the SDK. | 
|  | action(meta_target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | script = "//build/sdk/generate_meta.py" | 
|  |  | 
|  | inputs = [ final_manifest_file ] | 
|  |  | 
|  | outputs = [ sdk_meta_file ] | 
|  |  | 
|  | args = [ | 
|  | "--manifest", | 
|  | rebase_path(final_manifest_file), | 
|  | "--meta", | 
|  | rebase_path(sdk_meta_file), | 
|  | "--target-arch", | 
|  | target_triple, | 
|  | "--host-arch", | 
|  | host_triple, | 
|  | "--schema-version", | 
|  | sdk_metadata_schema_version, | 
|  | ] | 
|  |  | 
|  | if (defined(invoker.id) && invoker.id != "") { | 
|  | args += [ | 
|  | "--id", | 
|  | invoker.id, | 
|  | ] | 
|  | } | 
|  |  | 
|  | public_deps = [ | 
|  | ":$copy_target_name", | 
|  | ":$verification_target_name", | 
|  | ] | 
|  | } | 
|  |  | 
|  | # Verifies that the manifest metadata is valid. | 
|  | validate_json(verify_meta_target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | data = sdk_meta_file | 
|  |  | 
|  | schema = "//build/sdk/meta/manifest.json" | 
|  |  | 
|  | public_deps = [ ":$meta_target_name" ] | 
|  | } | 
|  |  | 
|  | archive_manifest_file = "$target_gen_dir/$sdk_name.archive_manifest" | 
|  |  | 
|  | additional_archive_files = [ | 
|  | { | 
|  | source = sdk_meta_file | 
|  | dest = "meta/manifest.json" | 
|  | }, | 
|  | ] | 
|  |  | 
|  | # From the manifest file representing the SDK, generates a list of the files | 
|  | # going into the final archive. | 
|  | action(archive_manifest_target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | script = "//build/sdk/generate_archive_manifest.py" | 
|  |  | 
|  | sources = [ "//build/sdk/sdk_common.py" ] | 
|  |  | 
|  | inputs = [ final_manifest_file ] | 
|  |  | 
|  | outputs = [ archive_manifest_file ] | 
|  |  | 
|  | args = [ | 
|  | "--manifest", | 
|  | rebase_path(final_manifest_file), | 
|  | "--output", | 
|  | rebase_path(archive_manifest_file), | 
|  | ] | 
|  |  | 
|  | foreach(file, additional_archive_files) { | 
|  | inputs += [ file.source ] | 
|  | args += [ | 
|  | "--mapping", | 
|  | file.dest, | 
|  | rebase_path(file.source), | 
|  | ] | 
|  | } | 
|  |  | 
|  | public_deps = [ ":$verify_meta_target_name" ] | 
|  | } | 
|  |  | 
|  | if (build_sdk_archives) { | 
|  | # Generates the final archive. | 
|  | local_archive = "$target_gen_dir/$target_name.tar.gz" | 
|  |  | 
|  | archive_generate_target_name = "${archive_target_name}_generate" | 
|  |  | 
|  | compiled_action(archive_generate_target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | tool = "//build/tools/tarmaker" | 
|  |  | 
|  | inputs = [ archive_manifest_file ] | 
|  |  | 
|  | outputs = [ local_archive ] | 
|  |  | 
|  | args = [ | 
|  | "-manifest", | 
|  | rebase_path(archive_manifest_file), | 
|  | "-output", | 
|  | rebase_path(local_archive), | 
|  | ] | 
|  |  | 
|  | deps = [ ":$archive_manifest_target_name" ] | 
|  | } | 
|  |  | 
|  | copy(archive_target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | sources = [ local_archive ] | 
|  |  | 
|  | outputs = [ "$root_out_dir/sdk/archive/$sdk_name.tar.gz" ] | 
|  |  | 
|  | public_deps = [ ":$archive_generate_target_name" ] | 
|  | } | 
|  | } else { | 
|  | group(archive_target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | deps = [ ":$archive_manifest_target_name" ] | 
|  | } | 
|  | } | 
|  |  | 
|  | group(main_target_name) { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | public_deps = [ ":$archive_target_name" ] | 
|  | } | 
|  |  | 
|  | fidl_json_file = "$target_gen_dir/$sdk_name.fidl_json.txt" | 
|  |  | 
|  | # Generate a helpful list of all of the JSON for the fidl in this SDK | 
|  | generated_file(fidl_json_target_name) { | 
|  | testonly = true | 
|  | deps = [ ":$main_target_name" ] | 
|  | outputs = [ "$fidl_json_file" ] | 
|  | data_keys = [ "fidl_json" ] | 
|  | } | 
|  |  | 
|  | stamp_file = "$target_gen_dir/$target_name.exported" | 
|  |  | 
|  | action("${target_name}_export") { | 
|  | forward_variables_from(invoker, [ "testonly" ]) | 
|  |  | 
|  | script = "//build/sdk/export_sdk.py" | 
|  |  | 
|  | inputs = [ archive_manifest_file ] | 
|  |  | 
|  | outputs = [ stamp_file ] | 
|  |  | 
|  | args = [ | 
|  | "--out-dir", | 
|  | rebase_path("$root_out_dir/sdk/exported/$sdk_name"), | 
|  | "--stamp-file", | 
|  | rebase_path(stamp_file), | 
|  | "--manifest", | 
|  | rebase_path(archive_manifest_file), | 
|  | ] | 
|  |  | 
|  | deps = [ ":$archive_manifest_target_name" ] | 
|  | } | 
|  | } |