From c20829e6a8fba44450e35492656a598d341275c6 Mon Sep 17 00:00:00 2001 From: Mark Schaller Date: Sat, 26 Sep 2026 02:32:27 -0400 Subject: [PATCH] Say which cc_library attributes propagate to dependents CMake scopes a compile definition or include directory to a target (PRIVATE) or its consumers (PUBLIC/INTERFACE). In Bazel the attribute decides: `defines`, `includes` and `linkopts` propagate to every dependent, while `copts`, `local_defines` and `local_includes` stay with the target, and `implementation_deps` keeps a dependency's headers private. The per-TU diff only checks that each TU gets what CMake gave it, so a PRIVATE define written as `defines` converges while changing how every consumer compiles (a visibility macro such as _EXPORTS turning on export-side behavior in consumers is the classic case). The only signal would be a WARN-level extra define on each consumer's TUs. "Create initial BUILD.bazel files" now lists both groups and says where private defines and include directories go. `local_includes` arrived in rules_cc 0.2.19 (June 2026), so the text gives the `copts` -I fallback for older versions. The scopes are as Bazel's cc_library documentation states them. Observed in any2bazel-lab: a lensfun migration avoided this unprompted, putting its visibility and _EXPORTS defines in local_defines for exactly this reason. No run has yet been seen getting it wrong. In the lab's later lensfun run with an earlier version of this change (one sentence, on defines only), the agent again kept those defines in local_defines. Lab-Proposal: P7 Co-Authored-By: Claude Opus 5.5 --- SKILL.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/SKILL.md b/SKILL.md index d1687d2..3e1d7ad 100644 --- a/SKILL.md +++ b/SKILL.md @@ -295,10 +295,21 @@ recorded apart, as `test_configure_command`. ### Create initial BUILD.bazel files {#create-build-files} Read `model..json`. For each production target emit a `cc_library` / -`cc_binary` with `srcs`, `hdrs`, `copts`, `defines`, `includes`, `deps`. Library -grouping need not match the reference (TU-set comparison is -grouping-agnostic), but keep **executable** names aligned or add a `target_map` -entry. Write `MODULE.bazel` as needed — before picking rulesets or pinning +`cc_binary` with `srcs`, `hdrs`, `copts`, `defines`, `includes`, `deps`. Bazel +scopes these differently from CMake: +- `defines`, `includes` and `linkopts` propagate to every dependent, like + CMake's `PUBLIC`/`INTERFACE`. +- `copts`, `local_defines` and `local_includes` apply to the target alone, like + `PRIVATE`; `implementation_deps` keeps a dependency's headers from reaching + dependents. + +So a define or include directory the reference keeps private to one target +(such as `_EXPORTS`) belongs in `local_defines` or `local_includes`. +`local_includes` needs rules_cc 0.2.19 or later; on older versions, pass a +private include directory in `copts` as `-I`. +Library grouping need not match the reference (TU-set +comparison is grouping-agnostic), but keep **executable** names aligned or add +a `target_map` entry. Write `MODULE.bazel` as needed — before picking rulesets or pinning versions, read [docs/BAZEL-RULES.md](docs/BAZEL-RULES.md) (which rulesets have been exercised here, why some were hand-written instead, and why a version must be resolved