[HN Gopher] Building Statically Linked Go Executables with CGO a...
___________________________________________________________________
Building Statically Linked Go Executables with CGO and Zig
Author : todsacerdoti
Score : 91 points
Date : 2025-03-28 14:11 UTC (8 hours ago)
(HTM) web link (calabro.io)
(TXT) w3m dump (calabro.io)
| HenriTEL wrote:
| All the magic seems to happen in const lib =
| b.addLibrary(.{ .linkage = .static, .name
| = "cgo_static_linking", .root_module = lib_mod,
| });
|
| and
|
| /* #cgo LDFLAGS: -L./zig-out/lib -lcgo_static_linking -static
| #include "zig_lib.h" */
|
| Now I can only guess why it works. A bit of an explanation
| wouldn't hurt. Good post btw
| nasretdinov wrote:
| Most of the magic is due to two things: 1. Zig comes with clang
| and musl (C library) for lots of architectures, so can be used
| for cross-compiling, even for non-Zig projects since clang can
| build C/C++ no problem 2. Musl is designed to be compatible
| with static linking (glibc is not), so it's the natural choice
| here too
| MawKKe wrote:
| Zig builds a statically linked library called
| "cgo_static_linking" from Zig sources. Zig places the artifact
| into "./zig-out/lib/cgo_static_linking.a" (or maybe some other
| extension). The library is exported with C ABI, which Go (cgo)
| compiler supports.
|
| The #cgo line tells the Go compiler to add custom compilation
| flags: -l flag tells the compiler that you wish to link to a
| library called "cgo_static_linking" in to the binary. However,
| the cgo compiler can't find it since it is not in the default
| search paths for libraries. The -L option extends the library
| search path to "./zig-out/lib/", allowing "cgo_static_linking"
| to be found.
|
| The "#include" line inserts the header file contents as-is into
| the source file (main.go), bringing the definition of the
| function available to the compiler. The compiler is then able
| to compile the Go source, and later link it with the other
| build artifacts to produce the final executable.
|
| The key here is the "C ABI" which acts as common ground for
| both languages. The rest is just scaffolding to let the
| compilers find and connect appropriate files together.
| bat_sy wrote:
| Hi HN, I tried doing this 2 days ago for AWS lambda arm64
| runners. And it did not work. Has anyone successfully built a
| statically linked golang binary arm64 runners in Lambda?
|
| Thanks in advance.
| Laremere wrote:
| This post seems to be missing an additional opportunity: Zig's
| build can involve go build! Use Build.addSystemCommand, have it
| depend on library step, and have the install step depend on that
| step. This reduces the steps to build to just 'zig build'
| jcalabro wrote:
| zigception!
| silisili wrote:
| Do you by chance have a link to a working example of this?
| Sounds interesting...
| karel-3d wrote:
| what is the upside for this rather than just building cgo with
| musl? what does zig add?
| nasretdinov wrote:
| Zig allows you to cross-compile as easily as Go does. Setting
| up cross-compilation toolchain otherwise is quite painful
| karel-3d wrote:
| ah okay.
|
| I was building with cgo+musl before and it was not complex at
| all, but yeah I didn't think about cross-compiling.
| bradfitz wrote:
| We tried this a few years back with a very loaded Go server using
| SQLite (actual C SQLite, not modernc.org/sqlite) and something
| made performance tank... likely some difference between glibc and
| musl. We never had time to hunt it down. We talked to Zig folk
| about sponsoring them to work on it, making performance
| comparable to glibc-built-SQLite, but they were busy at the time.
| raggi wrote:
| it was the intrinsics, sometime ago zig "imported" compiler-rt
| and wrote pure-zig variants that are lacking machine level
| optimizations and a lot of vectorization and so on. SQLite
| performance is highly dependent on them.
___________________________________________________________________
(page generated 2025-03-28 23:00 UTC)