Skip to content

kepler-formal: delete the submodule and the per-platform build code; a bump is one line - #4732

Open
oharboe wants to merge 9 commits into
The-OpenROAD-Project:masterfrom
oharboe:kepler-formal-bazel
Open

oharboe wants to merge 9 commits into
The-OpenROAD-Project:masterfrom
oharboe:kepler-formal-bazel

Conversation

@oharboe

@oharboe oharboe commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator

Bumping kepler-formal becomes a one-line edit: the version in etc/kepler-formal/MODULE.bazel. You don't move a submodule, and you don't chase new system packages on each platform.

A build breakage like #4717 is fixed and tested in kepler-formal's own CI, not patched in ORFS's scripts.

What ORFS no longer maintains

What doesn't change for users

  • ./build_openroad.sh --local is run the same way.
  • The binary still lands in tools/install/kepler-formal/bin/kepler-formal.
  • env.sh, KEPLER_FORMAL_EXE and LEC_CHECK are unchanged.
  • The Docker images are built the same way.

How

build_openroad.sh runs kepler-formal's own install target, bazelisk run //:install, from etc/kepler-formal/, the way it already builds OpenROAD. That folder pins kepler-formal and nothing else. ORFS itself does not become a Bazel project. Nothing new is needed on the host. The folder's README.md explains how to bump kepler-formal and how each step maps to what DependencyInstaller.sh did.

Why this is possible now

kepler-formal now installs this way after a number of PRs to kepler-formal and the Bazel Central Registry. Its install target, keplertech/kepler-formal#292, and its registry entry, bazelbuild/bazel-central-registry#11201, are both merged, so MODULE.bazel takes kepler-formal@0.5.0-20261026-a64adfaf from the registry with no override.

So far the way to install kepler-formal has been CMake plus host packages. That costs kepler-formal the same per-platform work it costs ORFS, so I expect kepler-formal to streamline its own install too. Each step upstream only makes this folder shorter, and the interface doesn't change.

How it was tested

CI tests build_openroad.sh on every supported platform, so locally I only ran smoke tests:

  • etc/kepler-formal: bazelisk run //:install -- <prefix>, from a cold start with the registry version, installs on x86-64 Linux with no host packages. kepler-formal --version runs, including from a copy of the install in another directory.
  • bash -n build_openroad.sh and bash -n etc/DependencyInstaller.sh pass.

🤖 Generated with Claude Code

The absolute RUNPATH tied bin/kepler-formal to the directory it was
built in, so a moved or re-pointed checkout loaded another build's
libnaja_*.so. Use $ORIGIN/../lib, and @loader_path/../lib on macOS.

Fixes The-OpenROAD-Project#4717.

Signed-off-by: Skot <48910715+saikatchatrg@users.noreply.github.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the manual CMake compilation of the kepler-formal tool and its dependencies with a Bazel-based installation using bazelisk. It removes the tools/kepler-formal submodule, cleans up related dependencies from etc/DependencyInstaller.sh, and introduces Bazel configuration files under etc/kepler-formal. Feedback on these changes includes ignoring Bazel build outputs in .dockerignore to keep the Docker build context small, correcting the ignored symlink name in .gitignore to match the workspace name orfs-kepler-formal, and avoiding the use of a personal fork as a Bazel registry in .bazelrc due to security and reliability risks.

Comment thread .dockerignore Resolved
Comment thread .gitignore Resolved
Comment thread etc/kepler-formal/.bazelrc Resolved
oharboe and others added 4 commits October 25, 2026 07:16
A small Bazel module that only pins kepler-formal; ORFS itself does not
become a Bazel project. From this folder,

    bazelisk run //:install -- <prefix>

