Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/packages/runai-model-streamer-gcs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ versions:
gpl-sources:
filename: gpl-sources.tar
description: gcc
- version: 0.17.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
From 820707245ffc7f9f363fc5de3f5375daacb0a8b9 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Thu, 24 Sep 2026 03:32:40 +0000
Subject: [PATCH] toolchain: add riscv64 as a supported architecture

configure_toolchain() and its per-arch .bazelrc block are already fully
generic over the arch string (native.platform constraint is
@platforms//cpu:<arch>, gcc tools are resolved as
/usr/bin/<arch>-linux-gnu-<tool>) -- riscv64 was simply never added to
either list.

No -march flag is added for riscv64: aarch64's exists for crc32c's ARM64
CRC32C path inside google-cloud-cpp, and on riscv64 crc32c takes its
portable path instead (see the next-but-one patch), so a native riscv64
build uses the compiler's own default target.

Upstream-Status: To upstream [this port does not open issues/PRs against third-party repos; riscv64 toolchain support is exactly the kind of change upstream would want once a downstream build proves it works]
---
cpp/.bazelrc | 3 +++
cpp/toolchain/configure.bzl | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/cpp/.bazelrc b/cpp/.bazelrc
index 4dc8e85..1e7f877 100644
--- a/cpp/.bazelrc
+++ b/cpp/.bazelrc
@@ -47,5 +47,8 @@ test:tsan --run_under='setarch --addr-no-randomize'
# its RUNPATH, so the plugin is not found - a harness limit, not a property of the code under test.
test:tsan --test_tag_filters=-no_tsan

+build:riscv64 --platform_suffix=riscv64
+build:riscv64 --platforms=@toolchain//:riscv64
+
# Azurite testing support (enables AZURE_STORAGE_ACCOUNT_KEY for local testing)
build:azurite --define azurite_testing=true
diff --git a/cpp/toolchain/configure.bzl b/cpp/toolchain/configure.bzl
index 7e2e95e..b389879 100644
--- a/cpp/toolchain/configure.bzl
+++ b/cpp/toolchain/configure.bzl
@@ -7,7 +7,7 @@ load("//toolchain:rules.bzl", "get_target_triplet", "runai_crosstool_tools")

# This should map to the devcontainer Dockerfile
# We install gcc-x86-64-linux-gnu and gcc-aarch64-linux-gnu toolchains
-ARCHITECTURES = ["x86_64", "aarch64"]
+ARCHITECTURES = ["x86_64", "aarch64", "riscv64"]
OS = "linux-gnu"

def _get_gcc_version(repository_ctx, arch):
--
2.43.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
From 75c45793987328b8011252f0f24950e94456b336 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Thu, 24 Sep 2026 08:01:06 +0000
Subject: [PATCH] toolchain: use gcc's own -dumpmachine triplet for builtin
include dirs

configure_toolchain()'s cxx_builtin_include_directories are built from the
same os+arch naming-convention triplet (<arch>-linux-gnu) used to resolve
tool paths (/usr/bin/<arch>-linux-gnu-<tool>). That equivalence holds for a
genuine Debian cross-toolchain package (a real x86_64-linux-gnu-gcc reports
exactly that as its own -dumpmachine), but not when the tool path is a
same-arch *native* compiler reachable only via a symlink under the expected
name -- its own compiled-in builtin search path (/usr/lib/gcc/<real
triplet>/<ver>/include, etc.) still uses its real vendor triplet regardless
of what name it is invoked under.

This is exactly riscv64's manylinux_riscv64 image: gcc is Red Hat's native
riscv64-redhat-linux build, symlinked to /usr/bin/riscv64-linux-gnu-gcc so
runai_crosstool_tools() finds it. Bazel's own absolute-path sandboxing then
rejects gcc's builtin headers (e.g. stddef.h) because
/usr/lib/gcc/riscv64-redhat-linux/<ver>/include is not in the declared
riscv64-linux-gnu-based list.

Thread the compiler's actual -dumpmachine output down as gcc_machine and use
it (falling back to the naming-convention triplet when unset, so x86_64 and
aarch64 are unaffected) for cxx_builtin_include_directories specifically,
while tool_paths keeps using the naming-convention triplet the workflow's
symlinks provide.

