Skip to content

stpyv8: Add version 13.1.201.22 - #2121

Open
luhenry wants to merge 9 commits into
mainfrom
port/stpyv8
Open

luhenry wants to merge 9 commits into
mainfrom
port/stpyv8

Conversation

@luhenry

@luhenry luhenry commented Sep 19, 2026

Copy link
Copy Markdown
Member

Wraps a from-source V8 build in a Boost.Python extension. Upstream publishes no riscv64 wheel.

Mirrors upstream's linux.yml, split into a build_v8 job and a build_wheel job so the ~48h V8 build only runs once per version.

Differs from upstream

  • is_clang=false + riscv64 gcc toolchain - Chromium's prebuilt clang has no riscv64 host build
  • Three V8 CIPD packages (reclient, siso, luci-go) patched out of DEPS - none of them is published for linux-riscv64, while gn and ninja, whose DEPS conditions have the same shape, are
  • VPYTHON_BYPASS in the V8 job - gclient downloads every dep_type: 'gcs' dep and runs every download_from_google_storage hook as vpython3 gsutil.py, and gsutil.vpython.toml pins crcmod==1.7+chromium.4, which chromium's wheel mirror does not build for riscv64
  • V8's wasm_spec_tests and wasm_js DEPS hooks conditioned off on riscv64 - the bypass above makes gsutil run on the container python 3.12, and the gsutil that V8's own DEPS-pinned depot_tools bootstraps is 4.68, whose vendored six 1.12 only implements the find_module() API CPython removed in 3.12 (ModuleNotFoundError: No module named 'six.moves'). Both hooks only unpack V8 test suites that a v8_monolith build never reads; the first-class gcs deps are unaffected because they go through the newer gsutil of the depot_tools clone driving the sync
  • One V8 source fix - building the RISC-V port with GCC instead of clang is what the toolchain choice above implies, and V8 only ever compiles that port with clang
  • Boost 1.90.0 instead of upstream's 1.87.0 - adds CPython 3.14 support. Boost 1.89 removed the Boost.System stub compiled library (header-only since 1.69), so settings.py's hardcoded boost_system entry has to go with it

Matrix: cp312/cp313/cp314 only - Boost.Python links a version-specific CPython ABI and has no free-threaded build

Testing

  • same as upstream

License: OK

Patches

  • 0001-setup-make-the-V8-checkout-work-on-a-riscv64-host.patch - Drops the three riscv64-less CIPD conditions and the two gsutil test-data hooks, unmanages the v8 solution so the tag checkout and those DEPS edits survive the sync, and serializes the sync; lets fetch/gclient sync complete on a riscv64 host.
  • 0002-settings-build-V8-with-the-riscv64-gcc-toolchain.patch - Routes gn at V8's existing gcc_toolchain("riscv64") instead of the x86_64-only prebuilt clang.
  • 0003-setup-fix-the-V8-riscv64-stack-helpers-GCC-rejects.patch - MacroAssembler::push_helper and ::pop_helper end a variadic recursion over a register pack with a one-register explicit specialization declared inside the class body, which only clang accepts (explicit specialization in non-namespace scope); V8 replaced both with an empty zero-register overload in 13.8, and this backports that shape. Also passes ninja -k 1000 on riscv64 so one build reports every remaining GCC-only failure instead of one per ten hours; to be dropped once the build is green.
  • 0004-settings-drop-the-boost_system-link-Boost-1.89-remove.patch - settings.py links boost_system unconditionally on POSIX, which no longer exists: Boost 1.89 removed the stub compiled library Boost.System had kept for link-line compatibility since it went header-only in 1.69, and boostorg/system has carried no build/ or src/ since. Not riscv64-specific - upstream only misses it because linux.yml pins Boost 1.87.0.

Built on cp312/cp313/cp314; wheel contents verified against upstream's published x86_64 wheel.

Builds V8 13.1.201.22 from source with V8's own riscv64-linux-gnu-
gcc_toolchain and wraps it in the Boost.Python extension stpyv8 ships,
mirroring upstream's linux.yml build-v8/build jobs narrowed to riscv64.
luhenry added a commit that referenced this pull request Sep 19, 2026
@github-actions

github-actions Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://riseproject-dev.github.io/python-wheels/pr-preview/pr-2121/

Built to branch gh-pages at 2026-09-21 14:03 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

The first build_v8 run died 25 minutes in, in `gclient sync`, on the gcs
dep v8/third_party/llvm-build/Release+Asserts:

    Because crcmod==1.7+chromium.4 has no wheels with a matching platform
    tag (e.g., `manylinux_2_39_riscv64`) [...] your requirements are
    unsatisfiable.

Every gcs dep, and every hook that calls download_from_google_storage,
runs gsutil under vpython3, whose spec (depot_tools/gsutil.vpython.toml)
pins crcmod==1.7+chromium.4, and chromium's wheel mirror builds that
wheel for x86_64/aarch64/arm/mac/windows only. The rest of depot_tools is
fine here -- the cipd client, the hermetic cpython3 and vpython3 itself
all have linux-riscv64 packages -- so skip the venv, not the tool:
VPYTHON_BYPASS is depot_tools' own escape hatch for a manually managed
python, and makes vpython3 exec the container's python3, where gsutil
treats crcmod as an optional accelerator. It also turns the DEPS
vpython3_common hook, which would resolve the same riscv64-less wheel
set, into a no-op.

