Skip to content

bazel: plain bazel_deps from BCR, no host tools - #457

Merged
xtofalex merged 11 commits into
najaeda:mainfrom
oharboe:bazel-bcr-ready
Oct 3, 2026
Merged

xtofalex merged 11 commits into
najaeda:mainfrom
oharboe:bazel-bcr-ready

Conversation

@oharboe

@oharboe oharboe commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Makes naja's Bazel build idiomatic, Bazel all the way down, so it can become a Bazel Central Registry module: MODULE.bazel is now only bazel_deps, using upstream BCR modules, nothing is probed on the host, and naja builds both as the root module and as a dependency (verified from kepler-formal on Bazel 8.6 with hermetic-llvm, and on Bazel 9.2).

Ready to merge once CI is green. Bazel-only change.

BCR pull requests, for now. Modules not on BCR yet come from their BCR pull requests, pinned by commit in .bazelrc, until those merge. Each .bazelrc line is replaced by the proper BCR module as it lands. Meanwhile, a root MODULE.bazel project depending on this one has to carry the same .bazelrc registry lines.

Dependencies

Before After
slang: built via rules_foreign_cc sv-lang (native Bazel build)
TBB: pkg-config wrapper around the system lib BCR onetbb
Boost: vendored tarball BCR boost.intrusive, boost.dynamic_bitset, boost.asio, boost.multiprecision
fmt, tomlplusplus: git_repository + overlays BCR fmt (tomlplusplus came only with slang)
spdlog: thirdparty/spdlog-1.17.0 BCR spdlog
bison/m4: found on PATH BCR bison (bison rule)
Python: python3-config/PATH probing rules_python toolchain (current_py_cc_headers/libs, $(PYTHON3_ROOTPATH))
cpptrace: git_override dropped, unused by the Bazel build
naja_git_version/naja_workspace_root repository rules git hash from the module version; SV tests resolve paths before chdir

Modules not on BCR yet

