blob: 7a1580dd780efc3b7591a83d0dbfd7c67077d038 [file] [log] [blame]
# 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.
# Like action() but using utility binaries from the C/C++ toolchain.
# This is the way to use `nm`, `objcopy`, etc.
#
# Parameters
#
# utils (required)
# [list of strings] Utilities to use, e.g. "nm", "objcopy", "objdump".
#
# script (optional)
# [string] Same as for action(). The script receives an implicit
# argument for each element in $utils giving the command to run.
# If omitted, then $utils must have only one element and that command
# itself will be run with $args just as given.
#
# args (required)
# [list of strings] Same as for action(). If there is a $script,
# the implicit $utils arguments precede $args.
#
# deps, inputs, outputs, sources, testonly, visibility
# Same as for action().
#
template("toolchain_utils_action") {
assert(defined(invoker.utils),
"toolchain_utils_action(\"$target_name\") requires `utils`")
forward_variables_from(invoker, [ "script" ])
utils_inputs = []
utils_paths = []
if (toolchain.tool_dir != "") {
# The toolchain binaries are in a specified location (e.g. a prebuilt).
foreach(util, invoker.utils) {
if (util == "cc") {
util = toolchain.cc
} else {
util = "${toolchain.tool_prefix}${util}"
}
util = "${toolchain.tool_dir}/${util}"
utils_inputs += [ util ]
utils_paths += [ rebase_path(util, root_build_dir) ]
}
} else {
# The toolchain binaries are just found in the system PATH.
# They won't be used as dependencies.
if (!defined(script)) {
# If there's no script, utils_paths[0] will become the script.
# But the script has to be a known location that's a dependency.
# So use a dummy wrapper as the script.
script = "/usr/bin/env"
}
foreach(util, invoker.utils) {
if (util == "cc") {
util = toolchain.cc
} else {
util = "${toolchain.tool_prefix}${util}"
}
utils_paths += [ util ]
}
}
action(target_name) {
forward_variables_from(invoker,
"*",
[
"args",
"script",
"utils",
])
if (!defined(inputs)) {
inputs = []
}
inputs += utils_inputs
if (defined(script)) {
args = utils_paths + invoker.args
} else {
script = rebase_path(utils_paths[0], "", root_build_dir)
assert(
utils_paths == [ utils_paths[0] ],
"toolchain_utils_action(\"$target_name\") without `script` must have exactly one element in `utils`")
args = invoker.args
}
}
}
# Define an action to convert an ELF file to a raw binary image file.
#
# Parameters
#
# sources (required)
# [list of one string] Input file.
#
# outputs (required)
# [list of one string] Output file.
#
# deps, testonly, visibility
# Same as for action().
#
template("image_binary") {
toolchain_utils_action(target_name) {
forward_variables_from(invoker,
[
"deps",
"metadata",
"outputs",
"sources",
"testonly",
"visibility",
])
assert(sources == [ sources[0] ], "sources must have exactly one element")
assert(outputs == [ outputs[0] ], "outputs must have exactly one element")
utils = [ "objcopy" ]
args = [
"-O",
"binary",
rebase_path(sources[0], root_build_dir),
rebase_path(outputs[0], root_build_dir),
]
}
}