blob: 84bbd7f0090166a5440366b4b0ffe554be2ad445 [file] [log] [blame]
# 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/bazel/bazel_fuchsia_sdk.gni")
import("//build/bazel/generate_prebuilt_dir_content_hash.gni")
import("//build/bazel/logging.gni")
import("//build/bazel/remote_services.gni")
import("//build/config/fuchsia/platform_version.gni")
import("//build/sdk/config.gni")
import("//build/sdk/idk.gni")
import("//build/sdk/sdk_collection.gni")
# The list of target cpu architectures supported by @fuchsia_sdk.
if (bazel_fuchsia_sdk_all_cpus) {
_fuchsia_sdk_target_cpus = idk_target_cpus
} else {
_fuchsia_sdk_target_cpus = [ target_cpu ]
}
# Ensure that the //build/bazel/bazel_sdk:idk target
# populates `$OUTPUT_DIR/sdk/exported/bazel_fuchsia_sdk_idk`.
idk("idk") {
output_name = "bazel_fuchsia_sdk_idk"
sdk_collection_label = "//sdk:core"
target_cpus = _fuchsia_sdk_target_cpus
api_levels = platform_version.build_time_supported_api_levels
# TODO(https://fxbug.dev/306723826): Deal with the fact that the mac builders
# are too slow to enable this setting, and therefore the mac IDK won't have
# per-api-level prebuilts.
if (host_os == "mac") {
api_levels = []
}
}
# Generate content hash files for python and Clang toolchains.
#
# These will be used to trigger new runs of the bazel_sdk_test_xxx targets
# if the content of these directory changes. And the
# //build/bazel_sdk/tests/script/bazel_test.py script will ensure that their
# values are passed to the test workspace.
#
_prebuilt_python_content_hash = "$target_out_dir/prebuilt_python.content_hash"
_prebuilt_clang_content_hash = "$target_out_dir/prebuilt_clang.content_hash"
generate_prebuilt_dir_content_hash("prebuilt_python_content_hash") {
source_dir = "//prebuilt/third_party/python3/${host_os}-${host_cpu}"
output = _prebuilt_python_content_hash
cipd_name = "cpython3"
exclude_suffixes = [ ".pyc" ]
}
generate_prebuilt_dir_content_hash("prebuilt_clang_content_hash") {
source_dir = "//prebuilt/third_party/clang/${host_os}-${host_cpu}"
output = _prebuilt_clang_content_hash
cipd_name = "clang"
}
# Generate remote service configs into a bazelrc.
_services_bazelrc_path = "$target_out_dir/remote_services.bazelrc"
action("remote_services_bazelrc") {
script = "//build/bazel/scripts/generate_services_bazelrc.py"
_output = _services_bazelrc_path
outputs = [ _output ]
_template = "//build/bazel/templates/template.remote_services.bazelrc"
_configs = [
"//build/rbe/fuchsia-reproxy.cfg",
"//build/rbe/fuchsia-rewrapper.cfg",
]
inputs = [ _template ] + _configs
args = [
"--template",
rebase_path(_template, root_build_dir),
"--output",
rebase_path(_output, root_build_dir),
"--cfgs",
] + rebase_path(_configs, root_build_dir)
}
# Run the //build/bazel_sdk/tests/scripts/bazel_test.sh
# script, which runs the test suite for the Fuchsia Bazel
# SDK rules, using the IDK built from the platform build
# as well as the prebuilt Clang in the Fuchsia source
# checkout.
#
# Note that this does not use bazel_action() because:
#
# 1) The test suite is run in its own Bazel workspace,
# completely separate from the one used by the platform
# build.
#
# 2) bazel_action() may change the target build configuration
# in ways that are not supported by the test suite, for
# example, changing `is_debug` or `optimize` in args.gn may
# change Bazel output paths, which will fail tests that rely
# on golden file that embeds hard-coded versions of them.
#
# 3) There is no way to list all inputs / outputs properly.
#
# Arguments:
# target_cpu: (optional)
# Target cpu name. Default to current_cpu otherwise.
#
# idk_exported_dir: (optional)
# GN path to an IDK `exported` directory to use to run the
# test suite. Requires `idk_exported_target` to be set as well.
#
# idk_exported_target: (optional)
# GN label of target used to generate the directory pointed to by
# `idk_exported_dir`, if provided.
#
# remote_build: (optional)
# Override the global `enable_bazel_remote_rbe` setting for building.
# Set to false to prevent use of remote services for building.
template("bazel_sdk_tests_for") {
_use_idk_exported = defined(invoker.idk_exported_path)
if (_use_idk_exported) {
_idk_exported_path = invoker.idk_exported_path
_idk_exported_target = invoker.idk_exported_target
}
_target_cpu = target_cpu
if (defined(invoker.target_cpu)) {
_target_cpu = invoker.target_cpu
}
action(target_name) {
testonly = true
script = "//build/bazel_sdk/tests/scripts/bazel_test.py"
inputs = [ "//prebuilt/third_party/bazel/${host_os}-${host_cpu}/bazel" ]
outputs = [
"$target_gen_dir/$target_name.stamp",
"$target_out_dir/$target_name.bazel_events_logs.json",
]
_exec_log = "$target_out_dir/$target_name.bazel_exec_log.pb.zstd"
depfile = "$target_gen_dir/$target_name.d"
# Provide a distinct output_base for each test. This is because the
# fuchsia_sdk_repository() rule call does not use a version file in
# //build/bazel_sdk/tests/WORKSPACE.bazel, and the content of @fuchsia_sdk
# will not be regenerated when we change the target cpu architecture.
#
# For example (assuming a shared output_base directory):
#
# fx clean
#
# # This populates @fuchsia_sdk//:generated_constants.bzl with
# # constants = struct(host_cpus = ["x64"], target_cpus = ["x64"])
# # the test suite passes though.
# #
# fx build bazel_sdk_tests
#
# # This does not regenerate @fuchsia_sdk//:generated_constants.bzl
# # but the test suite passes because it has the right target_cpus list.
# #
# fx build bazel_sdk_tests_idk_x64
#
# # This does not regenerate @fuchsia_sdk//:generated_constants.bzl
# # And Bazel complains there is not C++ toolchain for arm64 because
# # register_clang_toolchains() uses the content of constants.target_cpus
# # to declare C++ toolchains, and that one does not include an "arm64"
# # item, even though the IDK provides all the necessary prebuilt
# # binaries for it.
# #
# fx build bazel_sdk_tests_idk_arm64
#
#
_output_base = "${target_gen_dir}/${target_name}/output_base"
_output_user_root = "${target_gen_dir}/${target_name}/output_user_root"
args = [
"--verbose",
"--fuchsia_source_dir=" + rebase_path("//", root_build_dir),
"--output_base=" + rebase_path(_output_base, root_build_dir),
"--output_user_root=" + rebase_path(_output_user_root, root_build_dir),
"--target_cpu=${_target_cpu}",
"--bazel=" + rebase_path(inputs[0], root_build_dir),
"--stamp-file=" + rebase_path(outputs[0], root_build_dir),
"--depfile=" + rebase_path(depfile, root_build_dir),
"--quiet",
]
deps = []
_remote_build = enable_bazel_remote_rbe
if (defined(invoker.remote_build)) {
_remote_build = invoker.remote_build
}
if (_remote_build || bazel_upload_build_events != "") {
args += [
"--bazelrc",
rebase_path(_services_bazelrc_path, root_build_dir),
]
deps += [ ":remote_services_bazelrc" ]
}
if (_remote_build) {
args += [ "--bazel-config=remote" ]
}
if (bazel_upload_build_events != "") {
args += [ "--bazel-config=" + bazel_upload_build_events ]
}
if (_use_idk_exported) {
args += [
"--fuchsia_idk_directory",
rebase_path(_idk_exported_path, root_build_dir),
]
deps += [ _idk_exported_target ]
} else {
args += [
"--fuchsia_build_dir",
rebase_path(root_build_dir, root_build_dir),
]
deps += [ "//build/bazel:generate_fuchsia_sdk_repository" ]
}
args += [
"--prebuilt-python-version-file",
rebase_path(_prebuilt_python_content_hash, root_build_dir),
"--prebuilt-clang-version-file",
rebase_path(_prebuilt_clang_content_hash, root_build_dir),
]
if (bazel_execution_logs) {
args += [
"--bazel-exec-log-compact",
rebase_path(_exec_log, root_build_dir),
]
}
args += [
"--bazel-build-events-log-json",
rebase_path(outputs[1], root_build_dir),
]
metadata = {
# Used by //:bazel_build_events_logs Build API module
bazel_build_events_log = [
{
gn_label = get_label_info(":$target_name", "label_no_toolchain")
build_events_log = rebase_path(outputs[1], root_build_dir)
format = "json"
},
]
}
deps += [
":prebuilt_clang_content_hash",
":prebuilt_python_content_hash",
]
pool = "//:console"
hermetic_deps = false
# The build events log contains absolute paths written by Bazel!
no_output_dir_leaks = false
}
}
foreach(cpu, _fuchsia_sdk_target_cpus) {
# Run the test suite against the internal IDK used to populate
# @fuchsia_sdk, for the current target cpu only.
bazel_sdk_tests_for("bazel_sdk_tests_${cpu}") {
target_cpu = cpu
}
}
# Run the test suite against hte internal IDK used to populate
# @fuchsia_sdk, once per supported target CPU architecture, if
# bazel_fuchsia_sdk_all_cpus is set, otherwise only against
# the current target_cpu value.
group("bazel_sdk_tests") {
testonly = true
deps = []
foreach(cpu, _fuchsia_sdk_target_cpus) {
deps += [ ":bazel_sdk_tests_${cpu}" ]
}
}
foreach(cpu, idk_target_cpus) {
# This target runs the test suite against a locally-generated IDK
# (which includes support for all target architectures), but only
# for target_cpu. E.g. `bazel_sdk_tests_arm64` will run the
# test suite with a build configuration that generates Fuchsia/arm64
# binaries.
#
# Note that the IDK does _not_ contain //sdk:driver atoms.
# (see //sdk:final_fuchsia_idk definition for details).
bazel_sdk_tests_for("bazel_sdk_tests_idk_${cpu}") {
target_cpu = cpu
idk_exported_path = "$root_build_dir/sdk/exported/fuchsia_idk"
idk_exported_target = "//sdk:final_fuchsia_idk.exported"
}
}
# This target runs the test suite against each target architecture
# supported by the IDK. Currently, this runs multiple instances of
# the test suite, one per target cpu.
group("bazel_sdk_tests_idk") {
testonly = true
deps = []
foreach(cpu, idk_target_cpus) {
deps += [ ":bazel_sdk_tests_idk_${cpu}" ]
}
}
group("tests") {
testonly = true
deps = [
":bazel_sdk_tests",
# DO NOT INCLUDE bazel_sdk_tests_idk here to avoid making all core builds
# longer than necessary (https://fxbug.dev/42082370). It is still possible
# to invoke the target manually during local development though.
# ":bazel_sdk_tests_idk",
]
}