Each comes from its own BCR pull request, which .bazelrc lists by commit ahead of BCR; drop a line as its PR merges. There's no in-tree registry.

  • naja-if, naja-verilog (naja-if@0.0.0-20260723-099677d9 bazelbuild/bazel-central-registry#10881, #10885): new modules. naja-verilog uses BCR bison/flex instead of host tools.
  • sv-lang 11.0.0-20260701-b60d729d.bcr.1 (#10882): slang at b60d729 (BCR has f04e815, which doesn't compile against fmt 12.2). SLANG_STATIC_DEFINE, as upstream sets for static builds, which gcc 11 needs.
  • bison 3.8.2.bcr.10 (#10879): gnulib's wrapper headers on -I instead of -isystem, for toolchains that pass libc headers as -isystem (hermetic-llvm).

ci/check_submodule_bazel_sync.py reads the pins from those registries.

.bcr/ holds publish-to-bcr templates for naja itself. naja, naja-if and naja-verilog list @xtofalex and @nanocoh as BCR maintainers.

Other fixes found while consuming naja from kepler-formal

  • naja_runtime exports TBB/zlib, so binaries linking it don't link a second copy.
  • pyloader re-owns libpython (python_libs.bzl). current_py_cc_libs neither advertises CcInfo nor owns its linker inputs, so cc_shared_library filtering silently dropped libpython from binaries that link naja_runtime dynamically.
  • Explicit load()s for cc_*/sh_* (Bazel 9).
  • FF_scan.lib exported for downstream test suites.

Testing

  • bazel test //...: 20/20 pass (Bazel 8.6, host toolchain).
  • kepler-formal's bazel test //... (hermetic-llvm), and its consumer smoke test on Bazel 9.2, pass with this branch merged with Do not infer a memory for an array written from several always blocks #455.
  • bazel test //... in an ubuntu:22.04 container (gcc 11.4): 20/20 pass.
  • Bazel CI workflows no longer install any packages.

🤖 Generated with Claude Code

oharboe and others added 6 commits October 2, 2026 08:33
Make naja's Bazel build ready to be a Bazel Central Registry module:
MODULE.bazel now contains only bazel_deps.

- slang: sv-lang (native Bazel build) instead of building slang's
  CMake project through rules_foreign_cc.
- TBB, Boost, fmt, spdlog, bison/m4: the BCR onetbb, boost.*, fmt,
  spdlog and bison modules instead of pkg-config/python3-config/PATH
  probing repository rules, vendored tarballs and the vendored spdlog.
- Python: the rules_python toolchain for libpython and for the Python
  test runners.
- cpptrace, tomlplusplus: dropped; nothing in naja's Bazel build uses
  them directly.
- NajaVersion.h: the git hash comes from the module version
  (<release>-<date>-<commit> for registry builds) instead of a
  repository rule running git.
- SV frontend tests: resolve the benchmarks path before changing the
  current directory, instead of baking the workspace's absolute path in
  with a repository rule.
- Export FF_scan.lib for downstream test suites.

Modules not on BCR yet (naja-if, naja-verilog, and sv-lang at the slang
commit naja is developed against) are served by an in-tree registry in
bazel/registry/ with BCR's layout, listed ahead of BCR in .bazelrc, so
publishing them is a copy into a BCR pull request. The naja-verilog
entry's overlay uses the BCR bison/flex modules. The submodule/Bazel pin
check now reads the registry.

Bazel CI no longer installs any host packages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Binaries that link naja_runtime and also depend on TBB or zlib
themselves (kepler-formal) must use the runtime's single statically
linked copy; cc_shared_library refuses to link them twice. Match by
package, since BCR zlib's target behind @zlib//:z is in a subpackage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
slang's WaiverManager uses boost::regex header-only; with the host
toolchain it was silently picked up from /usr/include.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- bison 3.8.2.bcr.10 in the in-tree registry: BCR's bcr.9 with gnulib's
  wrapper headers on -I rather than -isystem. Toolchains that pass libc
  headers as -isystem (hermetic-llvm) otherwise shadow them and bison
  fails to compile. naja and naja-verilog ask for it.
- pyloader: re-own libpython's linker inputs. current_py_cc_libs
  forwards a toolchain target's CcInfo, which cc_binary's dynamic_deps
  filtering cannot see, so a binary linking naja_runtime dynamically
  silently dropped libpython.
- update_source.py keeps source.json fields it does not compute
  (mirror_urls, patch_strip).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cc_shared_library's graph aspect only visits rules that advertise
CcInfo; without provides=[CcInfo] the re-owned libpython was still
dropped from binaries that link naja_runtime dynamically.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bazel 9 removed the native cc_* and sh_* rules; a module consumed
under Bazel 9 must load them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
So agents (and people) keep the Bazel build BCR-ready: what may go in
MODULE.bazel, how the in-tree registry works, how to publish to BCR, and
the toolchain/linking traps already hit once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.20%. Comparing base (927b9ca) to head (114804c).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #457      +/-   ##
==========================================
- Coverage   97.26%   97.20%   -0.06%     
==========================================
  Files         246      237       -9     
  Lines       45106    43348    -1758     
==========================================
- Hits        43871    42136    -1735     
+ Misses       1235     1212      -23     
Flag Coverage Δ
unittests 97.20% <ø> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@oharboe oharboe changed the title bazel: plain bazel_deps, no cmake, no host tools bazel: plain bazel_deps from BCR, no host tools Oct 3, 2026
oharboe and others added 4 commits October 3, 2026 10:12
slang's BS_thread_pool.hpp has `class SLANG_EXPORT [[nodiscard]]
this_thread`; with SLANG_EXPORT expanding to a GNU attribute, gcc 11
rejects it, which broke the ubuntu-22.04 Bazel CI job. slang is built
as a static library, and upstream defines SLANG_STATIC_DEFINE for static
builds, which makes SLANG_EXPORT empty. The overlay now does the same.

Also replace the overlay/MODULE.bazel symlinks with copies: BCR rejects
symlinks in registry entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…latforms

- .bcr/ holds the publish-to-bcr templates for naja itself, with
  xtofalex and nanocoh as the module's BCR maintainers.
- naja-if and naja-verilog list the same maintainers.
- naja-if, naja-verilog presubmit: debian13, ubuntu2204, ubuntu2404,
  macos_arm64 on Bazel 8.x and 9.x (debian11 is past end of life).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
naja-verilog builds with the bison already on BCR, so its BCR entry
doesn't wait on bison 3.8.2.bcr.10. naja itself still asks for bcr.10
(needed with the hermetic llvm toolchain), and the highest version in
the module graph wins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bison 3.8.2.bcr.10, sv-lang 11.0.0-20260701-b60d729d.bcr.1, naja-if and
naja-verilog are submitted to BCR, one pull request each
(bazelbuild/bazel-central-registry#10879, #10882, #10881, #10885).
.bazelrc lists each PR's commit as a registry ahead of BCR, so the
in-tree registry goes away; drop a line as its PR merges.
check_submodule_bazel_sync.py reads source.json from those registries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@xtofalex

xtofalex commented Oct 3, 2026

Copy link
Copy Markdown
Member

Hi @oharboe ,
For my understanding, how further releases of naja will be managed related to BCR. What is the triggering mechanism to upload new version there. Currently for uploading new najaeda package we trigger on git tags.
Also a question: shouldn't the downstream repos: naja-verilog and naja-if BCR management be managed from the repos themselves.
About versioning, i think we should have a unique naja versioning scheme following the one that is used also for the najaeda package, which serves as global versioning and that is stored in NajaVersion.h.in .

@oharboe

oharboe commented Oct 3, 2026

Copy link
Copy Markdown
Contributor Author

how further releases of naja will be managed related to BCR. What is the triggering mechanism

There's no trigger, and none is needed. BCR versions don't have to follow naja releases or tags. A new BCR version is needed only when the Bazel files in the entry (the "overlay") have to change, for example when naja's build changes in a way the existing entry can't handle. That takes a person: someone edits the overlay, usually guiding an AI, checks it builds, and opens a BCR PR. As a listed maintainer, you approve that PR after BCR's CI has built it.

I'd advise against automatic BCR updates: they can't make the overlay changes that are the real reason to update. The .bcr/ templates in this PR are only a convenience for when you do want to publish a version. CMake and the pip/PyPI wheels are untouched by any of this.

As long as the existing entry still works with newer code, users don't need a new BCR version. They point their own build at a newer naja commit, or carry a patch.

shouldn't naja-verilog and naja-if BCR management be managed from the repos themselves

Yes, eventually. For now I've submitted them by hand, one BCR PR per module (bazelbuild/bazel-central-registry#10881 naja-if, bazelbuild/bazel-central-registry#10885 naja-verilog), at the commits naja uses, with commit-based versions. Once they're on BCR, the repos can take over.

a unique naja versioning scheme following the one used for the najaeda package, stored in NajaVersion.h.in

Agreed. MODULE.bazel already says version = "0.7.26", the same as NajaVersion.h.in, and a BCR entry for a naja version uses that version.

About urgency. With Bazel, something broken upstream is rarely urgent for a user:

  • They can point their own build at a newer commit, or at a BCR PR that hasn't merged yet; this PR does exactly that in .bazelrc while its BCR PRs wait.
  • They can carry a patch, and send it upstream if it's generally useful.
  • Any non-trivial project carries a few upstream patches anyway; that's normal, not an emergency.

So being a maintainer mostly means approving a BCR PR now and then; nothing is on your critical path.

@oharboe

oharboe commented Oct 3, 2026

Copy link
Copy Markdown
Contributor Author

@nanocoh @xtofalex Why did CI cancel builds? This is ready to merge if it goes green.

@xtofalex

xtofalex commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

@nanocoh @xtofalex Why did CI cancel builds? This is ready to merge if it goes green.

Happens sometimes with network issue when a github runner is not able to download a dependency. Others associated jobs (here wheels) get cancelled. I've relaunched them.

@xtofalex
xtofalex merged commit 20d67a2 into najaeda:main Oct 3, 2026
79 of 124 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants