chromium/third_party/fuchsia-gn-sdk/src/package_tool.gni

# Copyright 2020 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("gn_configs.gni")
import("gn_sdk_configs.gni")

# Template for running the ffx package-tool tool for building and archiving
# fuchsia packages.
#
# Parameters
#   package_name - defaults to target_name
#   archive_manifest - required
#   command - the packaging step to perform valid steps are build, archive
#   subpackages_manifest (with "build" command only) - optional
#
# Forwarded parameters
#       testonly
#       deps
#       public_deps
#       visibility
template("fuchsia_package_tool") {
  forward_variables_from(invoker, [ "*" ])
  action(target_name) {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "deps",
                             "public_deps",
                             "visibility",
                           ])
    _valid_commands = [
      "build",
      "archive",
    ]
    assert(defined(invoker.archive_manifest), "archive_manifest is required.")
    archive_manifest = invoker.archive_manifest

    assert(defined(invoker.command), "command is required")
    assert(invoker.command == "build" || invoker.command == "archive",
           "invalid command. valid commands are ${_valid_commands}")
    command = invoker.command

    package_name = target_name
    if (defined(invoker.package_name)) {
      package_name = invoker.package_name
    }

    # tool path
    _ffx_package_tool_path = "${fuchsia_tool_dir}/ffx_tools/ffx-package"
    script = gn_sdk_root + "/gn_run_binary.py"

    # output files
    _pkg_out_dir = "${target_gen_dir}/${package_name}"
    _pkg_output_manifest = "${_pkg_out_dir}/package_manifest.json"
    _meta_far_file = "${_pkg_out_dir}/meta.far"

    inputs = [
      # Depend on the SDK hash, to ensure rebuild if the SDK tools change.
      fuchsia_sdk_manifest_file,
      _ffx_package_tool_path,
      archive_manifest,
    ]

    args = [
      rebase_path(_ffx_package_tool_path, root_build_dir),
      "package",
    ]

    if (command == "build") {
      # "ffx package build" flow
      _meta_far_file = "${_pkg_out_dir}/meta.far"

      outputs = [
        _meta_far_file,
        _pkg_output_manifest,
      ]
      depfile = "${_meta_far_file}.d"
      args += [
        "build",
        rebase_path(archive_manifest, root_build_dir),
        "--out",
        rebase_path(_pkg_out_dir, root_build_dir),
        "--published-name",
        package_name,
        "--depfile",
      ]

      if (defined(invoker.subpackages_manifest)) {
        inputs += [ invoker.subpackages_manifest ]
        args += [
          "--subpackages-build-manifest-path",
          rebase_path(invoker.subpackages_manifest, root_build_dir),
        ]
      }

      assert(fuchsia_target_api_level >= 1)
      args += [
        "--api-level",
        "${fuchsia_target_api_level}",
      ]
    } else if (command == "archive") {
      # "ffx package archive create" flow
      _final_far_file = "$_pkg_out_dir/${package_name}.far"
      _final_far_depfile = "${_final_far_file}.d"

      inputs += [ _meta_far_file ]
      outputs = [ _final_far_file ]
      depfile = _final_far_depfile
      args += [
        "archive",
        "create",
        rebase_path(_pkg_output_manifest, root_build_dir),
        "--out",
        rebase_path(_final_far_file, root_build_dir),
        "--depfile",
        rebase_path(_final_far_depfile, root_build_dir),
      ]

      metadata = {
        # Export information for using this package as a subpackage.
        subpackages_manifest_data = [
          {
            package_manifest_file =
                rebase_path(_pkg_output_manifest, root_build_dir)
          },
        ]

        # Stop subpackage discovery from recursing into our own subpackages.
        # Used by `fuchsia_package_tool_subpackages_manifest` below.
        subpackages_manifest_barrier = []
      }
    }
  }
}

# Generates a subpackages manifest that references a list of packages.
#
# Parameters
#   subpackages - list of packages to be referenced by the generated manifest.
#   outputs - list with a single element, the output manifest file.
#
# Forwarded parameters
#       testonly
#       visibility
template("fuchsia_package_tool_subpackages_manifest") {
  generated_file(target_name) {
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])

    assert(defined(invoker.subpackages), "subpackages is required.")
    deps = invoker.subpackages

    assert(defined(invoker.outputs), "outputs is required.")
    outputs = invoker.outputs

    data_keys = [ "subpackages_manifest_data" ]
    walk_keys = [ "subpackages_manifest_barrier" ]
    output_conversion = "json"
  }
}