Disabling CGO to Remove glibc Dependency
Published: 2023-09-22 21:55:36

CGO is a feature of the Go programming language that allows Go programs to call C functions and access C data structures. This can be useful for interfacing with existing C libraries. However, using CGO can also introduce glibc dependencies into your Go program.

glibc is the GNU C library, and it is the default C library on most Linux distributions. However, glibc versions can vary from one distribution to another. This can cause problems if you try to run a Go program that uses CGO on a different distribution than the one it was built on.  For example, a Go program built on Ubuntu 22.04 will not run on Ubuntu 20.04.

## Disabling CGO

To disable CGO, you can set the CGO_ENABLED environment variable to 0 before building your Go program. For example, to build a Go program with CGO disabled on Ubuntu, you would run the following command:

```shell
CGO_ENABLED=0 go build
```

### Removing the glibc Dependency

Once you have disabled CGO, your Go program will no longer depend on glibc. This means you can run your program on any Linux distribution, regardless of the glibc version.

#### Example

To illustrate the benefits of disabling CGO, let's consider the following example. We will build a simple Go program that prints the current date and time:

```go
package main

import (
    "fmt"
    "time"
)

func main() {
    fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}
```

If we build this program with CGO enabled, it will depend on glibc. To verify this, we can run the following command:

```shell
go build -o date
ldd date
```

##### Output

```shell
linux-vdso.so.1 (0x00007fff09417000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5d10a6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5d103d0000)
```

As you can see, the program depends on the libc.so.6 library. This means we can only run the program on a Linux distribution with the same glibc version as it was built on.

When you try to run this program with a different version of glibc, you will see a similar output as the following:

```shell
/lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by ./date)
/lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./date)
```

If we disable CGO before building the program, it will no longer depend on glibc. To verify this, we can run the following commands:

```shell
CGO_ENABLED=0 go build -o date
ldd date
```

##### Output

```shell
not a dynamic executable
```

As you can see, the program is no longer a dynamic executable. This means that it does not depend on any external libraries. This means we can run the program on any Linux distribution, regardless of the glibc version.

### Benefits of disabling CGO
There are several benefits to disabling CGO in Go:

- **Portability:** Disabling CGO makes Go programs more portable because they no longer depend on C libraries. This means that Go programs can be run on systems that do not have glibc installed, such as Alpine Linux and FreeBSD, or on different versions of the same operating system, like Ubuntu 20.04 and 22.04.
- **Security:** Disabling CGO can make Go programs more secure because it reduces the program's attack surface. C libraries can contain security vulnerabilities, and disabling CGO prevents these vulnerabilities from being exploited in Go programs. [See this vulnerability report of glibc in Debian 11 (Ubuntu 20.04).](https://security.snyk.io/package/linux/debian:11/glibc)
- **Performance:** In most cases, disabling CGO can improve the performance of Go programs. For an example, see CockroachDB's article on [The cost and complexity of Cgo](https://www.cockroachlabs.com/blog/the-cost-and-complexity-of-cgo/).

### Drawbacks of disabling CGO
There are also some drawbacks to disabling CGO in Go:

- **Functionality:** Disabling CGO may limit the functionality of Go programs. There are C libraries that do not have an equivalent Go module, therefore making it more challenging to integrate with such systems.
- **Performance:** Theoretically, disabling CGO can degrade the performance of Go programs. This is because Go will have to implement some functionality in pure Go, which may be less efficient than using a C library. However, this is theoretical because the overhead of invoking C libraries likely outweighs the implementation performance difference.

## Conclusion

Disabling CGO can be a helpful way to remove the glibc dependency from your Go program. This can make your program more portable and less likely to break when running on different Linux distributions. However, it is important to note that disabling CGO will prevent you from using any C libraries.