Behind that sat a second wall of the kind patch 0001 already handles:
tools/luci-go's packages (infra/tools/luci/{isolate,swarming}) have no
linux-riscv64 build either, while gn and ninja, whose conditions are the
same shape, do. Add its condition to the ones the patch rewrites.

Invoke gclient through an absolute path as well: depot_tools' cipd
bootstrap derives its own directory from $0, so through a relative path
it looks for cipd_client_version.digests in the wrong place, which is
what printed the misleading "Platform linux-riscv64 is not supported by
the CIPD client bootstrap" in the same log.

Rehearsed under qemu-riscv64 in quay.io/pypa/manylinux_2_39_riscv64
(python3.12, no crcmod): gclient's own gcs code path,
download_from_google_storage.Gsutil.check_call("cp", ...) on the object
that failed in CI, returns 0 with VPYTHON_BYPASS set and reproduces the
resolver error without it.
gclient sync now reaches V8's DEPS hooks and dies in the first one that
shells out to download_from_google_storage.py: the gsutil that V8's own
DEPS-pinned depot_tools bootstraps is 4.68, which vendors six 1.12, whose
meta path importer only implements find_module() -- the API CPython
removed in 3.12. Its gsutil.vpython3 spec asks for python 3.8, so on a
bot it never meets a 3.12 interpreter; the VPYTHON_BYPASS that riscv64
needs to run gsutil at all hands it the container python 3.12 instead,
and the hook fails with "No module named 'six.moves'".

Only wasm_spec_tests and wasm_js are reached with V8's default variables,
and both only unpack test suites that building v8_monolith never reads,
so condition them off on riscv64 with the DEPS edit that already drops
the riscv64-less CIPD packages. Evaluating the patched DEPS through
gclient_eval leaves the two hooks off for host_cpu riscv64 and every
other hook, and all of x64, untouched.
The first run to get past gclient sync spent 9h17m in ninja and reached
1146 of 2117 targets -- as far as baseline.o, the first translation unit
that pulls in src/codegen/macro-assembler.h -- before GCC refused
src/codegen/riscv/macro-assembler-riscv.h:389 and :537, "explicit
specialization in non-namespace scope 'class v8::internal::MacroAssembler'".

Not a wall of any kind: no OOM, no ENOSPC, no ICE, no signal in the whole
log, exactly one FAILED edge, and the 48h timeout was under a fifth
spent. MacroAssembler::push_helper and ::pop_helper end a variadic
recursion over a register pack with a one-register explicit
specialization written inside the class body, which only clang accepts;
V8 builds its RISC-V port with nothing else, while settings.py has to
choose GCC because no prebuilt Chromium clang runs on a riscv64 host.

V8 itself replaced both with an empty zero-register overload in 13.8 --
the variadic overload has already stored the last register at sp+0 by the
time the pack empties -- so backport that rather than invent a fix.
Rewriting the pinned 13.1.201.22 header with this hunk reproduces 13.8's
text byte for byte, and the two forms were compiled both ways to confirm
GCC rejects only the old one and clang accepts both.

It is the only blocker of its kind left in this V8: the riscv64 sources
carry no other in-class specialization, and the two further GCC stoppers
the mini-racer V8 build hit postdate 13.1.201.22 (unicode.h has no
WriteLeadingAscii here, and highway is not in this BUILD.gn at all). The
warning class is already disarmed -- settings.py declares
treat_warnings_as_errors=false and no -Werror appears anywhere in the
log. Still, pass ninja -k 1000 so the next run reports every remaining
GCC-only failure at once instead of one per ten hours, and drop it once
the build is green.
The first run whose build_v8 job went green failed all three build_wheel
jobs at the same final link:

  /usr/bin/ld: cannot find -lboost_system: No such file or directory

-lv8_monolith and -lboost_python312 both resolved, so the V8 artifact and
the Boost.Python half are wired up correctly; boost_system is the one
library that no longer exists. Boost 1.89 removed the Boost.System stub
compiled library (header-only since 1.69), and this port builds against
1.90.0 because upstream's 1.87.0 predates CPython 3.14 -- so settings.py's
hardcoded "boost_system" entry has nothing to resolve against. Patch 0004
removes it; the extension references no Boost.System symbol, and
boostorg/system has carried no build/ or src/ since boost-1.89.0.

build_wheel had no patch step at all, so add the python-wheels checkout
and `git apply` that build_v8 already does. Patches 0001-0003 only affect
the V8 checkout/build, which --skip-build-v8 never reaches, so applying
the whole set there is a no-op beyond this fix.

Also restore the actions/cache around the V8 build that upstream's
linux.yml has and this port dropped, over exactly the paths the artifact
already collects. The ~23h monolith build is otherwise repeated in full
for every wheel-side iteration.
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.

1 participant