# Copyright 2020 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

import("$dir_pw_build/exec.gni")
import("$dir_pw_build/target_types.gni")

# Preprocess a linker script and turn it into a target.
#
# Note: to use this template, pw_cc_command must be specified in your target's
# config. It should match the name of the C compiler your target uses (e.g.
# arm-none-eabi-gcc).
#
# In lieu of direct GN support for linker scripts, this template makes it
# possible to run the C Preprocessor on a linker script file so defines can
# be properly evaluated before the linker script is passed to the dir_pw_build
#
# TODO(pwbug/53): This template serves as a stand-in until native GN support for
# linker scripts is added.
#
# Args:
#  linker_script: The linker script to send through the C preprocessor.
#
#  defines: Preprocessor defines to apply when running the C preprocessor.
#
#  cflags: Flags to pass to the C compiler.
#
#  inputs: Files that, when changed, should trigger a re-build of the linker
#    script. linker_script is implicitly added to this by the template.
#
# Example:
#
#   pw_linker_script("generic_linker_script") {
#     defines = [
#       "PW_HEAP_SIZE=1K",
#       "PW_NOINIT_SIZE=512"
#     ]
#     linker_script = "basic_script.ld"
#   }
#
template("pw_linker_script") {
  assert(
      defined(pw_cc_command) && pw_cc_command != "",
      "pw_cc_command has not been properly configured. This variable must be " +
          "defined to enable linker script preprocessing.")

  assert(
      defined(invoker.linker_script) && invoker.linker_script != "",
      "$target_name did not set `linker_script` to refer to a valid linker " +
          "script. This variable is required for linker script targets.")

  _final_linker_script = "${target_gen_dir}/${target_name}_final.ld"

  # This action invokes the C compiler provided by the target to preprocess the
  # linker script.
  pw_exec("${target_name}_preprocess") {
    program = pw_cc_command
    inputs = [ invoker.linker_script ]
    args = [
      # Run compiler in preprocessor-only mode.
      "-E",

      # Do not generate linemarkers in output.
      "-P",

      # Do not discard comments.
      "-C",

      # Treat the following file as a C file.
      "-x",
      "c",
      get_path_info(invoker.linker_script, "abspath"),
    ]

    # Include any explicitly listed c flags.
    if (defined(invoker.cflags)) {
      args += cflags
    }

    # Add defines.
    if (defined(invoker.defines)) {
      args += process_file_template(invoker.defines, "-D{{source_name_part}}")
    }

    # Set output file.
    args += [
      "-o",
      _final_linker_script,
    ]
    outputs = [ _final_linker_script ]
  }

  # This config adds a the linker script produced by the preprocess action to
  # the linker flags.
  config("${target_name}_config") {
    inputs = [ invoker.linker_script ]
    if (!defined(invoker.ldflags)) {
      ldflags = []
    }
    ldflags += [ "-T" + rebase_path(_final_linker_script) ]
  }

  # The target that adds the linker script config to this library and everything
  # that depends on it.
  pw_source_set(target_name) {
    inputs = [ _final_linker_script ]
    if (defined(invoker.inputs)) {
      inputs += invoker.inputs
    }
    all_dependent_configs = [ ":${target_name}_config" ]
    deps = [ ":${target_name}_preprocess" ]
  }
}
