Conversation
Builds v8 (branch-heads/14.4) from source for riscv64, the shape upstream already uses for x64/arm64: a build-dll job runs v8_build.py to produce libmini_racer.so, then build-wheel packages it into a single py3-none-manylinux_riscv64 wheel (the .so is not linked against libpython, so one wheel serves every interpreter). v8's own riscv64 codegen backend (src/codegen/riscv) is mature and actively developed; the gap is entirely in tooling: PyMiniRacer's build script does not recognize riscv64 as a host arch, its wheel tagging mislabels non-aarch64 riscv builds as x86_64, and Chromium's prebuilt clang is only published for amd64/arm64/mac hosts, so the build must use v8's existing riscv64-linux-gnu- gcc_toolchain instead. All three are patched in patches/mini-racer/0.14.1/.
luhenry
added a commit
that referenced
this pull request
Sep 13, 2026
CI hit gclient sync's 'gsutil' bootstrap lockfile.LockError: [Errno 11] Resource temporarily unavailable, from concurrent sync workers racing to fetch the shared gsutil binary. depot_tools already serializes sync (--jobs=1) for 32-bit arm boards for the same reason; do the same for riscv64. https://github.com/riseproject-dev/python-wheels/actions/runs/34731759983/job/103655726279
CI's gclient sync got past the gsutil lockfile race and then failed resolving two CIPD packages neither published for linux-riscv64: infra/rbe/client (remote build execution) and build/siso (the siso build tool). Both are optional accelerators the plain gn+ninja build never needs; skip them via custom_deps. https://github.com/riseproject-dev/python-wheels/actions/runs/34732817721/job/103658674867
CI proved the previous approach wrong: gclient still tried (and failed) to resolve infra/rbe/client/linux-riscv64 and build/siso/linux-riscv64 with the custom_deps override in place. CipdDependency.run() never consults the Dependency.url a custom_deps override changes, only should_process, which is derived straight from the DEPS-declared condition -- so nulling out a custom_deps entry can never skip a CIPD package. A global host_cpu var override doesn't work either: gn and ninja share the exact same guard clause and do have riscv64 packages, so spoofing host_cpu would stop them being fetched too. Patch the two conditions in the checked-out v8/DEPS directly instead, after letting the first sync attempt run to completion (it always finishes cloning v8 before it gets to CIPD resolution). https://github.com/riseproject-dev/python-wheels/actions/runs/34734236315/job/103662627780
CI proved the retry itself wrong: gclient still re-resolved and
re-checked-out the v8 solution as normal (branch-heads/14.4 is a
branch name, not a pinned hash, so the current_revision fast path
never applied), refusing to proceed over our uncommitted DEPS edit
("You have uncommitted changes"). Drop --revision from the retry so
the .gclient's "managed: False" takes effect (only happens when there
is no revision override), skipping v8's git step entirely rather than
touching the working tree.
https://github.com/riseproject-dev/python-wheels/actions/runs/34735996717/job/103669201128
…alse on riscv64 CI got past the DEPS/CIPD fixes into an actual ninja build for the first time, surfacing three independent problems: the bundled debian_trixie_riscv64-sysroot is missing a multiarch header our riscv64-linux-gnu- toolprefix trick expects, v8's custom libc++ needs GCC 15+ (ours is older), and the prebuilt Rust toolchain segfaults on riscv64 (published for amd64/arm64/mac hosts only, same as clang). https://github.com/riseproject-dev/python-wheels/actions/runs/34738407307/job/103678169855
luhenry
added a commit
that referenced
this pull request
Sep 13, 2026
sqreen/PyMiniRacer's own README deprecates it in favor of the bpcreech/PyMiniRacer fork, which continues under the PyPI name mini-racer (already being ported in PR #1875). py-mini-racer's last PyPI release stayed at 0.6.0 (2021-04-22).
enable_rust=false alone doesn't work: gn gen failed with
'assert(enable_rust)' in build/rust/gni_impl/rust_target.gni, reached
via v8_maybe_temporal -> third_party/rust/temporal_capi.
v8_enable_temporal_support's own default already excludes ppc64 and
s390x by name ('some architectures don't have Rust toolchains in
Chromium') -- riscv64 is simply missing from that list. Temporal is
runtime-flag-gated even when built in, so disabling it drops no
default-on behavior.
https://github.com/riseproject-dev/python-wheels/actions/runs/34742097041/job/103685126595
…stall patch(1)
CI got past gn gen and almost an hour into the actual ninja build,
then failed compiling with GCC (is_clang=false):
../../src/strings/unicode.h:218:13: error: explicit specialization
in non-namespace scope 'class unibrow::Utf8'
unibrow::Utf8::WriteLeadingAscii's two explicit specializations are
declared a second time inside the class body; clang accepts this as
an extension, GCC correctly rejects it (explicit specializations of a
member template must be at namespace scope). The out-of-line
definitions in unicode.cc are already namespace-scope and
standard-conformant on their own, so the in-class declarations are
both redundant and non-portable. Wire up the previously-unused
apply_patch() to drop them for a riscv64 build, and install the
patch(1) utility it shells out to.
https://github.com/riseproject-dev/python-wheels/actions/runs/34744357842/job/103689419698
CI got past the unicode.h fix and ~46% (1011/2176) into the ninja
build before hitting another GCC-only warning-as-error in
bigint/mul-karatsuba.cc ('1 << (shift - 2)' is int, compared against a
uint32_t; clang doesn't flag it, GCC does under -Wsign-compare). Cast
it explicitly. Renamed the accumulating patch to reflect that this is
evidently a class of issue, and pass ninja -k 1000 on riscv64 so one
build surfaces as many of these as it can find, instead of one
discovery per multi-hour CI cycle.
https://github.com/riseproject-dev/python-wheels/actions/runs/34748309593/job/103700194955
The -k 1000 run paid off: instead of one failure per cycle it collected all six that were left, and the job died at exactly timeout-minutes: 1440 with the build at 1970/2176 and still progressing normally -- so the cancellation was the timeout, not an infra flake or a hold. Five of the six are -Werror diagnostics GCC emits and clang does not (-Wuninitialized x53 in liftoff-compiler.cc, -Wdangling-reference in js-call-reducer.cc and js-typed-lowering.cc, -Wsign-compare in maglev-graph-builder.cc, -Wparentheses in collection-barrier.cc), all benign or false positives. V8 only gates -Werror on clang for third_party code precisely because "GCC may emit unsuppressible warnings", so set treat_warnings_as_errors=false rather than keep casting one line per 24h cycle, and drop the one cast already added for that reason. The sixth is a genuine error in third_party/highway: json-stringifier.cc wants a 16-lane FixedTag, highway resolved to HWY_SCALAR because its EMU128 opt-out disables EMU128 for any GCC below 16.0 at the revision v8 pins. On RISC-V without the V extension EMU128 is the only fallback that has fixed-width tags at all; highway has since fixed this upstream and names V8's JSON stringifier as the breakage, so backport the carve-out. Drop ninja -k 1000 now that the class it was hunting is gone -- past this point it only turns a fast failure into a 24h timeout -- and raise timeout-minutes to 2880, the value build-nodejs-wheel-binaries.yml and build-vtk.yml already use for full-V8-from-source work on these 4-core runners. 23h30m only reached 90% of ninja, so 24h was never enough. https://github.com/riseproject-dev/python-wheels/actions/runs/34755707688/job/103719604859
The branch sat open for six days and the repo moved: _setup.yml now takes a required package: input and hands back a JSON list of the versions to build, and pr-checks.yml grew a check_packages_yaml job that enforces it. Calling _setup.yml with no inputs is a startup failure, so the last push produced a run with no jobs at all rather than a build -- nothing to do with the v8 fixes it carried. Bring the workflow to the shape every recently-merged sibling uses (build-nodejs-wheel-binaries.yml is the closest, being the other V8-from-source port): * add docs/packages/mini-racer.yaml with one pending 0.14.1 entry. This was missing outright, which is also why check_packages_yaml failed; the version belongs there, never in the workflow. * call _setup.yml with package: mini-racer, and iterate matrix.version over its versions output in all three jobs, gated on needs.setup.outputs.versions != '[]', instead of hardcoding 0.14.1 in nine places. * turn the workflow_dispatch input into the standard optional version glob rather than a required tag. * add the push: trigger that was missing, restrict both path triggers to main, and list docs/packages/mini-racer.yaml in them. * pass secrets.RISEPROJECT_APP_PRIVATE_KEY to _publish-wheel.yml, as 708 of the 711 workflows on main do; without it the documentation PR gets no checks.
build_wheel installs the wheel and runs pytest under four interpreters on a 4-core riscv64 runner, and it only starts after build_dll has spent a day compiling V8. Hitting the implicit 360-minute default there would cost that whole day again to find out, so state the timeout with margin instead of inheriting one sized for a normal job.
luhenry
added a commit
that referenced
this pull request
Sep 19, 2026
Record what PR #1875's stalled run actually was and what unblocked it, so nobody re-reads that cancellation as a maintainer stop signal: the build_dll job ran exactly its 1440-minute timeout with ninja still progressing at 1970/2176, the six remaining compile failures are now fixed, and the branch has been caught up with main's _setup.yml contract after six days of drift. Still ci-running; the V8 compile needs over a day, so the branch must be left alone until it lands.
Contributor
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Important
Needs a maintainer decision on runner cost before merge — do not merge silently.
build_dllcarriestimeout-minutes: 2880(48h). That is a ceiling, not an allocation: the measured build is ~27h wall on a 4-core riscv64 runner (23h30m of ninja reached 1970/2176 targets, still progressing normally when the old 1440 ceiling killed it). The previous 24h ceiling was below the build's real cost, so it destroyed a full day of runner time and would have had it repeated — raising it lowers total runner consumption rather than raising it. The build is already parallel (measured: 21% of ninja completions land sub-second apart) and-g0/is_debug=false; the only ways to go materially faster are dropping WebAssembly, Intl/ICU or the optimizing tiers from the engine, which would make this wheel functionally different from mini-racer on every other platform. Same reasoning and same value asbuild-nodejs-wheel-binaries.yml(the other V8-from-source port: "a prior run needed ~23h16m and the next one was still compiling V8 objects when killed at the 24h mark") andbuild-vtk.yml. If ~27h per release is judged too expensive for the shared pool, this port should be parked rather than trimmed.mini-racer0.14.1Builds V8 (branch-heads/14.4) from source and embeds it as a minimal Python JS engine. Upstream publishes no riscv64 wheel.
Mirrors upstream's
build.ymlbuild-dll/build-wheeljobs, narrowed to Linux glibc riscv64.Differs from upstream
riscv64-linux-gnu-gcc_toolchain - Chromium's prebuilt clang has no riscv64 host build.Matrix: one riscv64 build, not one per interpreter; the wheel is
py3-none-<platform>, so one V8 build serves all four.Testing
pytest tests), run once per bundled interpreter (cp312/cp313/cp314/cp314t).License: OK
Patches (all
Upstream-Status: To upstream, all riscv64-only, all againstbuilder/v8_build.py)0001-0003- recognise riscv64 as a nativev8_target_cpu, give it its own manylinux tag, select the gcc_toolchain; without them the build fetches an unusable x86_64 clang and mislabels the wheel as x86_64.0004-0006- serializegclient syncand patch out the reclient/siso CIPD packages, which are not published for linux-riscv64.0007-0008- drop the cross sysroot, V8's custom libc++ and Rust/Temporal; none of them works on a native riscv64 GCC host.0009,0011- the two V8 sources GCC cannot compile (an explicit specialization inside a class body, andthird_party/highwayfalling back toHWY_SCALAR, which has noFixedTag<T, 16>for the JSON stringifier), plustreat_warnings_as_errors=falsefor the GCC-only warnings V8 gates on clang.Pending CI.