diff --git a/BUILD.bazel b/BUILD.bazel index 27b9458..396a904 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -15,6 +15,7 @@ exports_files( [ "LICENSE.md", "NOTICE", + "presets.bzl", ], visibility = ["//visibility:public"], ) diff --git a/MODULE.bazel b/MODULE.bazel index dcb06f4..fee2ae8 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -14,6 +14,7 @@ module(name = "score_cpp_policies") bazel_dep(name = "bazel_skylib", version = "1.8.2") -bazel_dep(name = "platforms", version = "0.0.10") +bazel_dep(name = "platforms", version = "1.0.0") bazel_dep(name = "rules_cc", version = "0.2.17") bazel_dep(name = "aspect_rules_lint", version = "2.5.0") +bazel_dep(name = "bazelrc-preset.bzl", version = "1.9.2") diff --git a/README.md b/README.md index 1fbea7c..6d1a0ec 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Planned: clang-format, code coverage policies. - **[`sanitizers/`](sanitizers/README.md)** — ASan/UBSan/LSan/TSan Bazel `cc_feature`s, ready-to-use `--config=` aliases, suppression files, and `target_compatible_with` constraints. - **[`clang_tidy/`](clang_tidy/README.md)** — centralized `.clang-tidy` baseline (conservative, tailorable per module) and a `--config=clang-tidy` Bazel integration. +- **[`presets.bzl`](presets.bzl)** — sanitizers and clang-tidy as [bazelrc-preset.bzl](https://github.com/bazel-contrib/bazelrc-preset.bzl) presets, for consumers who'd rather generate their `.bazelrc` than hand-copy `sanitizers.bazelrc`/`clang_tidy.bazelrc`. See `sanitizers/README.md` § Distribution via bazelrc-preset.bzl. ## Sanitizers diff --git a/clang_tidy/BUILD.bazel b/clang_tidy/BUILD.bazel index cc8e1bb..264ea42 100644 --- a/clang_tidy/BUILD.bazel +++ b/clang_tidy/BUILD.bazel @@ -16,6 +16,21 @@ exports_files( ".clang-tidy", "clang_tidy.bazelrc", "defs.bzl", + "presets.bzl", ], visibility = ["//visibility:public"], ) + +# Fails if clang_tidy.bazelrc and CLANG_TIDY_PRESETS drift apart. +sh_test( + name = "clang_tidy_bazelrc_equivalence_test", + srcs = ["//tools:check_bazelrc_equivalence.py"], + args = [ + "$(location :clang_tidy.bazelrc)", + "$(location //tools:preset)", + ], + data = [ + ":clang_tidy.bazelrc", + "//tools:preset", + ], +) diff --git a/clang_tidy/README.md b/clang_tidy/README.md index f6254a6..a4e237c 100644 --- a/clang_tidy/README.md +++ b/clang_tidy/README.md @@ -42,6 +42,12 @@ import %workspace%/path/to/clang_tidy.bazelrc # if vendored locally > `tests/` self-test workspace here), a relative `import` works. Otherwise vendor > the three lines from `clang_tidy.bazelrc` into your own `.bazelrc`. +> Or consume `CLANG_TIDY_PRESETS` via [bazelrc-preset.bzl](https://github.com/bazel-contrib/bazelrc-preset.bzl) +> instead — see `sanitizers/README.md` § Distribution via bazelrc-preset.bzl for the +> full steps. The same `tools/BUILD` preset target can pass +> `@score_cpp_policies//:presets.bzl`'s `PRESETS` (sanitizers + clang-tidy together) or +> `@score_cpp_policies//clang_tidy:presets.bzl`'s `CLANG_TIDY_PRESETS` alone. + ### 3 — Create `tools/lint/BUILD.bazel` ```python diff --git a/clang_tidy/presets.bzl b/clang_tidy/presets.bzl new file mode 100644 index 0000000..08f6017 --- /dev/null +++ b/clang_tidy/presets.bzl @@ -0,0 +1,41 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +"""bazelrc-preset.bzl extra_presets for the clang-tidy policy. + +Mirrors the `test:clang-tidy` flags in clang_tidy.bazelrc, for consumers using +bazelrc-preset.bzl (https://github.com/bazel-contrib/bazelrc-preset.bzl) instead of +`import`. + +The `aspects` value is a label relative to the consuming repo, not score_cpp_policies +— each consumer defines its own `tools/lint/linters.bzl` (see clang_tidy/README.md). +""" + +# buildifier: keep-sorted +CLANG_TIDY_PRESETS = { + "aspects": struct( + command = "test:clang-tidy", + default = "//tools/lint:linters.bzl%clang_tidy_aspect", + description = "Run the consumer's clang-tidy aspect (see clang_tidy/README.md step 3-4) under --config=clang-tidy.", + ), + "extra_toolchains": struct( + command = "test:clang-tidy", + default = "@llvm_toolchain//:cc-toolchain-x86_64-linux", + description = "Use the LLVM toolchain registered by the consumer's llvm_toolchain extension for clang-tidy.", + ), + "output_groups": struct( + command = "test:clang-tidy", + default = "+rules_lint_report", + description = "Surface the rules_lint_report output group produced by the clang-tidy aspect.", + ), +} diff --git a/presets.bzl b/presets.bzl new file mode 100644 index 0000000..a9adf82 --- /dev/null +++ b/presets.bzl @@ -0,0 +1,34 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +"""Single entry point for all score_cpp_policies bazelrc-preset.bzl presets. + +Consumers wanting every policy this repo ships should load PRESETS: + + load("@score_cpp_policies//:presets.bzl", "PRESETS") + + bazelrc_preset( + name = "preset", + extra_presets = PRESETS, + ) + +Consumers wanting only one policy (e.g. sanitizers without clang-tidy) can load the +individual dicts instead: SANITIZER_PRESETS, CLANG_TIDY_PRESETS. + +Coverage and CodeQL are not included here yet. +""" + +load("//clang_tidy:presets.bzl", "CLANG_TIDY_PRESETS") +load("//sanitizers:presets.bzl", "SANITIZER_PRESETS") + +PRESETS = SANITIZER_PRESETS | CLANG_TIDY_PRESETS diff --git a/sanitizers/BUILD.bazel b/sanitizers/BUILD.bazel index 6b215f0..69ab443 100644 --- a/sanitizers/BUILD.bazel +++ b/sanitizers/BUILD.bazel @@ -14,10 +14,27 @@ load("//sanitizers/private:expand_template.bzl", "expand_template") exports_files( - ["sanitizers.bazelrc"], + [ + "presets.bzl", + "sanitizers.bazelrc", + ], visibility = ["//visibility:public"], ) +# Fails if sanitizers.bazelrc and SANITIZER_PRESETS drift apart. +sh_test( + name = "sanitizers_bazelrc_equivalence_test", + srcs = ["//tools:check_bazelrc_equivalence.py"], + args = [ + "$(location :sanitizers.bazelrc)", + "$(location //tools:preset)", + ], + data = [ + ":sanitizers.bazelrc", + "//tools:preset", + ], +) + filegroup( name = "suppressions", srcs = [ diff --git a/sanitizers/README.md b/sanitizers/README.md index 4811611..dfb2c94 100644 --- a/sanitizers/README.md +++ b/sanitizers/README.md @@ -28,6 +28,43 @@ bazel test --config=tsan_ubsan //your/target/... > ``` > try-import %workspace%/path/to/score_cpp_policies/sanitizers/sanitizers.bazelrc > ``` +> +> Or consume `SANITIZER_PRESETS` via [bazelrc-preset.bzl](https://github.com/bazel-contrib/bazelrc-preset.bzl) instead — see +> [Distribution via bazelrc-preset.bzl](#distribution-via-bazelrc-presetbzl) below. + +--- + +## Distribution via bazelrc-preset.bzl + +[bazelrc-preset.bzl](https://github.com/bazel-contrib/bazelrc-preset.bzl) generates a +`.bazelrc` fragment from `SANITIZER_PRESETS` that you vendor into your own repo, +instead of copy-pasting `sanitizers.bazelrc` by hand. + +1. Add the dependency to your `MODULE.bazel`: + ```python + bazel_dep(name = "score_cpp_policies", version = "") + bazel_dep(name = "bazelrc-preset.bzl", version = "1.9.2") + ``` +2. Reference `SANITIZER_PRESETS` (or `PRESETS` for sanitizers + clang-tidy together) + from a `BUILD` file, e.g. `tools/BUILD`: + ```python + load("@bazelrc-preset.bzl", "bazelrc_preset") + load("@score_cpp_policies//:presets.bzl", "PRESETS") + # Or, sanitizers only: + # load("@score_cpp_policies//sanitizers:presets.bzl", "SANITIZER_PRESETS") + + bazelrc_preset( + name = "preset", + extra_presets = PRESETS, + ) + ``` +3. Generate and commit the preset file: `bazel run //tools:preset.update`. +4. Import it from your workspace `.bazelrc`: + ``` + import %workspace%/tools/preset.bazelrc + ``` +5. `bazel test //tools:preset.update_test` catches drift whenever `presets.bzl` + changes — re-run step 3 to update. --- diff --git a/sanitizers/presets.bzl b/sanitizers/presets.bzl new file mode 100644 index 0000000..a450a1c --- /dev/null +++ b/sanitizers/presets.bzl @@ -0,0 +1,183 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +"""bazelrc-preset.bzl extra_presets for the sanitizers policy. + +Mirrors the --config=asan/ubsan/lsan/tsan/asan_ubsan_lsan/tsan_ubsan flags in +sanitizers.bazelrc, for consumers using bazelrc-preset.bzl +(https://github.com/bazel-contrib/bazelrc-preset.bzl) instead of `import`. +""" + +_WRAPPER = "@score_cpp_policies//sanitizers:wrapper" + +# buildifier: keep-sorted +SANITIZER_PRESETS = { + "@score_cpp_policies//sanitizers/flags:asan": struct( + command = "build:asan", + default = True, + description = "Activate the ASan cc_feature (score_asan) for the //sanitizers/flags:asan_on config_setting.", + ), + "@score_cpp_policies//sanitizers/flags:lsan": struct( + command = "build:lsan", + default = True, + description = "Activate the LSan cc_feature (score_lsan) for the //sanitizers/flags:lsan_on config_setting.", + ), + "@score_cpp_policies//sanitizers/flags:tsan": struct( + command = "build:tsan", + default = True, + description = "Activate the TSan cc_feature (score_tsan) for the //sanitizers/flags:tsan_on config_setting.", + ), + "@score_cpp_policies//sanitizers/flags:ubsan": struct( + command = "build:ubsan", + default = True, + description = "Activate the UBSan cc_feature (score_ubsan) for the //sanitizers/flags:ubsan_on config_setting.", + ), + "config": [ + struct( + command = "build:asan", + default = "with_debug_symbols", + description = "Keep debug symbols (-g1, --strip=never) so sanitizer stack traces are readable.", + ), + struct( + command = "build:ubsan", + default = "with_debug_symbols", + description = "Keep debug symbols (-g1, --strip=never) so sanitizer stack traces are readable.", + ), + struct( + command = "build:lsan", + default = "with_debug_symbols", + description = "Keep debug symbols (-g1, --strip=never) so sanitizer stack traces are readable.", + ), + struct( + command = "build:tsan", + default = "with_debug_symbols", + description = "Keep debug symbols (-g1, --strip=never) so sanitizer stack traces are readable.", + ), + struct( + command = "build:asan_ubsan_lsan", + default = "asan", + allow_repeated = True, + description = "Composite config: address + leak + UB checking together.", + ), + struct( + command = "build:asan_ubsan_lsan", + default = "ubsan", + allow_repeated = True, + description = "Composite config: address + leak + UB checking together.", + ), + struct( + command = "build:asan_ubsan_lsan", + default = "lsan", + allow_repeated = True, + description = "Composite config: address + leak + UB checking together.", + ), + struct( + command = "build:tsan_ubsan", + default = "tsan", + allow_repeated = True, + description = "Composite config: thread + UB checking together.", + ), + struct( + command = "build:tsan_ubsan", + default = "ubsan", + allow_repeated = True, + description = "Composite config: thread + UB checking together.", + ), + ], + "features": [ + struct( + command = "test:with_debug_symbols", + default = "debug_symbols", + description = "Emit -g1 debug info under any sanitizer config so stack traces resolve symbols.", + ), + struct( + command = "build:asan", + default = "score_asan", + description = "Compile/link with -fsanitize=address via the score_asan cc_feature.", + ), + struct( + command = "build:ubsan", + default = "score_ubsan", + description = "Compile/link with -fsanitize=undefined via the score_ubsan cc_feature.", + ), + struct( + command = "build:lsan", + default = "score_lsan", + description = "Compile/link with -fsanitize=leak via the score_lsan cc_feature.", + ), + struct( + command = "build:tsan", + default = "score_tsan", + description = "Compile/link with -fsanitize=thread via the score_tsan cc_feature.", + ), + ], + "platform_suffix": [ + struct( + command = "build:asan", + default = "asan", + description = "Disambiguate the asan output tree from plain builds.", + ), + struct( + command = "build:ubsan", + default = "ubsan", + description = "Disambiguate the ubsan output tree from plain builds.", + ), + struct( + command = "build:lsan", + default = "lsan", + description = "Disambiguate the lsan output tree from plain builds.", + ), + struct( + command = "build:tsan", + default = "tsan", + description = "Disambiguate the tsan output tree from plain builds.", + ), + struct( + command = "build:asan_ubsan_lsan", + default = "asan_ubsan_lsan", + description = "Canonical suffix for the composite asan+ubsan+lsan config, overriding the per-sanitizer suffixes.", + ), + struct( + command = "build:tsan_ubsan", + default = "tsan_ubsan", + description = "Canonical suffix for the composite tsan+ubsan config, overriding the per-sanitizer suffixes.", + ), + ], + "run_under": [ + struct( + command = "test:asan", + default = _WRAPPER, + description = "Run tests under the sanitizers wrapper so suppressions/options env files are applied.", + ), + struct( + command = "test:ubsan", + default = _WRAPPER, + description = "Run tests under the sanitizers wrapper so suppressions/options env files are applied.", + ), + struct( + command = "test:lsan", + default = _WRAPPER, + description = "Run tests under the sanitizers wrapper so suppressions/options env files are applied.", + ), + struct( + command = "test:tsan", + default = _WRAPPER, + description = "Run tests under the sanitizers wrapper so suppressions/options env files are applied.", + ), + ], + "strip": struct( + command = "build:with_debug_symbols", + default = "never", + description = "Never strip symbols under any sanitizer config so stack traces remain readable.", + ), +} diff --git a/tools/BUILD.bazel b/tools/BUILD.bazel new file mode 100644 index 0000000..51814a6 --- /dev/null +++ b/tools/BUILD.bazel @@ -0,0 +1,31 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@bazelrc-preset.bzl", "bazelrc_preset", "bazelrc_preset_test") +load("//:presets.bzl", "PRESETS") + +bazelrc_preset( + name = "preset", + extra_presets = PRESETS, + visibility = ["//visibility:public"], +) + +bazelrc_preset_test( + name = "preset_schema_test", + extra_presets = PRESETS, +) + +exports_files( + ["check_bazelrc_equivalence.py"], + visibility = ["//visibility:public"], +) diff --git a/tools/check_bazelrc_equivalence.py b/tools/check_bazelrc_equivalence.py new file mode 100755 index 0000000..9a7e12a --- /dev/null +++ b/tools/check_bazelrc_equivalence.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 + +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +"""Compares a legacy .bazelrc fragment (e.g. sanitizers/sanitizers.bazelrc) against a +bazelrc-preset.bzl-generated file, restricted to the commands the legacy file defines +(e.g. "build:asan"). + +Usage: check_bazelrc_equivalence.py +""" + +import re +import sys + +_LINE_RE = re.compile(r"^([A-Za-z0-9_:-]+)\s+--(.+)$") + + +def normalize(path, filter_commands=None): + """Returns the sorted set of (command, flag, value) tuples in a .bazelrc file.""" + entries = set() + with open(path) as f: + for line in f: + line = line.strip() + if not line or line.startswith("#"): + continue + match = _LINE_RE.match(line) + if not match: + continue + cmd, rest = match.group(1), match.group(2) + if filter_commands is not None and cmd not in filter_commands: + continue + if rest.startswith("no") and "=" not in rest: + flag, val = rest[2:], "False" + elif "=" in rest: + flag, val = rest.split("=", 1) + val = val.strip('"') + else: + flag, val = rest, "True" + entries.add((cmd, flag, val)) + return entries + + +def main(legacy_file, generated_file): + legacy = normalize(legacy_file) + commands = {cmd for cmd, _, _ in legacy} + generated = normalize(generated_file, filter_commands=commands) + + if legacy != generated: + print(f"MISMATCH between {legacy_file} and {generated_file} (commands: {sorted(commands)})", file=sys.stderr) + for entry in sorted(legacy - generated): + print(f" only in {legacy_file}: {entry}", file=sys.stderr) + for entry in sorted(generated - legacy): + print(f" only in {generated_file}: {entry}", file=sys.stderr) + return 1 + + print(f"OK: {legacy_file} matches {generated_file} for commands: {sorted(commands)}") + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1], sys.argv[2])) diff --git a/tools/preset.bazelrc b/tools/preset.bazelrc new file mode 100644 index 0000000..76b118d --- /dev/null +++ b/tools/preset.bazelrc @@ -0,0 +1,342 @@ +# Generated by bazelrc-preset.bzl +# To update this file, run: +# bazel run @@//tools:preset.update + +# On CI, announce all announces command options read from the bazelrc file(s) when starting up at the +# beginning of each Bazel invocation. This is very useful on CI to be able to inspect which flags +# are being applied on each run based on the order of overrides. +common:ci --announce_rc +# Docs: https://registry.build/flag/bazel@8.3.0?filter=announce_rc + +# Avoid creating a runfiles tree for binaries or tests until it is needed. +# See https://github.com/bazelbuild/bazel/issues/6627 +# This may break local workflows that `build` a binary target, then run the resulting program outside of `bazel run`. +# In those cases, the script will need to call `bazel build --build_runfile_links //my/binary:target` and then execute the resulting program. +common --nobuild_runfile_links +# Docs: https://registry.build/flag/bazel@8.3.0?filter=build_runfile_links + +# Always run tests even if they have cached results. +# This ensures tests are executed fresh each time, useful for debugging and ensuring test reliability. +common:debug --nocache_test_results +# Docs: https://registry.build/flag/bazel@8.3.0?filter=cache_test_results + +# Don’t encourage a rules author to update their deps if not needed. +# These bazel_dep calls should indicate the minimum version constraint of the ruleset. +# If the author instead updates to the newest of any of their transitives, as this flag would suggest, +# then they'll also force their dependents to a newer version. +# Context: +# https://bazelbuild.slack.com/archives/C014RARENH0/p1691158021917459?thread_ts=1691156601.420349&cid=C014RARENH0 +common:ruleset --check_direct_dependencies="off" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=check_direct_dependencies + +# On CI, use colors to highlight output on the screen. Set to `no` if your CI does not display colors. +common:ci --color="yes" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=color + +# On CI, use cursor controls in screen output. +common:ci --curses="yes" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=curses + +# Bazel picks up host-OS-specific config lines from bazelrc files. For example, if the host OS is +# Linux and you run bazel build, Bazel picks up lines starting with build:linux. Supported OS +# identifiers are `linux`, `macos`, `windows`, `freebsd`, and `openbsd`. Enabling this flag is +# equivalent to using `--config=linux` on Linux, `--config=windows` on Windows, etc. +common --enable_platform_specific_config +# Docs: https://registry.build/flag/bazel@8.3.0?filter=enable_platform_specific_config + +# Speed up all builds by not checking if external repository files have been modified. +# For reference: https://github.com/bazelbuild/bazel/blob/1af61b21df99edc2fc66939cdf14449c2661f873/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java#L244 +common --noexperimental_check_external_repository_files +# Docs: https://registry.build/flag/bazel@8.3.0?filter=experimental_check_external_repository_files + +# Always download coverage files for tests from the remote cache. By default, coverage files are not +# downloaded on test result cache hits when --remote_download_minimal is enabled, making it impossible +# to generate a full coverage report. +common --experimental_fetch_all_coverage_outputs +# Docs: https://registry.build/flag/bazel@8.3.0?filter=experimental_fetch_all_coverage_outputs + +# Set this flag to enable re-tries of failed tests on CI. +# When any test target fails, try one or more times. This applies regardless of whether the "flaky" +# tag appears on the target definition. +# This is a tradeoff: legitimately failing tests will take longer to report, +# but we can "paper over" flaky tests that pass most of the time. +# +# An alternative is to mark every flaky test with the `flaky = True` attribute, but this requires +# the buildcop to make frequent code edits. +# This flag is not recommended for local builds: flakiness is more likely to get fixed if it is +# observed during development. +# +# Note that when passing after the first attempt, Bazel will give a special "FLAKY" status rather than "PASSED". +test:ci --flaky_test_attempts=2 +# Docs: https://registry.build/flag/bazel@8.3.0?filter=flaky_test_attempts + +# Fixes builds hanging on CI that get the TCP connection closed without sending RST packets. +common:ci --grpc_keepalive_time="30s" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=grpc_keepalive_time + +# Output a heap dump if an OOM is thrown during a Bazel invocation +# (including OOMs due to `--experimental_oom_more_eagerly_threshold`). +# The dump will be written to `/.heapdump.hprof`. +# You should configure CI to upload this artifact for later inspection. +common --heap_dump_on_oom +# Docs: https://registry.build/flag/bazel@8.3.0?filter=heap_dump_on_oom + +# Allow the Bazel server to check directory sources for changes. Ensures that the Bazel server +# notices when a directory changes, if you have a directory listed in the srcs of some target. +# Recommended when using [copy_directory](https://github.com/bazel-contrib/bazel-lib/blob/main/docs/copy_directory.md) +# and [rules_js](https://github.com/aspect-build/rules_js) since npm package are source directories inputs to copy_directory actions. +startup --host_jvm_args="-DBAZEL_TRACK_SOURCE_DIRECTORIES=1" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=host_jvm_args + +# By default, Bazel automatically creates __init__.py files for py_binary and py_test targets. +# From https://github.com/bazelbuild/bazel/issues/10076: +# > It is magic at a distance. +# > Python programmers are already used to creating __init__.py files in their source trees, +# > so doing it behind their backs introduces confusion and changes the semantics of imports +common --incompatible_default_to_explicit_init_py +# Docs: https://registry.build/flag/bazel@8.3.0?filter=incompatible_default_to_explicit_init_py + +# Accept multiple --modify_execution_info flags, rather than the last flag overwriting earlier ones. +common --incompatible_modify_execution_info_additive +# Docs: https://registry.build/flag/bazel@8.3.0?filter=incompatible_modify_execution_info_additive + +# Make builds more reproducible by using a static value for PATH and not inheriting LD_LIBRARY_PATH. +# Use `--action_env=ENV_VARIABLE` if you want to inherit specific variables from the environment where Bazel runs. +# Note that doing so can prevent cross-user caching if a shared cache is used. +# See https://github.com/bazelbuild/bazel/issues/2574 for more details. +common --incompatible_strict_action_env +# Docs: https://registry.build/flag/bazel@8.3.0?filter=incompatible_strict_action_env + +# Fail the build if the MODULE.bazel.lock file is out of date. +# Using this mode in ci prevents the lockfile from being out of date. +common:ci --lockfile_mode="error" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=lockfile_mode + +# On CI, don't download remote outputs to the local machine. +# Most CI pipelines don't need to access the files and they can remain at rest on the remote cache. +# Significant time can be spent on needless downloads, which is especially noticeable on fully-cached builds. +# +# If you do need to download files, the fastest options are: +# - (preferred) Use `remote_download_regex` to specify the files to download. +# - Use the Remote Output Service (https://blog.bazel.build/2024/07/23/remote-output-service.html) +# to lazy-materialize specific files after the build completes. +# - Perform a second bazel command with specific targets and override this flag with the `toplevel` value. +# - To copy executable targets, you can use `bazel run --run_under=cp //some:binary_target `. +common:ci --remote_download_outputs="minimal" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=remote_download_outputs + +# On CI, fall back to standalone local execution strategy if remote execution fails. +# Otherwise, when a grpc remote cache connection fails, it would fail the build. +common:ci --remote_local_fallback +# Docs: https://registry.build/flag/bazel@8.3.0?filter=remote_local_fallback + +# On CI, extend the maximum amount of time to wait for remote execution and cache calls. +common:ci --remote_timeout=3600 +# Docs: https://registry.build/flag/bazel@8.3.0?filter=remote_timeout + +# Do not upload locally executed action results to the remote cache. +# This should be the default for local builds so local builds cannot poison the remote cache. +# +# Note that this flag is flipped to True under --config=ci, see below. +common --noremote_upload_local_results +# Docs: https://registry.build/flag/bazel@8.3.0?filter=remote_upload_local_results + +# On CI, upload locally executed action results to the remote cache. +common:ci --remote_upload_local_results +# Docs: https://registry.build/flag/bazel@8.3.0?filter=remote_upload_local_results + +# Repository rules, such as rules_jvm_external: put Bazel's JDK on the path. +# Avoids non-hermeticity from dependency on a JAVA_HOME pointing at a system JDK +# see https://github.com/bazelbuild/rules_jvm_external/issues/445 +common --repo_env="JAVA_HOME=../bazel_tools/jdk" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=repo_env + +# Reuse sandbox directories between invocations. +# Directories used by sandboxed non-worker execution may be reused to avoid unnecessary setup costs. +# Saves time on sandbox creation and deletion when many of the same kind of action is spawned during the build. +common --reuse_sandbox_directories +# Docs: https://registry.build/flag/bazel@8.3.0?filter=reuse_sandbox_directories + +# Don't allow network access for build actions in the sandbox by default. +# Avoids accidental non-hermeticity in actions/tests which depend on remote services. +# Developers should tag targets with `tags=["requires-network"]` to be explicit that they need network access. +# Note that the sandbox cannot print a message to the console if it denies network access, +# so failures under this flag appear as application errors in the networking layer. +common --nosandbox_default_allow_network +# Docs: https://registry.build/flag/bazel@8.3.0?filter=sandbox_default_allow_network + +# Only show progress every 60 seconds on CI. +# We want to find a compromise between printing often enough to show that the build isn't stuck, +# but not so often that we produce a long log file that requires a lot of scrolling. +common:ci --show_progress_rate_limit=60 +# Docs: https://registry.build/flag/bazel@8.3.0?filter=show_progress_rate_limit + +# The printed files are convenient strings for copy+pasting to the shell, to execute them. +# This option requires an integer argument, which is the threshold number of targets above which result information is not printed. +# Show the output files created by builds that requested more than one target. +# This helps users locate the build outputs in more cases. +common --show_result=20 +# Docs: https://registry.build/flag/bazel@8.3.0?filter=show_result + +# On CI, add a timestamp to each message generated by Bazel specifying the time at which the message was displayed. +# This makes it easier to reason about what were the slowest steps on CI. +common:ci --show_timestamps +# Docs: https://registry.build/flag/bazel@8.3.0?filter=show_timestamps + +# The terminal width in columns. Configure this to override the default value based on what your CI system renders. +common:ci --terminal_columns=143 +# Docs: https://registry.build/flag/bazel@8.3.0?filter=terminal_columns + +# Output test errors to stderr so users don't have to `cat` or open test failure log files when test fail. +# This makes the log noisier in exchange for reducing the time-to-feedback on test failures for users. +common --test_output="errors" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=test_output + +# Stream stdout/stderr output from each test in real-time. +# This provides immediate feedback during test execution, useful for debugging test failures. +common:debug --test_output="streamed" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=test_output + +# Run one test at a time in exclusive mode. +# This prevents test interference and provides clearer output when debugging test issues. +common:debug --test_strategy="exclusive" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=test_strategy + +# The default test_summary ("short") prints a result for every test target that was executed. +# In a large repo this amounts to hundreds of lines of additional log output when testing a broad wildcard pattern like //... +# This value means to print information only about unsuccessful tests that were run. +test:ci --test_summary="terse" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=test_summary + +# Prevent long running tests from timing out. +# Set to a high value to allow tests to complete even if they take longer than expected. +common:debug --test_timeout=9999 +# Docs: https://registry.build/flag/bazel@8.3.0?filter=test_timeout + +# Activate the ASan cc_feature (score_asan) for the //sanitizers/flags:asan_on config_setting. +build:asan --@score_cpp_policies//sanitizers/flags:asan +# Docs: https://registry.build/flag/bazel@8.3.0?filter=@score_cpp_policies//sanitizers/flags:asan + +# Activate the LSan cc_feature (score_lsan) for the //sanitizers/flags:lsan_on config_setting. +build:lsan --@score_cpp_policies//sanitizers/flags:lsan +# Docs: https://registry.build/flag/bazel@8.3.0?filter=@score_cpp_policies//sanitizers/flags:lsan + +# Activate the TSan cc_feature (score_tsan) for the //sanitizers/flags:tsan_on config_setting. +build:tsan --@score_cpp_policies//sanitizers/flags:tsan +# Docs: https://registry.build/flag/bazel@8.3.0?filter=@score_cpp_policies//sanitizers/flags:tsan + +# Activate the UBSan cc_feature (score_ubsan) for the //sanitizers/flags:ubsan_on config_setting. +build:ubsan --@score_cpp_policies//sanitizers/flags:ubsan +# Docs: https://registry.build/flag/bazel@8.3.0?filter=@score_cpp_policies//sanitizers/flags:ubsan + +# Run the consumer's clang-tidy aspect (see clang_tidy/README.md step 3-4) under --config=clang-tidy. +test:clang-tidy --aspects="//tools/lint:linters.bzl%clang_tidy_aspect" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=aspects + +# Keep debug symbols (-g1, --strip=never) so sanitizer stack traces are readable. +build:asan --config="with_debug_symbols" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=config + +# Keep debug symbols (-g1, --strip=never) so sanitizer stack traces are readable. +build:ubsan --config="with_debug_symbols" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=config + +# Keep debug symbols (-g1, --strip=never) so sanitizer stack traces are readable. +build:lsan --config="with_debug_symbols" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=config + +# Keep debug symbols (-g1, --strip=never) so sanitizer stack traces are readable. +build:tsan --config="with_debug_symbols" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=config + +# Composite config: address + leak + UB checking together. +build:asan_ubsan_lsan --config="asan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=config + +# Composite config: address + leak + UB checking together. +build:asan_ubsan_lsan --config="ubsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=config + +# Composite config: address + leak + UB checking together. +build:asan_ubsan_lsan --config="lsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=config + +# Composite config: thread + UB checking together. +build:tsan_ubsan --config="tsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=config + +# Composite config: thread + UB checking together. +build:tsan_ubsan --config="ubsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=config + +# Use the LLVM toolchain registered by the consumer's llvm_toolchain extension for clang-tidy. +test:clang-tidy --extra_toolchains="@llvm_toolchain//:cc-toolchain-x86_64-linux" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=extra_toolchains + +# Emit -g1 debug info under any sanitizer config so stack traces resolve symbols. +test:with_debug_symbols --features="debug_symbols" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=features + +# Compile/link with -fsanitize=address via the score_asan cc_feature. +build:asan --features="score_asan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=features + +# Compile/link with -fsanitize=undefined via the score_ubsan cc_feature. +build:ubsan --features="score_ubsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=features + +# Compile/link with -fsanitize=leak via the score_lsan cc_feature. +build:lsan --features="score_lsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=features + +# Compile/link with -fsanitize=thread via the score_tsan cc_feature. +build:tsan --features="score_tsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=features + +# Surface the rules_lint_report output group produced by the clang-tidy aspect. +test:clang-tidy --output_groups="+rules_lint_report" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=output_groups + +# Disambiguate the asan output tree from plain builds. +build:asan --platform_suffix="asan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=platform_suffix + +# Disambiguate the ubsan output tree from plain builds. +build:ubsan --platform_suffix="ubsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=platform_suffix + +# Disambiguate the lsan output tree from plain builds. +build:lsan --platform_suffix="lsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=platform_suffix + +# Disambiguate the tsan output tree from plain builds. +build:tsan --platform_suffix="tsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=platform_suffix + +# Canonical suffix for the composite asan+ubsan+lsan config, overriding the per-sanitizer suffixes. +build:asan_ubsan_lsan --platform_suffix="asan_ubsan_lsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=platform_suffix + +# Canonical suffix for the composite tsan+ubsan config, overriding the per-sanitizer suffixes. +build:tsan_ubsan --platform_suffix="tsan_ubsan" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=platform_suffix + +# Run tests under the sanitizers wrapper so suppressions/options env files are applied. +test:asan --run_under="@score_cpp_policies//sanitizers:wrapper" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=run_under + +# Run tests under the sanitizers wrapper so suppressions/options env files are applied. +test:ubsan --run_under="@score_cpp_policies//sanitizers:wrapper" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=run_under + +# Run tests under the sanitizers wrapper so suppressions/options env files are applied. +test:lsan --run_under="@score_cpp_policies//sanitizers:wrapper" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=run_under + +# Run tests under the sanitizers wrapper so suppressions/options env files are applied. +test:tsan --run_under="@score_cpp_policies//sanitizers:wrapper" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=run_under + +# Never strip symbols under any sanitizer config so stack traces remain readable. +build:with_debug_symbols --strip="never" +# Docs: https://registry.build/flag/bazel@8.3.0?filter=strip