blob: e2466d8668500cd2b29e9ade5934b4d0801af400 [file] [log] [blame]
# Copyright 2020 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/fuzzing/fuchsia_library_fuzzer.gni")
import("//build/fuzzing/host_library_fuzzer.gni")
import("//build/rust/rustc_staticlib.gni")
# Defines a Rust fuzzer
#
# The template creates a Rust static library with fuzz target functions enabled
# and provides it to the usual `fuzzer` template. This can create three
# different outputs based on the toolchain variant applied to the target:
#
# - If the toolchain variant is "rust-*san-fuzzer", this will build a fuzzer
# which instruments the Rust code of the target and its dependencies.
#
# - If the toolchain variant is "*san-fuzzer", this will build a fuzzer which
# instruments the C/C++ code of the target and its dependencies.
#
# - Otherwise, it will build an uninstrumented unit test that ensures the
# fuzzer code can build and link.
#
# Parameters are the same as `executable`, plus:
#
# rustfunction (optional)
# Name of the fuzz target function. Defaults to the GN target name.
# See also https://llvm.org/docs/LibFuzzer.html#fuzz-target.
#
# version
# edition
# configs
# data_deps
# deps
# source_root
# enforce_source_listing
# sources
# inputs
# features
# rustenv
# disable_rbe
# Same meaning as for rustc_staticlib.
#
# test_inputs
# Same meaning as for `host_library_fuzzer` when building for host, ignored otherwise.
#
# Example:
#
# In src/lib.rs:
# fuzz!("my_fuzzer", (input: ArbitraryType), { ... });
#
# In BUILD.gn:
# rustc_fuzzer("my_fuzzer") {}
#
template("rustc_fuzzer") {
fuzzer_name = target_name
fuzzer_lib = "${fuzzer_name}_lib"
fuzzer_cfg = "${fuzzer_name}_cfg"
rustfunction = target_name
if (defined(invoker.rustfunction)) {
rustfunction = invoker.rustfunction
}
if (defined(invoker.original_target_name)) {
_original_target_name = invoker.original_target_name
} else {
_original_target_name = target_name
}
staticlib_vars = [
"deps",
"version",
"edition",
"source_root",
"enforce_source_listing",
"sources",
"inputs",
"features",
"rustenv",
]
config(fuzzer_cfg) {
visibility = [ ":*" ]
rustflags = [
"--cfg=fuzz",
"--cfg=fuzz_target=\"$rustfunction\"",
]
# https://fxbug.dev/42176112: rustc multiple codegen units seems incompatible
# with fuzzing.
configs = [ "//build/config/rust:one_codegen_unit" ]
}
rustc_staticlib(fuzzer_lib) {
testonly = true
visibility = [ ":*" ]
forward_variables_from(invoker, staticlib_vars)
configs = []
configs = [ ":$fuzzer_cfg" ] + invoker.configs
original_target_name = _original_target_name
disable_rustdoc = true
}
staticlib_vars += [ "configs" ]
# https://fxbug.dev/42176112: rustc multiple codegen units are incompatible with fuzzing.
ignored_parameters = []
if (is_fuchsia) {
ignored_parameters += [ "test_inputs" ]
fuchsia_library_fuzzer(target_name) {
forward_variables_from(invoker, "*", staticlib_vars + ignored_parameters)
deps = [ ":$fuzzer_lib" ]
configs += [ "//build/config/rust:one_codegen_unit" ]
}
} else {
# TODO(https://fxbug.dev/42056966): Remove once all fuzzers are using explicit manifests.
host_library_fuzzer(target_name) {
forward_variables_from(invoker, "*", staticlib_vars + ignored_parameters)
deps = [ ":$fuzzer_lib" ]
configs += [ "//build/config/rust:one_codegen_unit" ]
}
}
not_needed(invoker, ignored_parameters)
}
set_defaults("rustc_fuzzer") {
configs = default_common_binary_configs + default_rust_configs
}