CGO_ENABLED=1 I believe is the current default which means that it depends on GLIBC which can have breaking changes between updates & distributions.
CGO_ENABLED=0 is the workaround for creating static standalone binaries, so why isn't this the default?
The cgo tool is enabled by default for native builds on systems where it is expected to work. It is disabled by default when cross-compiling. You can control this by setting the CGO_ENABLED environment variable when running the go tool: set it to 1 to enable the use of cgo, and to 0 to disable it.
cgo is an amazing technology which allows Go programs to interoperate with C libraries. It's a tremendously useful feature without which Go would not be in the position it is today. cgo is key to ability to run Go programs on Android and iOS.
-installsuffix suffix. a suffix to use in the name of the package installation directory, in order to keep output separate from default builds. If using the -race flag, the install suffix is automatically set to race.
In general, CGO_ENABLED=1
leads to faster, smaller builds & runtimes - as it can dynamically load the host OS's native libraries (e.g. glibc
, DNS resolver etc.) - when running on the build OS. This is ideal for local rapid development. For deployment, CGO_ENABLED=1
may not be practical or even possible - when considering the deployment hosting OS.
If you're purely using the standard library, they you may not necessarily need CGO enabled. In certain standard libraries behavior will different if using a pure-Go version (CGO_ENABLED=0
) or a CGO-enabled version:
CGO_ENABLED=1
uses the native OS (e.g. on Linux nsswitch
) for ID lookupCGO_ENABLED=0
uses a basic Go implementation (e.g. reads from /etc/passwd
) - which does not include other ID registries the host may be aware ofDeployment
While a CGO_ENABLED=1
binary may be smaller in size, it relies on delivering a host OS too. Comparing Docker images:
ubuntu:20.04
is 73.9MB (glibc
: GNU-libc)alpine:3.12.1
is 5.57MB (musl
libc)so adding an OS (even a minimal one) adds this extra baggage. alpine
looks attractive in its minimal size - but its libc
may not be compatible with packages that rely on glibc
.
CGO_ENABLED=0
is, however, ideal for scratch docker image deployments - as no host OS needs to be bundled.
However, if your application imports a package with C-code (e.g. go-sqlite3) then your build must enable CGO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With