Upstream-Status: To upstream [this port does not open issues/PRs against third-party repos; making cxx_builtin_include_directories match the compiler's own reported triplet is a general robustness fix upstream would likely want]
---
cpp/toolchain/configure.bzl | 7 ++++++-
cpp/toolchain/template/toolchain.bzl | 23 ++++++++++++++++++++---
2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/cpp/toolchain/configure.bzl b/cpp/toolchain/configure.bzl
index 9a04125..510ef90 100644
--- a/cpp/toolchain/configure.bzl
+++ b/cpp/toolchain/configure.bzl
@@ -11,6 +11,10 @@ def _get_gcc_version(repository_ctx, arch):
gcc_tool = runai_crosstool_tools(get_target_triplet(OS, arch))["gcc"]
return repository_ctx.execute([gcc_tool, "-dumpversion"]).stdout.strip()

+def _get_gcc_machine(repository_ctx, arch):
+ gcc_tool = runai_crosstool_tools(get_target_triplet(OS, arch))["gcc"]
+ return repository_ctx.execute([gcc_tool, "-dumpmachine"]).stdout.strip()
+
def _get_host_arch(repository_ctx):
return repository_ctx.execute(["/usr/bin/uname", "-m"]).stdout.strip()

@@ -18,9 +22,10 @@ def _cc_autoconf_toolchain_impl(repository_ctx):
define_statements = []
for arch in ARCHITECTURES:
gcc_version = _get_gcc_version(repository_ctx, arch)
+ gcc_machine = _get_gcc_machine(repository_ctx, arch)
host_arch = _get_host_arch(repository_ctx)
toolchain_name = arch
- define_statements.append('define_toolchain(name = "%s", os = "%s", host_arch = "%s", arch = "%s", gcc_version = "%s")' % (toolchain_name, OS, host_arch, arch, gcc_version))
+ define_statements.append('define_toolchain(name = "%s", os = "%s", host_arch = "%s", arch = "%s", gcc_version = "%s", gcc_machine = "%s")' % (toolchain_name, OS, host_arch, arch, gcc_version, gcc_machine))

repository_ctx.template(
"BUILD",
diff --git a/cpp/toolchain/template/toolchain.bzl b/cpp/toolchain/template/toolchain.bzl
index 6a4c6cf..36daffc 100644
--- a/cpp/toolchain/template/toolchain.bzl
+++ b/cpp/toolchain/template/toolchain.bzl
@@ -73,6 +73,15 @@ def _impl(ctx):
target_triplet = get_target_triplet(ctx.attr.os, ctx.attr.arch)
tool_paths = [tool_path(name = k, path = v) for k, v in runai_crosstool_tools(target_triplet).items()]

+ # gcc_machine is the triplet gcc itself reports (`gcc -dumpmachine`), which is
+ # what its own builtin include search path is actually built from. It is
+ # normally identical to target_triplet (a real x86_64-linux-gnu/aarch64-linux-gnu
+ # cross-gcc reports exactly that), but differs when the "gcc" behind
+ # target_triplet's tool path is a same-arch native compiler under a different
+ # vendor triplet (e.g. Red Hat's riscv64-redhat-linux) made reachable only by a
+ # symlink under the expected name.
+ include_triplet = ctx.attr.gcc_machine if ctx.attr.gcc_machine else target_triplet
+
# Documented at
# https://docs.bazel.build/versions/main/skylark/lib/cc_common.html#create_cc_toolchain_config_info.
#
@@ -89,7 +98,7 @@ def _impl(ctx):
abi_version = "unknown",
abi_libc_version = "unknown",
tool_paths = tool_paths,
- cxx_builtin_include_directories = _get_include_directories(target_triplet, ctx.attr.gcc_version, ctx.attr.use_cross),
+ cxx_builtin_include_directories = _get_include_directories(include_triplet, ctx.attr.gcc_version, ctx.attr.use_cross),
features = features
)

@@ -111,6 +120,11 @@ _toolchain_config = rule(
mandatory = True,
doc = "GCC major version to use (eg: 9)",
),
+ "gcc_machine": attr.string(
+ mandatory = False,
+ default = "",
+ doc = "The triplet `gcc -dumpmachine` reports, if it differs from os/arch's own naming convention",
+ ),
"use_cross": attr.bool(
mandatory = False,
default = False,
@@ -121,7 +135,7 @@ _toolchain_config = rule(
)


-def define_toolchain(name, os, host_arch, arch, gcc_version):
+def define_toolchain(name, os, host_arch, arch, gcc_version, gcc_machine = ""):
""""define_toolchain creates rules for a cc_toolchain.

This expects toolchain tools to exist at a canonical path.
@@ -134,6 +148,9 @@ def define_toolchain(name, os, host_arch, arch, gcc_version):
host_arch: The host architecture for this toolchain
arch: The target architecture for this toochain
gcc_version: The GCC version of this toolchain
+ gcc_machine: The triplet `gcc -dumpmachine` reports for this toolchain's
+ compiler, if it differs from the os/arch naming convention used for
+ the tool paths themselves
"""

native.platform(
@@ -145,7 +162,7 @@ def define_toolchain(name, os, host_arch, arch, gcc_version):
)

toolchain_config_name = "%s_toolchain_config" % name
- _toolchain_config(name = toolchain_config_name, os = os, arch = arch, gcc_version = gcc_version, use_cross = host_arch != arch)
+ _toolchain_config(name = toolchain_config_name, os = os, arch = arch, gcc_version = gcc_version, gcc_machine = gcc_machine, use_cross = host_arch != arch)

empty_target_name = "%s_empty" % name
empty_target_label = ":%s" % empty_target_name
--
2.43.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Mon, 28 Sep 2026 04:00:00 +0000
Subject: [PATCH] third_party: give google-cloud-cpp's crc32c config a
portable default

google-cloud-cpp 2.37.0's bazel/crc32c.BUILD generates crc32c_config.h
by first rewriting every `#cmakedefine01 X` to `#define X` and then
appending the value per substitution. HAVE_SSE42 and HAVE_ARM64_CRC32C
only get a value on @platforms//cpu:x86_64 and :arm64; on any other CPU
the "//conditions:default" branch is empty, so both end up as bare
`#define HAVE_SSE42`, and crc32c's own `#if HAVE_SSE42 && ...` /
`#if HAVE_ARM64_CRC32C` fail to preprocess ("operator '&&' has no left
operand", "#if with no expression"). google-cloud-cpp main still has
the empty default.

Patch the fetched google_cloud_cpp archive so the default branch sets
both to 0, i.e. crc32c's portable implementation. x86_64 and aarch64
builds are unaffected.

Upstream-Status: To upstream [this port does not open issues/PRs against third-party repos; the empty default is a google-cloud-cpp bug on every CPU other than x86_64/arm64, and runai-model-streamer can carry the patch until it is fixed there]
---
cpp/third_party/gcp_repo.bzl | 2 ++
cpp/third_party/google_cloud_cpp_crc32c_default.patch | 17 +++++++++++++++++
2 files changed, 19 insertions(+)

diff --git a/cpp/third_party/gcp_repo.bzl b/cpp/third_party/gcp_repo.bzl
index e91b830..17803dd 100644
--- a/cpp/third_party/gcp_repo.bzl
+++ b/cpp/third_party/gcp_repo.bzl
@@ -8,4 +8,6 @@ def load_gcp_repo():
sha256 = "10867580483cb338e7d50920c2383698f3572cc6b4c7d072e38d5f43755cbd80",
strip_prefix = "google-cloud-cpp-2.37.0",
url = "https://github.com/googleapis/google-cloud-cpp/archive/v2.37.0.tar.gz",
+ patches = [Label("//third_party:google_cloud_cpp_crc32c_default.patch")],
+ patch_args = ["-p1"],
)
diff --git a/cpp/third_party/google_cloud_cpp_crc32c_default.patch b/cpp/third_party/google_cloud_cpp_crc32c_default.patch
new file mode 100644
index 0000000..d357c31
--- /dev/null
+++ b/cpp/third_party/google_cloud_cpp_crc32c_default.patch
@@ -0,0 +1,17 @@
+diff --git a/bazel/crc32c.BUILD b/bazel/crc32c.BUILD
+index c8d8b3c..78b083f 100644
+--- a/bazel/crc32c.BUILD
++++ b/bazel/crc32c.BUILD
+@@ -115,7 +115,11 @@ configure_template(
+ " HAVE_SSE42": " HAVE_SSE42 0",
+ " HAVE_ARM64_CRC32C": " HAVE_ARM64_CRC32C 1",
+ },
+- "//conditions:default": {},
++ # Any other CPU (e.g. riscv64) uses crc32c's portable implementation.
++ "//conditions:default": {
++ " HAVE_SSE42": " HAVE_SSE42 0",
++ " HAVE_ARM64_CRC32C": " HAVE_ARM64_CRC32C 0",
++ },
+ }),
+ template = "src/crc32c_config.h.in",
+ )
--
2.43.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
Date: Mon, 28 Sep 2026 04:00:00 +0000
Subject: [PATCH] gcs: ship the licences of the statically linked dependencies

