Skip to content

Commit 1dbcd91

Browse files
authored
Add support for Bzlmod (#242)
* Add support for Bzlmod Requires fixing a case of a non-hermetic Python import in `dict_validation_test` that breaks with Python 3.11, with which Bazel uses `PYTHONSAFEPATH` by default. A follow-up PR will provide the publishing setup for releases to the Bazel Central Registry (BCR). * Disable layering_check for OSS-Fuzz OSS-Fuzz builds fail with: ``` ERROR: /root/.cache/bazel/_bazel_root/17db7bb59affe64429348778697da03a/external/abseil-cpp~20230802.1/absl/strings/BUILD.bazel:591:11: Compiling absl/strings/internal/cordz_functions.cc failed: undeclared inclusion(s) in rule '@@abseil-cpp~20230802.1//absl/strings:cordz_functions': this rule is missing dependency declarations for the following files included by 'absl/strings/internal/cordz_functions.cc': 'bazel-out/k8-opt-ST-b76ee6246659/bin/external/abseil-cpp~20230802.1/absl/base/atomic_hook.cppmap' 'bazel-out/k8-opt-ST-b76ee6246659/bin/external/abseil-cpp~20230802.1/absl/base/errno_saver.cppmap' 'bazel-out/k8-opt-ST-b76ee6246659/bin/external/abseil-cpp~20230802.1/absl/base/log_severity.cppmap' ``` These files are emitted by Bazel when using the `layering_check` feature. This looks like a bug or breaking change in clang. * Revert "Disable layering_check for OSS-Fuzz" This reverts commit 60a831d. * Address review comments * Update abseil and use a custom repo_name * Add subproject to .bazelignore * Use `Label` in macros * Update Bazel to 7.0.2 and ignore WORKSPACE repos in example repo * Add _repo_mapping file if supported * Apply repo mapping to local_jdk exclusion * Fix failure if there are no runfiles * Make `local_jdk` visible
1 parent d17a7d7 commit 1dbcd91

20 files changed

+304
-25
lines changed

.bazelignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
examples/bzlmod

.bazelrc

-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
# rules_fuzzing is not yet compatible with Bzlmod.
16-
# Use the experimental version of the flag for Bazel 5 compatibility.
17-
common --noexperimental_enable_bzlmod
18-
1915
# Force the use of Clang for all builds.
2016
build --repo_env=CC=clang
2117

.bazelversion

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.0.0
1+
7.0.2

.github/workflows/bazel_test.yml

+20
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,23 @@ jobs:
169169
- name: Run regression tests on macOS
170170
run: |
171171
bazel test --verbose_failures --test_output=all //examples/...
172+
bzlmod_examples_libfuzzer:
173+
name: Bzlmod examples (libFuzzer)
174+
runs-on: ubuntu-20.04
175+
steps:
176+
- name: Checkout repository
177+
uses: actions/checkout@v2
178+
- name: Run regression tests on macOS
179+
run: |
180+
cd examples/bzlmod
181+
bazel test --verbose_failures --test_output=all --@my_rules_fuzzing//fuzzing:cc_engine=@my_rules_fuzzing//fuzzing/engines:libfuzzer //...
182+
bzlmod_examples_replay:
183+
name: Bzlmod examples (replay)
184+
runs-on: ubuntu-20.04
185+
steps:
186+
- name: Checkout repository
187+
uses: actions/checkout@v2
188+
- name: Run regression tests on macOS
189+
run: |
190+
cd examples/bzlmod
191+
bazel test --verbose_failures --test_output=all --@my_rules_fuzzing//fuzzing:cc_engine=@my_rules_fuzzing//fuzzing/engines:replay //...

.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,19 @@
1414

1515
# Bazel-generated files.
1616
/bazel-*
17+
/examples/bzlmod/bazel-*
1718

1819
# Visual Studio Code configuration.
1920
/.vscode
2021

2122
# IntelliSense configuration generated by
2223
# https://github.com/grailbio/bazel-compilation-database
2324
compile_commands.json
25+
26+
# IntelliJ & CLion
27+
.clwb
28+
.ijwb
29+
30+
# The Bzlmod lockfile is platform-dependent with Python and thus hard
31+
# to keep up-to-date in CI. It still speeds up local development.
32+
MODULE.bazel.lock

MODULE.bazel

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
module(
16+
name = "rules_fuzzing",
17+
# Automatically updated during releases by the Publish to BCR app.
18+
version = "0.0.0",
19+
)
20+
21+
bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "com_google_absl")
22+
bazel_dep(name = "bazel_skylib", version = "1.5.0")
23+
bazel_dep(name = "platforms", version = "0.0.8")
24+
bazel_dep(name = "rules_python", version = "0.28.0")
25+
bazel_dep(name = "rules_java", version = "6.5.2")
26+
27+
bazel_dep(name = "stardoc", version = "0.6.2", dev_dependency = True, repo_name = "io_bazel_stardoc")
28+
bazel_dep(name = "googletest", version = "1.14.0.bcr.1", dev_dependency = True, repo_name = "com_google_googletest")
29+
bazel_dep(name = "re2", version = "2023-11-01", dev_dependency = True)
30+
31+
non_module_dependencies = use_extension("//fuzzing/private:extensions.bzl", "non_module_dependencies")
32+
use_repo(
33+
non_module_dependencies,
34+
"honggfuzz",
35+
"rules_fuzzing_jazzer",
36+
"rules_fuzzing_jazzer_api",
37+
"rules_fuzzing_oss_fuzz",
38+
)
39+
40+
SUPPORTED_PYTHON_VERSIONS = [
41+
"3.8",
42+
"3.9",
43+
"3.10",
44+
"3.11",
45+
"3.12",
46+
]
47+
48+
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
49+
50+
[
51+
python.toolchain(
52+
# Required to avoid an error when running as root in OSS-Fuzz.
53+
ignore_root_user_error = True,
54+
is_default = python_version == SUPPORTED_PYTHON_VERSIONS[-1],
55+
python_version = python_version,
56+
)
57+
for python_version in SUPPORTED_PYTHON_VERSIONS
58+
]
59+
60+
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
61+
62+
[
63+
pip.parse(
64+
extra_pip_args = ["--require-hashes"],
65+
hub_name = "rules_fuzzing_py_deps",
66+
python_version = python_version,
67+
requirements_lock = "//fuzzing:requirements.txt",
68+
)
69+
for python_version in SUPPORTED_PYTHON_VERSIONS
70+
]
71+
72+
use_repo(pip, fuzzing_py_deps = "rules_fuzzing_py_deps")
73+
74+
java_toolchains = use_extension("@rules_java//java:extensions.bzl", "toolchains")
75+
use_repo(java_toolchains, "local_jdk")

