Skip to content

fix: link ICU dynamically on Alpine (musl static ICU is non-PIC) - #36

Merged
arv merged 1 commit into
mainfrom
arv/alpine-dynamic-icu
Jun 3, 2026
Merged

fix: link ICU dynamically on Alpine (musl static ICU is non-PIC)#36
arv merged 1 commit into
mainfrom
arv/alpine-dynamic-icu

Conversation

@arv

@arv arv commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Problem

The Alpine prebuild fails to link with:

/usr/lib/libicuuc.a(putil.ao): relocation R_X86_64_PC32 against symbol `tzname'
can not be used when making a shared object; recompile with -fPIC

Alpine's icu-static is not built with -fPIC, so it can't be linked into the .node shared object — the same wall glibc hit. (Correcting an earlier wrong assumption that musl static archives are PIC.)

Static ICU only works on macOS. Both glibc and musl ship non-PIC static archives.

Fix

Link ICU dynamically on all Linux (glibc + Alpine); keep static on macOS.

  • deps/icu.js: useStatic = isMac only (drop the Alpine static branch).
  • build.yml: drop icu-static from the alpine prebuild apk installs — icu-dev provides the headers and the .so we now link against.

Verified macOS still static-links and stays self-contained (otool -L shows no ICU).

⚠️ Runtime requirement (action needed in the image repo)

The Alpine .node now has a NEEDED libicu*.so.<ver>, so the zero-cache Alpine runtime image must install ICU:

RUN apk add --no-cache icu-libs

Without it, loading @rocicorp/zero-sqlite3 will fail at runtime on Alpine. (Couples to the ICU soname/major in the build image — currently Alpine icu 76.)

Note on the in-flight v1.1.0 release

v1.1.0 was cut before this fix, so its Alpine prebuild failed and npm publish never ran (npm is still on 1.0.18). This fix needs to be on main and in a new tag (e.g. re-cut after merge) for the release to complete cleanly.

🤖 Generated with Claude Code

Alpine's icu-static (libicuuc.a) is NOT built with -fPIC, so it can't link
into the .node shared object — the alpine prebuild failed with the same
"recompile with -fPIC" error as glibc. Correcting my earlier assumption that
musl static archives are PIC.

Static ICU is therefore only viable on macOS (Homebrew). Link ICU dynamically
on ALL Linux (glibc + Alpine); the runtime image must provide ICU
(`apk add icu-libs` in the zero-cache Alpine image).

- icu.js: useStatic = isMac only; drop the Alpine static branch.
- build.yml: drop `icu-static` from the alpine prebuild apk installs (icu-dev
  provides the headers and the .so we now link against).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@arv
arv force-pushed the arv/alpine-dynamic-icu branch from b6b198f to a42b828 Compare June 3, 2026 08:05
@arv
arv merged commit 1c54c9e into main Jun 3, 2026
37 checks passed
@arv
arv deleted the arv/alpine-dynamic-icu branch June 3, 2026 08:12
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