blob: b78ed70d15f579c2e01d05a8a2260172c1548f50 [file]
# Copyright 2025 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/bazel/bazel_build_group.gni")
import("//build/bazel/bazel_root_targets_list.gni")
import("//build/host.gni")
if (current_toolchain == default_toolchain) {
# Generates a single bazel_build_group() to build all root bazel targets at
# once.
#
# This template does not take any arguments. It generates a bazel_build_group
# based on entries from `resolved_bazel_root_targets`.
#
# This target, because it runs `bazel build`, is expected to only expand in the
# default toolchain.
#
# Subtargets are created based on `gn_subtarget_name` from
# `resolved_bazel_root_targets` list.
#
# NOTE: To consume host binaries, prefer subtargets from
# `install_bazel_host_tools`, which are conventionally expanded in the host
# toolchain.
#
template("bazel_root_targets_build_group") {
assert(
current_toolchain == default_toolchain,
"bazel_host_tools_build_group should only be expanded in the default toolchain")
assert(resolved_bazel_root_targets != [],
"unexpected empty resolved_bazel_root_target")
_subtargets = []
foreach(_root_target, resolved_bazel_root_targets) {
_subtargets += [
{
bazel_target = _root_target.bazel_label
gn_target_name =
get_label_info(_root_target.gn_subtarget_label, "name")
if (defined(_root_target.copy_outputs)) {
copy_outputs = _root_target.copy_outputs
} else {
copy_outputs = [
{
bazel = "{{BAZEL_TARGET_OUT_DIR}}/${_root_target.bazel_name}"
ninja = _root_target.ninja_name
},
]
}
},
]
}
bazel_build_group(target_name) {
no_sdk = true
host = true
subtargets = _subtargets
update_rust_project = true
}
# This template doesn't take any arguments, ensure GN doesn't
# complain about the unused invoker scope.
not_needed([ "invoker" ])
}
}
if (current_toolchain == host_toolchain) {
# Creates subtargets for host tools from root Bazel targets.
#
# These targets follows GN convention to make host tool available in the host
# toolchain, with relevant metadata attached.
#
# These subtargets are created in the host toolchain for each entry in
# `resolved_bazel_root_targets`:
#
# ${host_bin_label}
# Copies the binary to ${host_out_dir}.
#
# ${host_bin_label}.host_tool
# Optionally created when `install_host_tool` is true.
# Copies the binary to ${host_tools_dir}
#
template("install_bazel_host_tools") {
assert(
current_toolchain == host_toolchain,
"install_bazel_host_tools should only be expanded in the host toolchain")
_all_deps = []
foreach(_root_target, resolved_bazel_root_targets) {
_gn_target_name = get_label_info(_root_target.host_bin_label, "name")
_ninja_output =
get_label_info(":${_root_target.gn_subtarget_label}",
"target_out_dir") + "/${_root_target.ninja_name}"
copy(_gn_target_name) {
outputs = [ "${host_out_dir}/${_root_target.ninja_name}" ]
sources = [ _ninja_output ]
deps = [ _root_target.gn_subtarget_label ]
metadata = {
# Used by //:tool_paths build API module
tool_paths = [
{
os = host_os
cpu = host_cpu
name = _root_target.ninja_name
label =
get_label_info(":${_gn_target_name}", "label_with_toolchain")
path = rebase_path(outputs[0], root_build_dir)
},
]
}
}
_all_deps += [ ":${_gn_target_name}" ]
if (_root_target.install_host_tool) {
_host_tool_target = "${_gn_target_name}.host_tool"
if (current_toolchain == toolchain_variant.base) {
# There is more than one host_toolchain when variants are involved, or when
# building tools for multiple host environments, so we only want to do this
# copy in the base host toolchain to avoid multiple targets generating the
# same output.
copy(_host_tool_target) {
outputs = [ "${host_tools_dir}/${_root_target.ninja_name}" ]
sources = [ _ninja_output ]
deps = [ _root_target.gn_subtarget_label ]
}
} else {
# Redirect to the base host_toolchain, where the copy rule above is.
group(_host_tool_target) {
public_deps = [ ":${_host_tool_target}(${toolchain_variant.base})" ]
}
}
_all_deps += [ ":${_host_tool_target}" ]
}
}
group(target_name) {
deps = _all_deps
}
# This template doesn't take any arguments, ensure GN doesn't
# complain about the unused invoker scope.
not_needed([ "invoker" ])
}
}