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.

flags.nim · 78 lines · 3.0 KBNim Blame HistoryRaw
muslkit: musl static libraries from Alpine, without Alpine 5feb050 nandi 21h ago1## Turning a sysroot into compiler flags.
2##
3## Nim's OpenSSL binding is the one place a static build needs more than paths:
4## `-d:ssl` makes Nim dlopen libssl at runtime, which a static binary cannot do,
5## and OpenSSL 3 dropped a symbol Nim still references. Both fixes are emitted
6## here rather than left as folklore in someone's shell history.
7
8import std/[os, strutils]
9import ./sysroot
10
11type Toolchain* = enum
12 tcNim = "nim", tcCc = "cc", tcPkgConfig = "pkg-config"
13
14proc includeDir*(root: string): string = root / "usr" / "include"
15proc libDir*(root: string): string = root / "usr" / "lib"
16
17proc hasLib(root, name: string): bool =
18 fileExists(libDir(root) / ("lib" & name & ".a"))
19
20proc nimFlags*(root: string, libs: openArray[string] = [],
21 opensslCompat = true): seq[string] =
22 result = @["--passC:-I" & includeDir(root),
23 "--passL:-L" & libDir(root),
24 "--passL:-static"]
25 if hasLib(root, "ssl") and hasLib(root, "crypto"):
26 # Stop Nim dlopen'ing OpenSSL, and link the archives instead.
27 result.add "--dynlibOverride:ssl"
28 result.add "--dynlibOverride:crypto"
29 result.add "--passL:" & libDir(root) / "libssl.a"
30 result.add "--passL:" & libDir(root) / "libcrypto.a"
31 if opensslCompat:
32 # Removed in OpenSSL 3.0; Nim's wrapper still names it.
33 result.add "--passC:-DSSL_get_peer_certificate=SSL_get1_peer_certificate"
34 for lib in libs:
35 result.add "--passL:-l" & lib
36
37proc ccFlags*(root: string, libs: openArray[string] = []): seq[string] =
38 result = @["-I" & includeDir(root), "-L" & libDir(root), "-static"]
39 for lib in libs:
40 result.add "-l" & lib
41
42proc pkgConfigEnv*(root: string): seq[string] =
43 @["PKG_CONFIG_SYSROOT_DIR=" & root,
44 "PKG_CONFIG_LIBDIR=" & libDir(root) / "pkgconfig"]
45
46proc nimCfg*(root, cc: string, libs: openArray[string] = []): string =
47 ## A nim.cfg fragment: cross-compiler plus every flag from `nimFlags`.
48 result = "# Generated by muslkit — static musl build against " & root &
49 "\n# Regenerate with: muslkit nimcfg --root " & root & "\n"
50 if cc.len > 0:
51 result.add "--cc:clang\n"
52 result.add "--clang.exe:\"" & cc & "\"\n"
53 result.add "--clang.linkerexe:\"" & cc & "\"\n"
54 for f in nimFlags(root, libs):
55 result.add f & "\n"
56
57const zigccTemplate* = """#!/bin/sh
58# Generated by muslkit: zig as a musl cross-compiler.
59exec zig cc -target @TARGET@ "$@"
60"""
61
62proc zigccScript*(target: string): string =
63 zigccTemplate.replace("@TARGET@", target)
64
65proc writeZigCc*(path, target: string) =
66 writeFile(path, zigccScript(target))
67 setFilePermissions(path, {fpUserRead, fpUserWrite, fpUserExec,
68 fpGroupRead, fpGroupExec,
69 fpOthersRead, fpOthersExec})
70
71proc describe*(root: string): string =
72 let libs = staticLibs(root)
73 if libs.len == 0:
74 return "no static libraries in " & root
75 result = $libs.len & " static libraries in " & libDir(root) & ":\n"
76 for l in libs:
77 result.add " " & l.extractFilename & " (" &
78 $(getFileSize(l) div 1024) & " KiB)\n"