blog: Go static linking

With Go you get statically linked executables, right?

% go build 
% file unreadMail
unreadMail: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, not stripped

% GOARCH=arm go build
% file unreadMail
unreadMail: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped

% CGO_ENABLED=0 go build
% file unreadMail
unreadMail: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

The answer is a clear sometimes. Apparently the import of net causes the executable to be dynamically linked, since it uses CGO. Unless you disable CGO entirely. I would like an option to force go build to statically link or fail if not possible, please. Implicit behavioral changes are not my thing.

[Update 20170815:] You can still force Go to produce a statically linked executable by invoking an external linker and using a libc that fully supports static linkage, i.e. not GNU libc. My favorite so far is musl with its gcc wrapper:

CC=/usr/bin/musl-gcc go build -ldflags ' -linkmode=external -extldflags "-static"'

Not pretty, but better than dynamically linked executables...

Posted in rant
2017-08-14 22:36