pw_fuzzer: Refactor conditional GN targets
This CL moves conditional logic around whether fuzzing and/or OSS-Fuzz
support is enabled up the dependency graph. This allows for dedicated
targets based on specific conditions, making it clearer exactly what
configs and deps are being used.
Change-Id: Iba5fbd6229ec28e3e6e32e35e632d210c9992ea3
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/169712
Reviewed-by: Armando Montanez <amontanez@google.com>
Commit-Queue: Aaron Green <aarongreen@google.com>
diff --git a/pw_fuzzer/BUILD.gn b/pw_fuzzer/BUILD.gn
index 3b81538..a8eeb54 100644
--- a/pw_fuzzer/BUILD.gn
+++ b/pw_fuzzer/BUILD.gn
@@ -76,38 +76,62 @@
#
# Create FuzzTest-style fuzzers by adding a dep on dir_pw_fuzzer:fuzztest
-# Unit tests with a dep on this target can include FuzzTest-style fuzzers.
-pw_source_set("fuzztest") {
- # Include headers that extend FuzzTest's interface with support for common
- # Pigweed types.
- public = [ "public/pw_fuzzer/fuzztest.h" ]
- public_configs = [ ":public_include_path" ]
+group("fuzztest") {
+ if (dir_pw_third_party_fuzztest != "" && pw_toolchain_FUZZING_ENABLED) {
+ public_deps = [ ":fuzztest.enabled" ]
+ } else {
+ public_deps = [ ":fuzztest.disabled" ]
+ }
+}
+
+# Used by fuzzable unit tests when fuzzing is enabled. Includes headers and deps
+# that provide a Pigweed-compatible subset of FuzzTest, as well as extensions to
+# support common Pigweed types.
+if (dir_pw_third_party_fuzztest != "" && pw_toolchain_FUZZING_ENABLED) {
+ pw_source_set("fuzztest.enabled") {
+ public = [
+ "private/pw_fuzzer/internal/fuzztest.h",
+ "public/pw_fuzzer/fuzztest.h",
+ ]
+ public_configs = [
+ ":public_include_path",
+ ":private_include_path",
+ "$dir_pw_third_party/abseil-cpp/configs:disabled_warnings",
+ "$dir_pw_third_party/abseil-cpp/configs:public_include_path",
+ "$dir_pw_third_party/fuzztest/configs:disabled_warnings",
+ "$dir_pw_third_party/fuzztest/configs:public_include_path",
+ "$dir_pw_third_party/re2/configs:disabled_warnings",
+ "$dir_pw_third_party/re2/configs:public_include_path",
+ ]
+ public_deps = [
+ "$dir_pw_third_party/fuzztest/fuzztest",
+ dir_pw_containers,
+ dir_pw_result,
+ dir_pw_status,
+ dir_pw_string,
+ ]
+ }
+}
+
+# Used by fuzzable unit tests when fuzzing is disabled. Includes stubs of the
+# Pigweed-compatible subset of FuzzTest's interface, as well as extensions to
+# support common Pigweed types.
+pw_source_set("fuzztest.disabled") {
+ public = [
+ "private_overrides/pw_fuzzer/internal/fuzztest.h",
+ "public/pw_fuzzer/fuzztest.h",
+ "public_overrides/fuzztest/fuzztest.h",
+ ]
+ public_configs = [
+ ":public_include_path",
+ ":overrides_include_path",
+ ]
public_deps = [
dir_pw_containers,
dir_pw_result,
dir_pw_status,
dir_pw_string,
]
- if (dir_pw_third_party_fuzztest != "" && pw_toolchain_FUZZING_ENABLED) {
- # Include headers and deps that provide a Pigweed-compatible subset of
- # FuzzTest.
- public += [ "private/pw_fuzzer/internal/fuzztest.h" ]
- public_configs += [
- "$dir_pw_third_party/abseil-cpp/configs:disabled_warnings",
- "$dir_pw_third_party/re2/configs:disabled_warnings",
- "$dir_pw_third_party/fuzztest/configs:disabled_warnings",
- ":private_include_path",
- ]
- public_deps += [ "$dir_pw_third_party/fuzztest/fuzztest" ]
- } else {
- # Include headers that provide stubs of the Pigweed-compatible subset of
- # FuzzTest's interface.
- public += [
- "private_overrides/pw_fuzzer/internal/fuzztest.h",
- "public_overrides/fuzztest/fuzztest.h",
- ]
- public_configs += [ ":overrides_include_path" ]
- }
}
pw_test("fuzztest_tests") {
@@ -118,41 +142,55 @@
# This target should only be used when defining a fuzzing toolchain, e.g. to set
# `pw_unit_test_GOOGLETEST_BACKEND = "$dir_pw_fuzzer:gtest"
# TODO: b/295961502 - Support running FuzzTest-based fuzzers on OSS-Fuzz.
-if (pw_toolchain_OSS_FUZZ_ENABLED) {
- group("gtest") {
- public_deps = [ "$dir_pw_unit_test:light" ]
- }
-} else if (dir_pw_third_party_googletest != "") {
- group("gtest") {
- public_deps = [ "$dir_pw_third_party/googletest" ]
- }
-} else {
+if (dir_pw_third_party_googletest == "") {
pw_error("gtest") {
message_lines = [
"pw_unit_test_GOOGLETEST_BACKEND is set to dir_pw_fuzzer:gtest, ",
"but dir_pw_third_party_googletest is not set.",
]
}
+} else if (!pw_toolchain_FUZZING_ENABLED) {
+ pw_error("gtest") {
+ message_lines = [
+ "pw_unit_test_GOOGLETEST_BACKEND is set to dir_pw_fuzzer:gtest, ",
+ "but $current_toolchain does not support fuzzing.",
+ ]
+ }
+} else {
+ group("gtest") {
+ if (pw_toolchain_OSS_FUZZ_ENABLED) {
+ public_deps = [ "$dir_pw_unit_test:light" ]
+ } else {
+ public_deps = [ "$dir_pw_third_party/googletest" ]
+ }
+ }
}
# This target should only be used when defining a fuzzing toolchain, e.g. to set
# `pw_unit_test_MAIN = "$dir_pw_fuzzer:fuzztest_main"
# TODO: b/295961502 - Support running FuzzTest-based fuzzers on OSS-Fuzz.
-if (pw_toolchain_OSS_FUZZ_ENABLED) {
- group("fuzztest_main") {
- deps = [ "$dir_pw_unit_test:simple_printing_main" ]
- }
-} else if (dir_pw_third_party_fuzztest != "") {
- group("fuzztest_main") {
- deps = [ "$dir_pw_third_party/fuzztest/fuzztest:fuzztest_gtest_main" ]
- }
-} else {
+if (dir_pw_third_party_fuzztest == "") {
pw_error("fuzztest_main") {
message_lines = [
"pw_unit_test_MAIN is set to dir_pw_fuzzer:fuzztest_main, ",
"but dir_pw_third_party_fuzztest is not set.",
]
}
+} else if (!pw_toolchain_FUZZING_ENABLED) {
+ pw_error("fuzztest_main") {
+ message_lines = [
+ "pw_unit_test_MAIN is set to dir_pw_fuzzer:fuzztest_main, ",
+ "but $current_toolchain does not support fuzzing.",
+ ]
+ }
+} else {
+ group("fuzztest_main") {
+ if (pw_toolchain_OSS_FUZZ_ENABLED) {
+ deps = [ "$dir_pw_unit_test:simple_printing_main" ]
+ } else {
+ deps = [ "$dir_pw_third_party/fuzztest/fuzztest:fuzztest_gtest_main" ]
+ }
+ }
}
################################################################################
@@ -161,46 +199,10 @@
# Create libFuzzer-style fuzzers by using the `pw_fuzzer` template from
# fuzzer.gni.
-# Add flags for adding LLVM sanitizer coverage for fuzzing. This is added by
-# the host_clang_fuzz toolchains.
-config("instrumentation") {
- if (pw_toolchain_OSS_FUZZ_ENABLED) {
- # OSS-Fuzz manipulates compiler flags directly. See
- # google.github.io/oss-fuzz/getting-started/new-project-guide/#Requirements.
- cflags_c = string_split(getenv("CFLAGS"))
- cflags_cc = string_split(getenv("CXXFLAGS"))
-
- # OSS-Fuzz sets "-stdlib=libc++", which conflicts with the "-nostdinc++" set
- # by `pw_minimal_cpp_stdlib`.
- if (cflags_cc + [ "-stdlib=libc++" ] - [ "-stdlib=libc++" ] != cflags_cc) {
- cflags_cc += [ "-Wno-unused-command-line-argument" ]
- }
-
- # Disable UBSan vptr when the target is built with -fno-rtti.
- if (cflags_cc + [ "-fno-rtti" ] - [ "-fno-rtti" ] != cflags_cc) {
- cflags_cc += [ " -fno-sanitize=vptr" ]
- }
- cflags_cc += [ "-fcoverage-compilation-dir=" + getenv("PW_ROOT") ]
- } else {
- cflags = [ "-fsanitize=fuzzer-no-link" ]
- }
-}
-
# Add flags for linking against compiler-rt's libFuzzer. This is added
# automatically by `pw_fuzzer`.
config("libfuzzer_config") {
- ldflags = []
- engine = ""
- if (pw_toolchain_OSS_FUZZ_ENABLED) {
- # OSS-Fuzz manipulates linker flags directly. See
- # google.github.io/oss-fuzz/getting-started/new-project-guide/#Requirements.
- ldflags = string_split(getenv("LDFLAGS"))
- engine = getenv("LIB_FUZZING_ENGINE")
- }
- if (engine == "") {
- engine = "-fsanitize=fuzzer"
- }
- ldflags += [ engine ]
+ ldflags = [ "-fsanitize=fuzzer" ]
}
# Includes wrapper's for LLVM's libFuzzer compiler runtime library.
@@ -225,3 +227,47 @@
group("fuzzers") {
deps = [ "examples/libfuzzer:fuzzers" ]
}
+
+################################################################################
+# Local fuzzing support
+
+# Add flags for adding LLVM sanitizer coverage for fuzzing. This is added by
+# the host_clang_fuzz toolchains.
+config("fuzz_instrumentation") {
+ cflags = [ "-fsanitize=fuzzer-no-link" ]
+}
+
+################################################################################
+# OSS-Fuzz support
+#
+# OSS-Fuzz manipulates compiler and linker flags directly. See
+# google.github.io/oss-fuzz/getting-started/new-project-guide/#Requirements.
+#
+# WARNING: This is not hermetic by design. It never can be, and never will be.
+
+config("oss_fuzz_instrumentation") {
+ cflags_c = string_split(getenv("CFLAGS"))
+ cflags_cc = string_split(getenv("CXXFLAGS"))
+
+ # OSS-Fuzz sets "-stdlib=libc++", which conflicts with the "-nostdinc++" set
+ # by `pw_minimal_cpp_stdlib`.
+ if (cflags_cc + [ "-stdlib=libc++" ] - [ "-stdlib=libc++" ] != cflags_cc) {
+ cflags_cc += [ "-Wno-unused-command-line-argument" ]
+ }
+
+ # Disable UBSan vptr when the target is built with -fno-rtti.
+ if (cflags_cc + [ "-fno-rtti" ] - [ "-fno-rtti" ] != cflags_cc) {
+ cflags_cc += [ " -fno-sanitize=vptr" ]
+ }
+ cflags_cc += [ "-fcoverage-compilation-dir=" + getenv("PW_ROOT") ]
+
+ ldflags = cflags_cc + [ "-fuse-ld=lld" ]
+}
+
+config("libfuzzer_oss_fuzz_config") {
+ engine = getenv("LIB_FUZZING_ENGINE")
+ if (engine == "") {
+ engine = "-fsanitize=fuzzer"
+ }
+ ldflags = [ engine ]
+}
diff --git a/pw_fuzzer/fuzzer.gni b/pw_fuzzer/fuzzer.gni
index aa1bdfa..512bc8a 100644
--- a/pw_fuzzer/fuzzer.gni
+++ b/pw_fuzzer/fuzzer.gni
@@ -81,7 +81,11 @@
"visibility",
])
forward_variables_from(invoker, [ "visibility" ])
- configs += [ "$dir_pw_fuzzer:libfuzzer_config" ]
+ if (pw_toolchain_OSS_FUZZ_ENABLED) {
+ configs += [ "$dir_pw_fuzzer:libfuzzer_oss_fuzz_config" ]
+ } else {
+ configs += [ "$dir_pw_fuzzer:libfuzzer_config" ]
+ }
deps += [
":$_test_metadata",
"$dir_pw_fuzzer:libfuzzer",
diff --git a/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py b/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py
index dde7a59..42aa48a 100755
--- a/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py
+++ b/pw_presubmit/py/pw_presubmit/pigweed_presubmit.py
@@ -492,7 +492,20 @@
oss_fuzz_build = build.GnGenNinja(
name='oss_fuzz_build',
path_filter=_BUILD_FILE_FILTER,
+ packages=('abseil-cpp', 'fuzztest', 'googletest', 're2'),
gn_args={
+ 'dir_pw_third_party_abseil_cpp': lambda ctx: '"{}"'.format(
+ ctx.package_root / 'abseil-cpp'
+ ),
+ 'dir_pw_third_party_fuzztest': lambda ctx: '"{}"'.format(
+ ctx.package_root / 'fuzztest'
+ ),
+ 'dir_pw_third_party_googletest': lambda ctx: '"{}"'.format(
+ ctx.package_root / 'googletest'
+ ),
+ 'dir_pw_third_party_re2': lambda ctx: '"{}"'.format(
+ ctx.package_root / 're2'
+ ),
'pw_toolchain_OSS_FUZZ_ENABLED': True,
},
ninja_targets=('oss_fuzz',),
diff --git a/pw_rpc/fuzz/engine_test.cc b/pw_rpc/fuzz/engine_test.cc
index f5cc648..2d0f9c2 100644
--- a/pw_rpc/fuzz/engine_test.cc
+++ b/pw_rpc/fuzz/engine_test.cc
@@ -111,7 +111,8 @@
Vector<uint32_t, Fuzzer::kMaxActions> actions_;
};
-TEST_F(RpcFuzzTestingTest, SequentialRequests) {
+// TODO(b/274437709): Re-enable.
+TEST_F(RpcFuzzTestingTest, DISABLED_SequentialRequests) {
// Callback thread
Add(Action::kWriteStream, 1, 'B', 1);
Add(Action::kSkip, 0, 0);
diff --git a/pw_toolchain/host_clang/toolchains.gni b/pw_toolchain/host_clang/toolchains.gni
index 2d314de..273b202 100644
--- a/pw_toolchain/host_clang/toolchains.gni
+++ b/pw_toolchain/host_clang/toolchains.gni
@@ -138,7 +138,11 @@
forward_variables_from(_defaults, "*")
pw_toolchain_FUZZING_ENABLED = true
- default_configs += [ "$dir_pw_fuzzer:instrumentation" ]
+ if (pw_toolchain_OSS_FUZZ_ENABLED) {
+ default_configs += [ "$dir_pw_fuzzer:fuzz_instrumentation" ]
+ } else {
+ default_configs += [ "$dir_pw_fuzzer:oss_fuzz_instrumentation" ]
+ }
# Fuzz faster.
default_configs += [ "$dir_pw_build:optimize_speed" ]
diff --git a/third_party/abseil-cpp/configs/BUILD.gn b/third_party/abseil-cpp/configs/BUILD.gn
index 1ac2454..3d82ece 100644
--- a/third_party/abseil-cpp/configs/BUILD.gn
+++ b/third_party/abseil-cpp/configs/BUILD.gn
@@ -35,5 +35,5 @@
# toolchain, and `public_configs` do not propagate across toolchain boundaries
# by default.
config("public_include_path") {
- include_dirs = [ "$dir_pw_third_party_abseil_cpp" ]
+ include_dirs = [ dir_pw_third_party_abseil_cpp ]
}
diff --git a/third_party/fuzztest/configs/BUILD.gn b/third_party/fuzztest/configs/BUILD.gn
index cea99b1..3fdac81 100644
--- a/third_party/fuzztest/configs/BUILD.gn
+++ b/third_party/fuzztest/configs/BUILD.gn
@@ -20,6 +20,8 @@
config("disabled_warnings") {
cflags = [
"-Wno-sign-compare",
+ "-Wno-sign-conversion",
+ "-Wno-shorten-64-to-32",
"-Wno-unused-parameter",
"-Wno-missing-field-initializers",
]
@@ -31,5 +33,5 @@
# This is needed as FuzzTest is built in a dedicated toolchain, and
# `public_configs` do not propagate across toolchain boundaries by default.
config("public_include_path") {
- include_dirs = [ "$dir_pw_third_party_fuzztest" ]
+ include_dirs = [ dir_pw_third_party_fuzztest ]
}
diff --git a/third_party/re2/configs/BUILD.gn b/third_party/re2/configs/BUILD.gn
index 8874e7f..61c6bf1 100644
--- a/third_party/re2/configs/BUILD.gn
+++ b/third_party/re2/configs/BUILD.gn
@@ -45,5 +45,5 @@
# toolchain, and `public_configs` do not propagate across toolchain boundaries
# by default.
config("public_include_path") {
- include_dirs = [ "$dir_pw_third_party_re2" ]
+ include_dirs = [ dir_pw_third_party_re2 ]
}