WORKSPACE.bzlmod

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Intentionally left blank as all deps are defined in MODULE.bazel.
16+
# By having this file exist, Bazel will not add the repositories defined in the implicit
17+
# "WORKSPACE suffix" with --enable_bzlmod.

examples/bzlmod/.bazelrc

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
common --repo_env=CC=clang
16+
common --@my_rules_fuzzing//fuzzing:cc_engine_instrumentation=libfuzzer
17+
common --@my_rules_fuzzing//fuzzing:cc_engine_sanitizer=asan

examples/bzlmod/BUILD

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
load("@my_rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test")
16+
load("@my_rules_fuzzing//fuzzing:java_defs.bzl", "java_fuzz_test")
17+
18+
cc_fuzz_test(
19+
name = "cc_fuzz_test",
20+
srcs = ["cc_fuzz_test.cc"],
21+
)
22+
23+
java_fuzz_test(
24+
name = "java_fuzz_test",
25+
srcs = ["JavaFuzzTest.java"],
26+
target_class = "com.example.JavaFuzzTest",
27+
)

examples/bzlmod/JavaFuzzTest.java

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// A plain fuzz target that does nothing.
16+
17+
package com.example;
18+
19+
import com.code_intelligence.jazzer.api.FuzzedDataProvider;
20+
21+
public class JavaFuzzTest {
22+
public static void fuzzerTestOneInput(FuzzedDataProvider data) {}
23+
}

examples/bzlmod/MODULE.bazel

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# We use a custom repo_name to verify that e.g. macros do not contain hard-coded
16+
# references to rules_fuzzing.
17+
bazel_dep(name = "rules_fuzzing", repo_name = "my_rules_fuzzing")
18+
local_path_override(
19+
module_name = "rules_fuzzing",
20+
path = "../..",
21+
)

examples/bzlmod/WORKSPACE.bzlmod

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Intentionally left blank as all deps are defined in MODULE.bazel.
16+
# By having this file exist, Bazel will not add the repositories defined in the implicit
17+
# "WORKSPACE suffix" with --enable_bzlmod.

examples/bzlmod/cc_fuzz_test.cc

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// A plain fuzz target that does nothing (just returns).
16+
17+
#include <cstddef>
18+
#include <cstdint>
19+
20+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
21+
return 0;
22+
}

examples/java/BUILD

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
# serve as regression tests. Targets that are expected to crash or hang are
1717
# disabled in the OSS-Fuzz integration using the "no-oss-fuzz" tag.
1818

19-
load("@rules_cc//cc:defs.bzl", "cc_binary")
2019
load("//fuzzing:java_defs.bzl", "java_fuzz_test")
2120

