Summary
The chat_xdk_dotnet native ships for osx-arm64, osx-x64, linux-x64 and win-x64. There is no linux-arm64, so the JVM and .NET bindings cannot run on 64-bit ARM Linux — AWS Graviton, Ampere, and ARM CI runners.
The Python binding already ships manylinux_2_17_aarch64, so this Rust target is already built in this repo's CI. Only the dotnet-build matrix skips it.
Impact
On Linux/aarch64, NativeLoader.detectRid() returns null:
} else if (os.contains("linux")) {
if (x64) {
return "linux-x64";
}
}
extractBundledLibrary() then returns null, and load() falls through to the system lookup, which fails unless the operator supplies their own build. Because dotnet-build also feeds the java job, one missing matrix entry affects both bindings.
Verification
I built chat-xdk-dotnet for aarch64-unknown-linux-gnu from v0.5.0, with juicebox-sdk as a sibling checkout and the pinned 1.91.1 toolchain:
Finished `release` profile [optimized] target(s) in 1m 25s
libchat_xdk_dotnet.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked
Loaded through JNA on an ARM64 JVM (Temurin 25), with no jna.library.path set:
arch=aarch64
RESOURCE_PREFIX=linux-aarch64
LOADED OK: true
Unmodified source — same crate, same pinned toolchain, same sibling dependency. Only the target triple differs.
Suggested change
ubuntu-24.04-arm runners are already used by the Python job, so the runner and target are proven here.
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 97034d3..9a283e9 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -429,6 +429,10 @@ jobs:
rust_target: x86_64-unknown-linux-gnu
rid: linux-x64
lib: libchat_xdk_dotnet.so
+ - runs_on: ubuntu-24.04-arm
+ rust_target: aarch64-unknown-linux-gnu
+ rid: linux-arm64
+ lib: libchat_xdk_dotnet.so
- runs_on: windows-latest
rust_target: x86_64-pc-windows-msvc
rid: win-x64
@@ -489,7 +493,7 @@ jobs:
run: |
set -euo pipefail
base=crates/dotnet/dotnet/ChatXdk/runtimes
- for rid in osx-arm64 osx-x64 linux-x64 win-x64; do
+ for rid in osx-arm64 osx-x64 linux-x64 linux-arm64 win-x64; do
mkdir -p "$base/$rid/native"
cp artifacts/dotnet-native-$rid/* "$base/$rid/native/"
done
@@ -542,7 +546,7 @@ jobs:
run: |
set -euo pipefail
base=crates/jvm/java/chatxdk/src/main/resources/native
- for rid in osx-arm64 osx-x64 linux-x64 win-x64; do
+ for rid in osx-arm64 osx-x64 linux-x64 linux-arm64 win-x64; do
mkdir -p "$base/$rid"
cp artifacts/dotnet-native-"$rid"/* "$base/$rid/"
done
@@ -560,6 +564,7 @@ jobs:
native/osx-arm64/libchat_xdk_dotnet.dylib \
native/osx-x64/libchat_xdk_dotnet.dylib \
native/linux-x64/libchat_xdk_dotnet.so \
+ native/linux-arm64/libchat_xdk_dotnet.so \
native/win-x64/chat_xdk_dotnet.dll \
META-INF/LICENSE \
META-INF/THIRD_PARTY_NOTICES.md; do
diff --git a/crates/jvm/java/chatxdk/src/main/java/com/x/chatxdk/NativeLoader.java b/crates/jvm/java/chatxdk/src/main/java/com/x/chatxdk/NativeLoader.java
index 4bc6d3b..d5eed33 100644
--- a/crates/jvm/java/chatxdk/src/main/java/com/x/chatxdk/NativeLoader.java
+++ b/crates/jvm/java/chatxdk/src/main/java/com/x/chatxdk/NativeLoader.java
@@ -61,7 +61,7 @@ final class NativeLoader {
return out;
}
- /** RID labels aligned with the .NET / CI matrix: osx-arm64, osx-x64, linux-x64, win-x64. */
+ /** RID labels aligned with the .NET / CI matrix: osx-arm64, osx-x64, linux-x64, linux-arm64, win-x64. */
static String detectRid() {
String os = System.getProperty("os.name", "").toLowerCase(Locale.ROOT);
String arch = System.getProperty("os.arch", "").toLowerCase(Locale.ROOT);
@@ -76,6 +76,9 @@ final class NativeLoader {
return "osx-x64";
}
} else if (os.contains("linux")) {
+ if (arm) {
+ return "linux-arm64";
+ }
if (x64) {
return "linux-x64";
}
Happy to open this as a PR if that is easier for you.
Summary
The
chat_xdk_dotnetnative ships forosx-arm64,osx-x64,linux-x64andwin-x64. There is nolinux-arm64, so the JVM and .NET bindings cannot run on 64-bit ARM Linux — AWS Graviton, Ampere, and ARM CI runners.The Python binding already ships
manylinux_2_17_aarch64, so this Rust target is already built in this repo's CI. Only thedotnet-buildmatrix skips it.Impact
On Linux/aarch64,
NativeLoader.detectRid()returnsnull:extractBundledLibrary()then returns null, andload()falls through to the system lookup, which fails unless the operator supplies their own build. Becausedotnet-buildalso feeds thejavajob, one missing matrix entry affects both bindings.Verification
I built
chat-xdk-dotnetforaarch64-unknown-linux-gnufrom v0.5.0, withjuicebox-sdkas a sibling checkout and the pinned 1.91.1 toolchain:Loaded through JNA on an ARM64 JVM (Temurin 25), with no
jna.library.pathset:Unmodified source — same crate, same pinned toolchain, same sibling dependency. Only the target triple differs.
Suggested change
ubuntu-24.04-armrunners are already used by the Python job, so the runner and target are proven here.Happy to open this as a PR if that is easier for you.