blob: 02730aaf2ab38c8cff6d637d4451df4cbbd42f69 [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("$zx/public/gn/config/standard.gni")
import("$zx/public/gn/toolchain/environment.gni")
import("$zx/public/gn/toolchain/environment_redirect.gni")
# Lists the names of the default set of sanitized variants used to build fuzzer
# binaries. Named lists of useful variant subsets are defined in standard.gni,
# e.g. $standard_sanitizer_variants. If at some point the fuuzers should be
# built with a different set of default variants, the set of named lists should
# be changed there to minimize duplication of individual items here.
fuzzer_default_variants = []
foreach(sanitizer, standard_sanitizer_variants) {
# Clear from last iteration.
_sanitizer_variant = {
}
_sanitizer_variant = sanitizer.variant
fuzzer_default_variants += [ _sanitizer_variant.name ]
}
# Builds fuzzer binaries using the libFuzzer fuzzing engine.
#
# See [libFuzzer](https://llvm.org/docs/LibFuzzer.html) for background on
# libFuzzer. To create a fuzzer, developers should specify the code being
# fuzzed in $deps, and provide an "LLVMFuzzerTestOneInput" fuzz target
# function for libFuzzer in $sources.
#
# The fuzzer() template below will build the fuzzer binary, link the engine, and
# instrument the $deps in an environment corresponding to an appropriate base
# environment. This means dependents on this target will get fuzzers for their
# base environment (e.g. host dependents will get host fuzzers, etc.).
#
# For clarity, it is strongly recommended that fuzzer names include the name of
# the code being fuzzed and end in "-fuzzer", e.g. a fuzzer in
# $zx/system/ulib/foo might be named "foo-fuzzer".
#
# Parameters
#
# sanitizers
# Optional: A list of variant names as they appear in $variants. This
# controls which toolchain variants are used to build each fuzzer binary.
# This is only needed if a fuzzer should not be built with one or more of
# $fuzzer_default_variants.
# Type: list(string)
# Default: fuzzer_default_variants
#
# See executable() for additional parameters and details.
template("fuzzer") {
# Match any "*.fuzzer" environment ("*" is ${toolchain.base_environment}).
if (get_path_info(toolchain.environment, "extension") == "fuzzer") {
# The test() template is used for programs that verify proper operation of
# associated code if the tests passes. This isn't an appropriate choice for
# fuzzers as they run indefinitely and never "pass".
executable(target_name) {
testonly = true
# Explicitly forward visibility for nested scope, and ensure the redirect
# is always visible.
forward_variables_from(invoker,
"*",
[
"testonly",
"visibility",
])
forward_variables_from(invoker, [ "visibility" ])
if (defined(visibility)) {
visibility += [ ":$target_name" ]
}
}
if (defined(invoker.sanitizers)) {
not_needed(invoker.sanitizers)
}
} else {
# Otherwise build sanitized variants in the fuzzer environment.
if (defined(invoker.sanitizers)) {
sanitizer_names = invoker.sanitizers
} else {
sanitizer_names = fuzzer_default_variants
}
environment_redirect(target_name) {
testonly = true
forward_variables_from(invoker, [ "visibility" ])
environment_label =
"$zx/public/gn/fuzzer:${toolchain.base_environment}.fuzzer"
direct = true
deps = []
foreach(sanitizer, sanitizer_names) {
deps += [ ":$target_name.$sanitizer" ]
}
}
not_needed(invoker, "*")
}
}