# Copyright 2023 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/cpp/library_headers.gni")

# Compile a binary blob into an RODATA object that can be linked into code.
#
# This produces a source_set() target that compiles generated assembly code to
# define a pair of symbols around an RODATA object containing the contents of a
# raw binary input file. C++ code with this target in $deps can access the blob
# by using `#include "${output_name}_blob.h"` to provide a constexpr function
# `${output_name}_blob()` that returns cpp20::span<const std::byte>.
#
# Note that the RODATA object will have no special alignment guarantees but
# instead must be copied at runtime to someplace that is aligned appropriately
# for how the data will be used.
#
# Parameters
#
#   * sources
#     - Required: Must be a list of exactly one file. This is the file that
#     will be embedded as an RODATA object.
#     - Type: list(file)
#
#   * deps, public_deps
#     - Optional: Should include anything that generates $sources.
#     Use $public_deps to propagate public_configs and public_deps.
#     - Type: list(label)
#     - Default: []
#
#   * output_name
#     - Optional: This is used to choose the symbol names in the generated
#     linkable object. The names will be "embedded_blob.start.$output_name"
#     and "embedded_blob.end.$output_name" for symbols that point to the
#     start and end of the object respectively. These symbols are used by
#     the "${output_name}_blob()" C++ constexpr function, which is defined
#     in a generated header file called "${output_name}_blob.h".
#     - Type: string
#     - Default: target_name
#
#   * visibility, testonly
#     - Optional: As for source_set().
#
template("embedded_blob") {
  label = get_label_info(":$target_name", "label_with_toolchain")

  assert(defined(invoker.sources),
         "sources is required for embedded_blob() $label")

  if (defined(invoker.output_name)) {
    output_name = invoker.output_name
  } else {
    output_name = target_name
  }

  blobs = invoker.sources
  assert(blobs != [] && blobs == [ blobs[0] ],
         "sources must have exactly one element for embedded_blob() $label")
  blob = blobs[0]
  blob_path = rebase_path(blob, root_build_dir)

  start_label = "embedded_blob.start.$output_name"
  end_label = "embedded_blob.end.$output_name"

  main_target = target_name
  gen_asm_target = "_embedded_blob.$target_name.gen_asm"
  gen_header_target = "_embedded_blob.$target_name.gen_header"
  headers_target = "_embedded_blob.$target_name.headers"

  gen_asm_file = "$target_gen_dir/embedded_blob.$output_name.S"
  gen_header_file = "$target_gen_dir/include/${output_name}_blob.h"

  generated_file(gen_asm_target) {
    forward_variables_from(invoker, [ "testonly" ])
    visibility = [ ":*" ]

    outputs = [ gen_asm_file ]
    output_conversion = "list lines"
    contents = [
      "// Generated by $label. DO NOT EDIT!",
      ".section .rodata, \"a\", %progbits",
      ".globl $start_label",
      "$start_label:",
      ".incbin \"$blob_path\"",
      ".size $start_label, . - $start_label",
      ".globl $end_label",
      "$end_label:",
    ]
  }

  generated_file(gen_header_target) {
    forward_variables_from(invoker, [ "testonly" ])
    visibility = [ ":*" ]

    outputs = [ gen_header_file ]
    output_conversion = "list lines"
    contents = [
      "// Generated by $label. DO NOT EDIT!",
      "#pragma once",
      "#include <lib/stdcompat/span.h>",
      "constexpr cpp20::span<const std::byte> ${output_name}_blob() {",
      "  extern const std::byte start[] __asm__(\"$start_label\");",
      "  extern const std::byte end[] __asm__(\"$end_label\");",
      "  return {+start, +end};",
      "}",
    ]
  }

  library_headers(headers_target) {
    forward_variables_from(invoker, [ "testonly" ])
    visibility = [ ":*" ]
    include_dir = get_path_info(gen_header_file, "dir")
    headers = [ get_path_info(gen_header_file, "file") ]
    deps = [ ":$gen_header_target" ]
    public_deps = [ "//sdk/lib/stdcompat" ]
  }

  source_set(main_target) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "public_deps",
                             "visibility",
                             "testonly",
                           ])
    if (!defined(deps)) {
      deps = []
    }
    if (!defined(public_deps)) {
      public_deps = []
    }
    public_deps += [ ":$headers_target" ]
    deps += [ ":$gen_asm_target" ]
    sources = [ gen_asm_file ]
    inputs = [ blob ]
  }
}
