blob: 8ae0cf204a368ac34089b746e31690e10a5aa098 [file] [log] [blame]
# Copyright 2020 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT
import("$zx/public/gn/toolchain/c_utils.gni")
import("$zx_build/public/gn/migrated_targets.gni")
if (zx == "/") {
import("$zx/public/gn/toolchain/environment_redirect.gni")
}
_is_phys = toolchain.environment == "kernel.phys" ||
toolchain.environment == "kernel.phys32"
# These both work together and must be presented in this order (for BFD ld).
_phys_linker_scripts = [
"$zx/kernel/phys/phys-end.ld",
"$zx/kernel/phys/phys.ld",
]
# Build an executable for the phys environment.
#
# This defines one public target whose output is the raw binary image.
# The target is used like executable(), but deps on this target from
# other environments transparently redirect to the phys environment, and
# a custom linker script is always required. There are also implicit
# deps to supply the phys entry point code that calls the C++ PhysMain
# via the "main.h" API.
#
# Parameters
#
# * output_extension
# - Optional: See executable(), but defaults to "bin".
# - Default: "bin"
#
# * tags
# - Optional: Tags to put in the //:images metadata for the target.
# - Type: list(string)
# - Default: []
#
# See executable() for other parameters.
#
template("phys_executable") {
if (!_is_phys) {
if (zx == "/") {
environment_redirect(target_name) {
environment_label = "$zx/kernel/phys:kernel.phys"
deps = [ ":$target_name" ]
}
} else {
group(target_name) {
public_deps =
[ ":$target_name($zx/kernel/phys:kernel.phys_$current_cpu)" ]
}
}
not_needed(invoker, "*")
} else {
image_target = target_name
executable_target = "_phys_executable.$target_name.executable"
# This is the actual linking target. It creates an ELF file that acts
# as the debug file but is not used at runtime.
executable(executable_target) {
visibility = [ ":*" ]
deps = []
inputs = []
ldflags = []
forward_variables_from(invoker,
"*",
[
"metadata",
"output_dir",
"output_extension",
"visibility",
"tags",
"target_name",
])
deps += [ "$zx/kernel/phys:phys_executable.deps" ]
inputs += _phys_linker_scripts
foreach(ldscript, _phys_linker_scripts) {
ldflags += [ "-Wl,-T," + rebase_path(ldscript, root_build_dir) ]
}
if (zx == "/") {
# Don't generate a binaries.json entry for this binary.
sdk_migrated = true
}
}
# This is the main target of the template, a raw binary load image file.
image_binary(image_target) {
forward_variables_from(invoker,
[
"output_dir",
"output_extension",
"output_name",
"testonly",
"visibility",
])
if (defined(visibility)) {
# Make sure it's visible to the environment_redirect() target above.
visibility += [ ":$image_target" ]
}
deps = [ ":$executable_target" ]
# Use the same variant for the extraction that will have built the
# actual executable.
variant_target = {
match = "executable"
if (defined(invoker.output_name)) {
output_name = invoker.output_name
}
}
if (!defined(output_dir)) {
if (zx == "/") {
output_dir = target_out_dir
} else {
output_dir = root_out_dir
}
}
if (!defined(output_name)) {
output_name = target_name
}
if (!defined(output_extension)) {
output_extension = "bin"
}
output_path = "$output_dir/$output_name.$output_extension"
metadata = {
images = []
if (defined(invoker.metadata)) {
forward_variables_from(invoker.metadata, "*")
}
# For the //:images build_api_module().
images += [
{
label = get_label_info(":$target_name", "label_with_toolchain")
name = target_name
forward_variables_from(invoker, [ "tags" ])
path = rebase_path(output_path, root_build_dir)
cpu = current_cpu
# Botanist needs this exact value for images used as QEMU kernels.
type = "kernel"
},
]
}
}
}
}
if (_is_phys) {
if (zx == "/") {
# Templates like phys_executable() use this in set_defaults().
#
# Type: list(config)
phys_default_configs = []
foreach(config, toolchain.configs) {
if (config == "$config") {
phys_default_configs += [ config ]
} else if (!defined(config.types) || config.types + [ "executable" ] -
[ "executable" ] != config.types) {
phys_default_configs += config.add
phys_default_configs -= config.remove
}
}
set_defaults("phys_executable") {
configs = phys_default_configs
}
} else {
set_defaults("phys_executable") {
configs = default_executable_configs
}
}
}