2221
filegroup(

fuzzing/private/binary.bzl

+7-2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ Provider for storing information about a fuzz test binary.
3434
fields = {
3535
"binary_file": "The instrumented fuzz test executable.",
3636
"binary_runfiles": "The runfiles of the fuzz test executable.",
37+
"binary_repo_mapping_manifest": "The _repo_mapping file of the fuzz " +
38+
"test executable.",
3739
"corpus_dir": "The directory of the corpus files used as input seeds.",
3840
"dictionary_file": "The dictionary file to use in fuzzing runs.",
3941
"engine_info": "The `FuzzingEngineInfo` provider of the fuzzing " +
@@ -108,9 +110,11 @@ def _fuzzing_binary_impl(ctx):
108110
)
109111
if ctx.attr._instrument_binary:
110112
# The attribute is a list if a transition is attached.
111-
binary_runfiles = ctx.attr.binary[0][DefaultInfo].default_runfiles
113+
default_info = ctx.attr.binary[0][DefaultInfo]
112114
else:
113-
binary_runfiles = ctx.attr.binary[DefaultInfo].default_runfiles
115+
default_info = ctx.attr.binary[DefaultInfo]
116+
binary_runfiles = default_info.default_runfiles
117+
binary_repo_mapping_manifest = getattr(default_info.files_to_run, "repo_mapping_manifest")
114118
other_runfiles = []
115119
if ctx.file.corpus:
116120
other_runfiles.append(ctx.file.corpus)
@@ -126,6 +130,7 @@ def _fuzzing_binary_impl(ctx):
126130
FuzzingBinaryInfo(
127131
binary_file = ctx.executable.binary,
128132
binary_runfiles = binary_runfiles,
133+
binary_repo_mapping_manifest = binary_repo_mapping_manifest,
129134
corpus_dir = ctx.file.corpus,
130135
dictionary_file = ctx.file.dictionary,
131136
engine_info = ctx.attr.engine[FuzzingEngineInfo],

fuzzing/private/extensions.bzl

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Internal dependencies that are not Bazel modules."""
16+
17+
load("//fuzzing:repositories.bzl", "rules_fuzzing_dependencies")
18+
19+
def _non_module_dependencies(_):
20+
rules_fuzzing_dependencies()
21+
22+
non_module_dependencies = module_extension(_non_module_dependencies)

fuzzing/private/fuzz_test.bzl

+9-9
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def cc_fuzz_test(
140140
name,
141141
corpus = None,
142142
dicts = None,
143-
engine = "@rules_fuzzing//fuzzing:cc_engine",
143+
engine = Label("//fuzzing:cc_engine"),
144144
size = None,
145145
tags = None,
146146
timeout = None,
@@ -225,7 +225,7 @@ def java_fuzz_test(
225225
target_class = None,
226226
corpus = None,
227227
dicts = None,
228-
engine = "@rules_fuzzing//fuzzing:java_engine",
228+
engine = Label("//fuzzing:java_engine"),
229229
size = None,
230230
tags = None,
231231
timeout = None,
@@ -329,19 +329,19 @@ def java_fuzz_test(
329329
jazzer_fuzz_binary(
330330
name = raw_binary_name,
331331
sanitizer = select({
332-
"@rules_fuzzing//fuzzing/private:is_oss_fuzz": native_library_sanitizer,
333-
"@rules_fuzzing//fuzzing/private:use_asan": "asan",
334-
"@rules_fuzzing//fuzzing/private:use_ubsan": "ubsan",
332+
Label("//fuzzing/private:is_oss_fuzz"): native_library_sanitizer,
333+
Label("//fuzzing/private:use_asan"): "asan",
334+
Label("//fuzzing/private:use_ubsan"): "ubsan",
335335
"//conditions:default": "none",
336336
}),
337337
sanitizer_options = select({
338-
"@rules_fuzzing//fuzzing/private:is_oss_fuzz": Label("//fuzzing/private:oss_fuzz_jazzer_sanitizer_options.sh"),
338+
Label("//fuzzing/private:is_oss_fuzz"): Label("//fuzzing/private:oss_fuzz_jazzer_sanitizer_options.sh"),
339339
"//conditions:default": Label("//fuzzing/private:local_jazzer_sanitizer_options.sh"),
340340
}),
341341
sanitizer_runtime = select({
342-
"@rules_fuzzing//fuzzing/private:is_oss_fuzz": _RUNTIME_BY_NAME[native_library_sanitizer],
343-
"@rules_fuzzing//fuzzing/private:use_asan": _ASAN_RUNTIME,
344-
"@rules_fuzzing//fuzzing/private:use_ubsan": _UBSAN_RUNTIME,
342+
Label("//fuzzing/private:is_oss_fuzz"): _RUNTIME_BY_NAME[native_library_sanitizer],
343+
Label("//fuzzing/private:use_asan"): _ASAN_RUNTIME,
344+
Label("//fuzzing/private:use_ubsan"): _UBSAN_RUNTIME,
345345
"//conditions:default": None,
346346
}),
347347
target = raw_target_name,

0 commit comments

Comments
 (0)