Repository navigation
Add linux-musl-x64 to the .NET binding's release matrix #21
Description
What
Please add x86_64-unknown-linux-musl / linux-musl-x64 to the dotnet-build matrix and to the RID staging loop in .github/workflows/release.yml, so that XDevPlatform.ChatXdk ships a runtimes/linux-musl-x64/native/libchat_xdk_dotnet.so alongside the four runtimes it already carries.
Why
XDevPlatform.ChatXdk 0.5.0 ships natives for linux-x64, osx-arm64, osx-x64 and win-x64. The Linux one is glibc linked: reading its ELF .dynamic and .gnu.version_r sections shows DT_NEEDED on libgcc_s.so.1, libm.so.6 (GLIBC_2.29), libc.so.6 (up to GLIBC_2.34) and ld-linux-x86-64.so.2, with the highest versioned symbols coming from the libpthread-into-libc merge: dlsym, pthread_create, pthread_join, pthread_detach, pthread_key_create, pthread_setspecific, pthread_setname_np and the pthread_attr_* family, all at GLIBC_2.34.
That means the package cannot be used on an Alpine or other musl based .NET image, which is a common deployment base for .NET 8 services. The failure is also over-determined rather than merely awkward: on a musl host the .NET RID is linux-musl-x64, linux-x64 is not in its fallback chain, so the shipped asset is never even selected, and a glibc compatibility shim cannot satisfy versioned relocations from the GLIBC_2.34 set anyway.
Why this should be small
The same core already builds for musl in this repository, for the Go binding, in this workflow, on the same runner. From the Makefile:
prebuilt-linux-amd64-musl:
cargo zigbuild -p chat-xdk-go --release --target x86_64-unknown-linux-musl
and from .github/workflows/release.yml, the Go job on a plain Ubuntu runner:
rustup target add x86_64-unknown-linux-gnu x86_64-unknown-linux-musl
sudo apt-get update && sudo apt-get install -y build-essential musl-tools
cargo build -p chat-xdk-go --release --target x86_64-unknown-linux-gnu
cargo build -p chat-xdk-go --release --target x86_64-unknown-linux-musl
The resulting musl artifact is committed at go/chatxdk/libs/linux_amd64_musl/. crates/dotnet/Cargo.toml declares crate-type = ["cdylib", "staticlib"], and crates/core/Cargo.toml describes its dependencies as "Cryptography - Pure Rust, WASM-compatible", so nothing in the crypto is platform locked. The .NET crate is the same cargo build command with a different -p.
The only reason the NuGet package has no musl runtime appears to be that the dotnet-build matrix lists four entries and musl is not one of them, and the packing step hardcodes the RID list.
The change
One matrix entry:
- runs_on: ubuntu-latest
rust_target: x86_64-unknown-linux-musl
rid: linux-musl-x64
lib: libchat_xdk_dotnet.so
linux-musl-x64 added to the RID staging loop, so it reads:
for rid in osx-arm64 osx-x64 linux-x64 linux-musl-x64 win-x64; do
and, on that matrix leg only, the same two lines the Go job already runs:
rustup target add x86_64-unknown-linux-musl
sudo apt-get update && sudo apt-get install -y build-essential musl-tools
Two build details we hit and would expect the workflow to need. The release build checks out juicebox-systems/juicebox-sdk at ref 0.3.4 as a sibling path dependency, so that step applies to this leg too. And Rust's musl target defaults to a static CRT, which for a cdylib normally needs -C target-feature=-crt-static.
What it changes for consumers
Nothing, for anyone already using the package. The managed ChatXdk.dll binds the native by plain name with a single DllImport and installs no SetDllImportResolver and no NativeLibrary call, so resolution is the ordinary CLR runtimes probe. A musl asset in runtimes/linux-musl-x64/native/ is picked up by the existing unmodified managed assembly on a musl host, and is ignored everywhere else.
Happy to open this as a pull request with the workflow change if that is easier to review than an issue.
Activity