Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does CGO_ENABLED affect dynamic vs static linking?

We are compiling our Go code to be run on docker and we were investigating why our binary was not executing. We found that it was missing some dynamic libraries (although we want statically linked binaries).

This is how it was compiled.

env GOOS=linux CGO_ENABLED=1 GO111MODULE=on GOPRIVATE=github.com/ourrepo GOPROXY=https://proxy.golang.org go build --installsuffix cgo --ldflags='-extldflags=-static' -o program main.go

Using the same build command with CGO_ENABLED=0 ended up fixing the issue, and the output binary was statically linked.

Now the weird part is we have another program that is using the same build command, this time with CGO_ENABLED=1 and... it is statically linked!

So I'm very confused why in some cases CGO_ENABLED=1 produces dynamic linking, and sometimes static linking. Happy to provide more details.

like image 954
Thomas Avatar asked Jul 09 '20 14:07

Thomas


1 Answers

Some Go packages use CGO under the hood, leveraging (very) common C libraries for broader compatibility across environments and edge cases encountered at runtime.

These common libraries are found on most major OS distributions - but obviously are not included in the Scratch image (which is by nature completely empty).

CGO_ENABLED is set to 1 by default, which means that it must be explicitly disabled with CGO_ENABLED=0 to avoid it, even when using the -static flag.

like image 161
Opnauticus Avatar answered Oct 16 '22 23:10

Opnauticus