installs bin/kepler-formal with everything it loads next to it.
Bumping kepler-formal is the version line in MODULE.bazel. README.md
says how this maps to DependencyInstaller.sh, and which lines go away
as kepler-formal's registry entry and install target merge upstream.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Instead of building kepler-formal with CMake, run its install target
from etc/kepler-formal, as Build.sh already builds OpenROAD with Bazel.
This drops the per-architecture -march choice, the EL9 TBB define, the
LTO flags, the build and install RPATHs (The-OpenROAD-Project#4717) and the gcc-toolset-13
setup that only kepler-formal needed. The binary still lands in
tools/install/kepler-formal/bin/kepler-formal, and it loads its
libraries from next to itself, wherever the install is moved.

The Docker builder copies etc/kepler-formal into the image, and the
tools image tag covers it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
build_openroad.sh installs kepler-formal from the version pinned in
etc/kepler-formal, so the submodule, and the five submodules inside
it, are no longer checked out. Its build directory leaves
.dockerignore and its commit leaves the tools image tag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
kepler-formal no longer builds against host packages: capnproto and
TBB on Ubuntu, EL and Homebrew, the oneTBB source build on EL8 and
gcc-toolset-13 on EL8 go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe
oharboe force-pushed the kepler-formal-bazel branch from d078245 to 2aa8f0a Compare October 25, 2026 06:17
@oharboe
oharboe requested a review from vvbandeira October 25, 2026 06:45
@oharboe
oharboe marked this pull request as ready for review October 25, 2026 06:45
@oharboe
oharboe requested a review from a team as a code owner October 25, 2026 06:45
@oharboe

oharboe commented Oct 25, 2026

Copy link
Copy Markdown
Collaborator Author

@vvbandeira ready for review.

The CI-Public/pr-merge failure is not from this PR. It is a regression on master that every open PR hits now, for example #4731, and pr-merge will re-run once it is fixed. pr-head doesn't matter once pr-merge is green. Jenkins fails in the OpenROAD build step, before the flow tests run:

Error downloading [https://github.com/MikePopoloski/slang/archive/f04e81565793c768b747a8fd058f3e7aeceee1b5.tar.gz]
Checksum was sha256-Pj8AVITB12EZCg7lD3wYZpuHgcexydYPQsOUh77CWqg= but wanted sha256-7SEVSm6uJ56ZBFyPoKeuLh6cpXLTl17x8iqBGomouLA=

GitHub now serves a different archive for that slang commit than the one recorded in the Bazel Central Registry entry sv-lang@10.0.1-20260316-f04e8156.

The step this PR changes passed in the same Jenkins runs. On both Ubuntu 26.04 and 24.04, the tools image ran bazelisk run //:install from etc/kepler-formal, and it printed kepler-formal installed to /OpenROAD-flow-scripts/tools/install/kepler-formal/bin/kepler-formal.

@oharboe

oharboe commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator Author

@maliberty @povik @vvbandeira Regarding unrelated pr-merge/head failure with github sv lang .tar.gz updated hash.

Once we're switched to Bazel only in OpenROAD, we can get all yosys+sv-lang, etc. into bazel bcr instead of git submodules.

Then we're no longer vulnerable to hash upates on github and it is bazel idiomatic.

That's a bit of an ordeal to untangle, I only have a vague sense of all the details, but worth it as it makes life for everyone simpler going forward.

@oharboe oharboe changed the title kepler-formal: bump with one line, no submodule, no per-platform build flags kepler-formal: delete the submodule and the per-platform build code; a bump is one line Oct 29, 2026
@openroad-ci

openroad-ci commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

🔍 QoR check

Metrics reflect the PR merge build — i.e. what will land on the target branch.

Commit 7b3387b · Jenkins build #7 · Baseline: build · View build on dashboard

62 design(s) checked — 0 with regression(s), 1 without a comparable baseline.

@saikatchatrg

Copy link
Copy Markdown

Checked #4732 at 2aa8f0a for the #4717 case. bazelisk run //:install from etc/kepler-formal, as build_openroad.sh runs it, built and installed in 109 s here (Ubuntu, x86-64). The installed bin/kepler-formal has only $ORIGIN-relative RUNPATH entries into bin/kepler-formal.runfiles/, and ldd resolves its two non-system libraries (libnaja_runtime.so and the bundled libpython3.11.so.1.0) there. The binary contains no build path and the install has no symlinks. I copied the install to another directory and renamed the original away: the copy loads both libraries from inside itself, and a small SystemVerilog SEC run from the copy proves an equivalent pair (exit 0) and gives a counterexample for a non-equivalent one (exit 3). So with this PR a moved or re-pointed install no longer loads another build's libraries. One leftover, outside #4717: the bundled Python's libtcl8.6.so and libtk8.6.so keep an absolute RPATH, /tools/deps/lib, from python-build-standalone; kepler-formal does not load them.

#4727 fixes the same RUNPATH with a one-line change to the CMake build this PR removes; I'll close it once this lands.

@oharboe

oharboe commented Nov 1, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for checking the #4717 case on a moved install, @saikatchatrg.

The libtcl8.6.so/libtk8.6.so RPATH comes with python-build-standalone's prebuilt Python, which the Bazel Python rules download. kepler-formal does not load Tcl/Tk through it, so I'll leave it out of this PR; if it ever matters, the fix belongs in python-build-standalone.

Agreed on closing #4727 once this lands: its RUNPATH fix is one line in a CMake build that this PR deletes.

Why this replaces the CMake build rather than patching it:

CI-Public/pr-merge errors on every open PR and on master; it is not caused by this PR.

@saikatchatrg

Copy link
Copy Markdown

Thanks for the explanation and for taking this on. Building kepler-formal through its own //:install, as ORFS already builds OpenROAD, removes the whole class of problem #4717 hit rather than one flag of it.

@maliberty

Copy link
Copy Markdown
Member

@nanocoh any concerns?

Comment thread etc/kepler-formal/MODULE.bazel Outdated
Comment on lines +12 to +19
# TODO(keplertech/kepler-formal#292): delete this override once a
# kepler-formal version with the //:install target is on the registry,
# and move the version above to it.
git_override(
module_name = "kepler-formal",
commit = "99d66cac88978312853a10b82657781f8e99d843",
remote = "https://github.com/oharboe/kepler-formal.git",
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

292 is merged

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The git_override is gone: kepler-formal@0.5.0-20261026-a64adfaf comes from the BCR (bazelbuild/bazel-central-registry#11201 merged), and it has //:install. 65fab0f

@nanocoh

nanocoh commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

@nanocoh any concerns?

Looks good as long as the regress is clean and we can occasionally use git_overide when bcr is not up to date.

@oharboe

oharboe commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator Author

@nanocoh any concerns?

Looks good as long as the regress is clean and we can occasionally use git_overide when bcr is not up to date.

Yes, you still can. This can be convenient when making improvements that ORFS cares about and then using git_override() to pick them up until next release is available. You could also carry a patch in ORFS on top of an official release, which I sometimes prefer over git_override() because it is is naturally scrubbed out in a bazel bcr bump. git_override() should come with a comment as to why the release isn't being used. Which approach is better while waiting for a bazel bcr bump of a module all depends on the specifics of each circumstance; normally I'd only carry tiny patches and use git_override() if there are lots of updates.

oharboe and others added 3 commits November 4, 2026 11:03
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
kepler-formal 0.5.0-20261026-a64adfaf is on the Bazel Central Registry
and has the //:install target, so the git_override on a fork goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
kepler-formal keeps its clang toolchain a dev_dependency on purpose, so
a module that depends on it registers the toolchain itself; the README
no longer says these lines go away. llvm moves to 0.8.26, the version
kepler-formal builds with.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@oharboe
oharboe requested a review from maliberty November 4, 2026 10:49
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
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.

5 participants