blob: 982d26f08f77552c19749cd72fe6afe9b25f98fd [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.
import("//build/compiled_action.gni")
import("//build/host.gni")
import("//build/testing/host_test.gni")
import("//build/testing/host_test_data.gni")
# Declares a suite of tests for a driver's bind rules.
#
# The tests run as host tests by invoking the compiler. To avoid specifying the rules and bind
# library dependencies twice use the `tests` parameter on the bind_rules template to generate this
# target with the appropriate parameters.
#
# Parameters
#
# rules (required)
# [path]: Path to the bind rules source file.
#
# tests (required)
# [path]: Path to a test specification. The test specification is a JSON file defining a set
# of devices and the expected result of the bind rules when applied to that device. The file
# must adhere to the JSON schema defined by //src/devices/bind/debugger/tests_schema.json.
#
# target (optional)
# [label]: The test target. Defaults to target_name.
#
# deps (optional)
# [list of labels]: List of bind_library targets included by the bind rules.
#
# visibility
# Forwarded from invoker.
#
template("bind_host_test") {
assert(defined(invoker.rules), "Need a bind rules source")
assert(defined(invoker.tests), "Need a test specification")
test_target = "_${target_name}_test"
group(target_name) {
testonly = true
if (is_host) {
deps = [ ":${test_target}" ]
}
}
if (is_host) {
response_file_target = "_${target_name}_response_file"
response_file = "${target_gen_dir}/${target_name}.rsp"
test_data_dir = "${root_out_dir}/test_data/bind-tests/${target_name}"
test_data_target = "_${target_name}_test_data"
generated_file(response_file_target) {
visibility = [ ":*" ]
testonly = true
forward_variables_from(invoker, [ "deps" ])
data_keys = [ "test_sources" ]
outputs = [ "${response_file}" ]
}
host_test_data(test_data_target) {
visibility = [ ":*" ]
sources = [
"${host_tools_dir}/bindc",
invoker.rules,
invoker.tests,
response_file,
]
outputs = [ "${test_data_dir}/{{source_file_part}}" ]
deps = [
":${response_file_target}",
"//tools/bindc:host($host_toolchain)",
]
}
host_test(test_target) {
visibility = [ ":*" ]
if (defined(invoker.target)) {
target = "${invoker.target}"
} else {
target = "${target_name}"
}
binary_path = "${test_data_dir}/bindc"
rules_filename = get_path_info(invoker.rules, "file")
test_spec_filename = get_path_info(invoker.tests, "file")
response_file_filename = get_path_info(response_file, "file")
args = [
"test",
rebase_path("${test_data_dir}/${rules_filename}", root_build_dir),
"--test-spec",
rebase_path("${test_data_dir}/${test_spec_filename}", root_build_dir),
"--include-file",
rebase_path("${test_data_dir}/${response_file_filename}",
root_build_dir),
]
deps = [
":${response_file_target}",
":${test_data_target}",
"//tools/bindc:bin($host_toolchain)",
]
}
} else {
not_needed(invoker,
[
"deps",
"tests",
"rules",
"target",
test_target,
])
}
}
# Declares a suite of tests for a driver's bind rules.
#
# This template is provided for convenience. It handles redirect bind_host_test to the host
# toolchain.
#
# Parameters
#
# rules (required)
# [path]: Path to the bind rules source file.
#
# tests (required)
# [path]: Path to a test specification. The test specification is a JSON file defining a set
# of devices and the expected result of the bind rules when applied to that device. The file
# must adhere to the JSON schema defined by //src/devices/bind/debugger/tests_schema.json.
#
# target (optional)
# [label]: The test target. Defaults to target_name.
#
# deps (optional)
# [list of labels]: List of bind_library targets included by the bind rules.
#
# visibility
# Forwarded from invoker.
#
template("bind_test") {
assert(defined(invoker.rules), "Need a bind rules source")
assert(defined(invoker.tests), "Need a test specification")
test_target = "${target_name}_test"
group(target_name) {
forward_variables_from(invoker, [ "visibility" ])
testonly = true
# Redirect to the host toolchain.
deps = [ ":${test_target}($host_toolchain)" ]
}
original_target_name = target_name
bind_host_test(test_target) {
if (defined(invoker.target)) {
target = "${invoker.target}"
} else {
target = "${original_target_name}"
}
rules = invoker.rules
tests = invoker.tests
forward_variables_from(invoker,
[
"deps",
"visibility",
])
}
}
# Declares a driver's bind rules.
#
# Generate a C header that exposes a ZIRCON_DRIVER macro with the specified bind rules built in.
# For more details refer to //tools/bindc/README.md.
#
# Parameters
#
# rules (required)
# [path]: Path to the bind rules source file.
# Note: This becomes optional when disable_autobind is true. See below.
#
# deps (optional)
# [lib of labels]: List of bind_library targets included by the bind rules.
#
# output (optional)
# [path]: Name of the header file generated by the tool (defaults to target name + ".h", or
# target name + ".bindbc" if output_bytecode is true).
#
# tests (optional)
# [path]: Path to a test specification. If this parameter is set then the template will
# create an additional bind_test target with the name "${target_name}_test". This allows you
# to define tests without specifying the bind library dependencies and rules file twice.
#
# disable_autobind (optional)
# [bool]: Configure the bind compiler to disable autobind, so that the driver must be bound on
# a user's request. If this is set to true, then the rules parameter becomes optional and when
# it's omitted the driver will bind unconditionally (but must be bound manually.) Defaults to
# false.
# TODO(fxbug.dev/43400): Eventually this option should be removed when we can define this
# configuration in the driver's component manifest.
#
# output_bytecode (optional)
# [bool]: Output a bytecode file, instead of a C header file.
#
# testonly, visibility
# Forwarded from invoker.
#
template("bind_rules") {
assert(defined(invoker.rules) || (defined(invoker.disable_autobind) &&
invoker.disable_autobind == true),
"Need a bind rules source")
output_file = "$target_name.h"
if (defined(invoker.output)) {
output_file = invoker.output
} else if (defined(invoker.output_bytecode) && invoker.output_bytecode) {
output_file = "$target_name.bindbc"
}
response_file_target = "_${target_name}_response_file"
response_file = "${target_gen_dir}/${target_name}.rsp"
generated_file(response_file_target) {
visibility = [ ":*" ]
forward_variables_from(invoker,
[
"deps",
"testonly",
])
data_keys = [ "sources" ]
outputs = [ "${response_file}" ]
}
compiled_action(target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
tool = "//tools/bindc:bin"
tool_output_name = "bindc"
if (defined(invoker.rules)) {
sources = [ invoker.rules ]
}
depfile = "$target_gen_dir/$target_name.d"
args = [
"compile",
"--output",
rebase_path("$target_gen_dir/$output_file", root_build_dir),
"--include-file",
rebase_path(response_file, root_build_dir),
"--depfile",
rebase_path(depfile, root_build_dir),
]
if (defined(invoker.disable_autobind) && invoker.disable_autobind) {
args += [ "--disable-autobind" ]
}
if (defined(invoker.output_bytecode) && invoker.output_bytecode) {
args += [ "--output-bytecode" ]
}
if (defined(invoker.rules)) {
args += [ rebase_path(invoker.rules, root_build_dir) ]
}
inputs = [ response_file ]
outputs = [ "$target_gen_dir/$output_file" ]
deps = [ ":$response_file_target" ]
if (defined(invoker.deps)) {
deps += invoker.deps
}
}
if (defined(invoker.tests)) {
bind_test("${target_name}_test") {
forward_variables_from(invoker,
[
"rules",
"deps",
"tests",
])
}
}
}
# Declares a bind library.
#
# Declare a bind library that may be included by other libraries or bind rules. For more details,
# refer to //tools/bindc/README.md.
#
# Parameters
#
# source (required)
# [path]: Path to the library source file.
#
# public_deps (optional)
# [list of labels]: List of other bind_library targets included by the library.
#
# testonly, visibility
# Forwarded from invoker.
#
template("bind_library") {
assert(defined(invoker.source), "Need a source file")
test_data_dir = "${target_out_dir}/test_data/bind-tests/"
test_data_target = "${target_name}_test_data"
copy(test_data_target) {
visibility = [ ":*" ]
sources = [ invoker.source ]
outputs = [ "${test_data_dir}/{{source_file_part}}" ]
}
group(target_name) {
metadata = {
sources = [ rebase_path(invoker.source, root_build_dir) ]
# Adds metadata for test_spec().
test_runtime_deps = get_target_outputs(":${test_data_target}")
# Adds metadata for bind_test().
test_sources = rebase_path(get_target_outputs(":${test_data_target}"),
root_build_dir)
}
deps = [ ":${test_data_target}" ]
forward_variables_from(invoker,
[
"public_deps",
"testonly",
"visibility",
])
}
}