nandi/nimstaticpublic Fork 0
5feb05094be9eb20a8a0588b44117d22c7dc3cac
Commits
Clone
git clone https://git.rickub.com/nandi/nimstatic.git
git clone ssh://git@rickub.com/nandi/nimstatic.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

README.md · 120 lines · 4.5 KBmarkdown Blame HistoryRaw
muslkit: musl static libraries from Alpine, without Alpine 5feb050 nandi 15h ago1# muslkit
2
3musl-linked static libraries from Alpine, without Alpine.
4
5Alpine builds everything against musl and ships `*-static` packages for most of
6it. An `.apk` is just a tarball, and an `APKINDEX` is just a text file — so you
7don't need apk, a chroot, a container or a distro to get `libcrypto.a` built
8for musl. muslkit fetches the index, resolves a dependency closure, downloads
9the packages and unpacks them into a sysroot directory you own.
10
11Nothing is installed system-wide. Nothing needs root.
12
13```bash
14muslkit add openssl-libs-static
15nim c -d:ssl $(muslkit nimflags) --cc:clang --clang.exe:./zigcc app.nim
16```
17
18## Why
19
20Getting a fully static Nim (or C, or Zig) binary with TLS on a glibc distro
21means finding musl-built archives, and the usual answers are "install Alpine",
22"run Docker" or "use Nix". Alpine's mirrors already serve exactly the files —
23this just takes them.
24
25## Usage
26
27```
28muslkit add <pkg>... Download packages and unpack into the sysroot
29muslkit list Show what the sysroot holds
30muslkit libs Show the static libraries in the sysroot
31muslkit search <text> Search the index (names and descriptions)
32muslkit show <pkg> Index record for one package
33muslkit nimflags [-l lib] Print nim flags for a static build
34muslkit ccflags [-l lib] Print cc/clang flags
35muslkit nimcfg [-o file] Write a nim.cfg fragment
36muslkit zigcc [-o file] Write a `zig cc -target …-musl` wrapper script
37muslkit env Shell exports (PKG_CONFIG_*, MUSLKIT_ROOT)
38muslkit path Print the sysroot path
39muslkit clean Remove the sysroot (cache is kept)
40```
41
42Options: `-r/--root`, `-b/--branch` (default `v3.21`, `edge` for rolling),
43`-a/--arch`, `-m/--mirror`, `--repo main,community`, `-l/--lib`, `--cc`,
44`--no-deps`, `--refresh`, `-q/--quiet`.
45
46The sysroot defaults to `$XDG_DATA_HOME/muslkit/sysroot` and honors
47`MUSLKIT_ROOT`. Downloads are cached under `$XDG_CACHE_HOME/muslkit`, so a
48second `add` is offline and the index is re-fetched only once a day.
49
50## A full static build, start to finish
51
52```bash
53muslkit add openssl-libs-static zlib-static
54muslkit zigcc # writes ./zigcc (needs zig on PATH)
55nim c -d:release -d:ssl \
56 --cc:clang --clang.exe:./zigcc --clang.linkerexe:./zigcc \
57 $(muslkit nimflags) --passL:-s \
58 -o:app src/app.nim
59```
60
61`muslkit nimflags` emits more than include and library paths, because two
62things bite every static Nim build with TLS:
63
64- **`-d:ssl` makes Nim `dlopen` libssl at runtime.** A static binary cannot,
65 and dies at startup with `could not load: libcrypto.so(...)` — even on code
66 paths that never touch the network. The fix is `--dynlibOverride:ssl
67 --dynlibOverride:crypto` plus the archives on the link line.
68- **OpenSSL 3 removed `SSL_get_peer_certificate`,** which Nim's wrapper still
69 references, so the link fails on one undefined symbol. The fix is
70 `-DSSL_get_peer_certificate=SSL_get1_peer_certificate`.
71
72Both are emitted automatically when `libssl.a` and `libcrypto.a` are present in
73the sysroot. A static binary carries no CA trust store, so set `SSL_CERT_FILE`
74to a bundle on the host that runs it.
75
76Cross-compiling is the same command with `--arch`; `muslkit add -a aarch64
77openssl-libs-static` and `muslkit zigcc -a aarch64` line up.
78
79## Trust
80
81Packages come over HTTPS from the mirror and are unpacked as-is. muslkit checks
82the size recorded in the index but does **not** verify Alpine's RSA signatures —
83apk's checksum field covers the package's control segment, not the file, so a
84real check means implementing apk's signature format. Treat a sysroot as build
85input, not as a trust root. If that matters for your use, pin a mirror you run.
86
87## Install
88
89```bash
90nimble install
91```
92
93or build in place with `nim c -d:ssl -o:muslkit src/muslkit.nim`. Requires
94`tar` on PATH (an `.apk` is concatenated gzip streams, which GNU tar reads) and,
95for the `zigcc` helper, `zig`.
96
97## Library
98
99```nim
100import muslkit
101
102let remote = initRemote(branch = "edge")
103let idx = remote.fetchIndex()
104for pkg in idx.resolve(["openssl-libs-static"]):
105 echo pkg.name, " ", pkg.version, " ", remote.fetchPackage(pkg)
106```
107
108Modules: `muslkit/index` (APKINDEX parsing, provides and dependency
109resolution), `muslkit/repo` (mirror, cache, download, unpack),
110`muslkit/sysroot` (manifest, static-lib discovery), `muslkit/flags` (nim/cc/
111pkg-config flag emission).
112
113## Tests
114
115```bash
116nimble test
117```
118
119The suite is offline — index parsing, resolution through `so:`/`pkg:` provides,
120manifest round-trips and flag emission all run against fixtures.