Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is CGO_ENABLED=1 default?

Tags:

go

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?

like image 437
hendry Avatar asked Oct 26 '20 04:10

hendry


People also ask

Is CGO enabled by default in Golang?

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.

What is Cgoenabled?

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.

What is Installsuffix?

-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.


Video Answer


1 Answers

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:

  • net: see DNS Name Resolution
  • os/users:
    • CGO_ENABLED=1 uses the native OS (e.g. on Linux nsswitch) for ID lookup
    • CGO_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 of

Deployment

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.

like image 140
colm.anseo Avatar answered Sep 19 '22 19:09

colm.anseo