| # 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, "*") |
| } |
| } |