libstreamergcs.so statically links google-cloud-cpp and everything it
pulls in through bazel (abseil, protobuf, gRPC, BoringSSL, libcurl,
zlib, c-ares, re2, crc32c, nlohmann/json, ...), but the explicit
license_files=("LICENSE",) only ships the project's own licence. The
BSD/MIT/curl/OpenSSL licences and the Apache-2.0 NOTICE files require
their notices to travel with the binary. Also match LICENSE.* next to
setup.py, where the build stages each dependency's licence text.

Upstream-Status: To upstream [this port does not open issues/PRs against third-party repos; the upstream wheels have the same gap]
---
py/runai_model_streamer_gcs/setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/py/runai_model_streamer_gcs/setup.py b/py/runai_model_streamer_gcs/setup.py
index 1379a4f..03f2ff3 100644
--- a/py/runai_model_streamer_gcs/setup.py
+++ b/py/runai_model_streamer_gcs/setup.py
@@ -22,7 +22,7 @@ assert_lib_exists()
setup(
name="runai-model-streamer-gcs",
version=VERSION,
- license_files=("LICENSE",),
+ license_files=("LICENSE", "LICENSE.*"),
packages=find_packages(),
install_requires=["google-cloud-storage", "google-auth"],
data_files=[("/runai_model_streamer/libstreamer/lib/", [LIB])],
--
2.43.0

Loading