# Copyright 2018 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/fuzzer_component.gni")
import("//build/fuzzing/fuzzer_corpus.gni")
import("//build/fuzzing/fuzzer_dictionary.gni")
import("//build/fuzzing/fuzzer_test_component.gni")
import("//build/test.gni")

# TODO(fxbug.dev/60168): Consumers should import fuzzer_package explicitly. Remove once all are
# migrated.
import("//build/fuzzing/fuzzer_package.gni")

# A list of configs present in fuzzer toolchain variants.
#
# GN logic that needs to behave differently between fuzzer and non-fuzzer variants can determine the
# variant type by checking the `toolchain_variant.configs`, e.g.
#    if (toolchain_variant.configs + fuzzer_configs - fuzzer_configs == toolchain_variant.configs) {
#        # Not using a fuzzer toolchain variant.
#    } else {
#        # Using a fuzzer toolchain variant.
#    }
#
# This approach works even with the way `import` caches this file.
#
fuzzer_configs = [ "//build/config/fuzzer" ]

# Defines a fuzzer binary.
#
# The fuzzer template is used to create components containing binaries which leverage LLVM's
# libFuzzer to perform fuzz testing. It also creates a unit test that exercises the fuzzer code
# without libFuzzer, simply trying each corpus element without mutation.
#
# Parameters are precisely those of an `executable`, along with:
#
#   corpus (optional)
#     [path] If specified, a directory containing elements of a seed corpus. These should be a
#       combination of hand-crafted fuzzer inputs that increase coverage, and artifacts from
#       previous fuzzing runs, e.g. fuzzer inputs that triggered crashes. These will be used to seed
#       new fuzzing runs, and as regression unit tests.
#
#   dictionary (optional)
#     [file] If specified, a file containing quoted inputs, one per line, that the fuzzer will use
#       to generate new mutations.
#
#   options (optional)
#     [list of strings] Each option is of the form "key=value" and indicates command line options
#       that the fuzzer should be invoked with. Valid keys are libFuzzer options
#       (https://llvm.org/docs/LibFuzzer.html#options).
#
template("fuzzer") {
  # Dummy target to catch incorrect dependencies. If fuzzer_package is not used, the executable
  # won't ever be built with proper instrumentation.
  #
  # If a GN error led you here, you probably have a group with a dep on a `fuzzer("...")` target.
  # You should include those deps in a `fuzzer_package` instead, and depend on that. This will
  # ensure things are built correctly when a supported fuzzing variant toolchain is selected.
  #
  # See https://fuchsia.dev/fuchsia-src/development/testing/fuzzing/build-a-fuzzer for more info.
  group(target_name) {
    visibility = []
  }

  # The component target names MUST match the deps of the package created by the `fuzzer_package`
  # GN template in //build/fuzzing/fuzzer_package.gni. That template dispatches these targets to the
  # correct toolchain variant, and references them by constructing these names.
  component_target = "${target_name}_component"
  component_deps = []
  test_component_target = "${target_name}_test_component"
  test_component_deps = []

  if (defined(invoker.output_name)) {
    fuzzer_name = invoker.output_name
  } else {
    fuzzer_name = target_name
  }
  fuzzer_label = get_label_info(":$target_name", "label_no_toolchain")

  # Explicitly forward visibility for nested scopes. Visibility is forwarded for both components and
  # binaries, as the latter may be copied directly as host tools.
  exclude_from_mass_forwards = [
    "corpus",
    "dictionary",
    "options",
    "output_name",
    "target_name",
    "visibility",
  ]

  # Generate fuzzer resources with metadata.
  if (defined(invoker.corpus)) {
    corpus_target = "${target_name}_corpus"
    fuzzer_corpus(corpus_target) {
      label = fuzzer_label
      corpus = invoker.corpus
    }
    component_deps += [ ":$corpus_target" ]
    test_component_deps += [ ":$corpus_target" ]
  }

  if (defined(invoker.dictionary)) {
    dictionary_target = "${target_name}_dictionary"
    fuzzer_dictionary(dictionary_target) {
      label = fuzzer_label
      fuzzer = fuzzer_name
      dictionary = invoker.dictionary
    }
    component_deps += [ ":$dictionary_target" ]
  }

  # Generate the fuzzer binary and component.
  executable_target = "${target_name}_executable"
  executable_output = fuzzer_name
  executable(executable_target) {
    deps = []
    forward_variables_from(invoker, "*", exclude_from_mass_forwards)
    forward_variables_from(invoker, [ "visibility" ])
    variant_selector_target_type = "fuzzed_executable"
    output_name = executable_output
    testonly = true

    # TODO(fxbug.dev/27011): This shouldn't be necessary, but libzircon isn't currently linked into
    # libFuzzer on Fuchsia.
    if (is_fuchsia) {
      deps += [ "//src/zircon/lib/zircon" ]
    }
  }
  component_deps += [ ":$executable_target" ]

  fuzzer_component(component_target) {
    forward_variables_from(invoker,
                           [
                             "options",
                             "visibility",
                           ])
    fuzzer = fuzzer_name
    label = fuzzer_label
    deps = component_deps
  }

  # Generate the fuzzer test binary and component.
  test_executable_target = "${target_name}_test_executable"
  test_executable_output = "${fuzzer_name}_test"
  test(test_executable_target) {
    deps = []
    forward_variables_from(invoker, "*", exclude_from_mass_forwards)
    forward_variables_from(invoker, [ "visibility" ])
    output_name = test_executable_output
    configs -= [ "//build/config/fuzzer:engine" ]
    deps += [ "//src/lib/fuzzing/cpp:fuzzer_test" ]
  }
  test_component_deps += [ ":$test_executable_target" ]

  fuzzer_test_component(test_component_target) {
    forward_variables_from(invoker,
                           [
                             "corpus",
                             "visibility",
                           ])
    fuzzer = fuzzer_name
    label = fuzzer_label
    deps = test_component_deps
  }
}

set_defaults("fuzzer") {
  configs = default_executable_configs + [ "//build/config/fuzzer:engine" ]
}
