It could happen that some executable build in one version of Linux operating system cannot be executed on other Linux OS. Statically linking may resolve this problem. In dynamic linking Go executable linked to shared object libraries with extension so similar as executables built from C language sources. Mainly system shared libraries were written in C language. The interaction between C libraries and Go code are controlled by Go environmental variables which begin with CGO prefix. Here we will use and discuss CGO_ENABLED variable. Let us create small program with using “net” package and convert host name to IP:
package main import ( func main() { |
Build and execute it on Ubuntu 24.04:
$ go build lookup.go $ ./lookup ladydebug.com [67.43.229.163] |
The executable was build with dynamic linking and ldd command shows what Linux are required for its execution:
$ ldd lookup linux-vdso.so.1 (0x00007fff71174000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5d9b786000) /lib64/ld-linux-x86-64.so.2 (0x00007f5d9b9a1000) |
The command below shows values of Go environmental variables used during build process:
$ go version -m lookup lookup: go1.22.2 path command-line-arguments build -buildmode=exe build -compiler=gc build CGO_ENABLED=1 build CGO_CFLAGS= build CGO_CPPFLAGS= build CGO_CXXFLAGS= build CGO_LDFLAGS= build GOARCH=amd64 build GOOS=linux build GOAMD64=v1 |
Pay attention that value of CGO_ENABLED is 1.
Copy this executable on Ubuntu 18.04 machine and try to run:
# ./lookup ladydebug.com ./lookup: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34′ not found (required by ./lookup) ./lookup: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32′ not found (required by ./lookup) |
The executable does not work here, because of libc.so.6 version mismatch. Now return to ubuntu 24.04 and rebuild Go code with CGO_ENABLED=0:
$CGO_ENABLED=0 go build lookup.go $ ./lookup ladydebug.com [67.43.229.163] |
Let us check what ldd command shows now:
$ ldd lookup
not a dynamic executable
There are no dynamic linking components anymore.
Go environmental variables looks now like this:
$ go version -m lookup lookup: go1.22.2 path command-line-arguments build -buildmode=exe build -compiler=gc build CGO_ENABLED=0 build GOARCH=amd64 build GOOS=linux build GOAMD64=v1 |
# ./lookup ladydebug.com [67.43.229.163] |