Home > Net >  golang build fails because of gcc being required
golang build fails because of gcc being required

Time:10-29

I am building the following ridiculously simple go program

package main

import (
    "context"
    "flag"
    "fmt"
    "log"

    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    _ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/homedir"
)

const namespace = "default"

func main() {
    home := homedir.HomeDir()
    defaultKubeConfigPath := fmt.Sprintf("%s/%s", home, ".kube/config")
    kubeconfig := flag.String("kubeconfig", defaultKubeConfigPath, "location to kubeconfig file")
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    if err != nil {
        panic(err)
    }
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        log.Fatal(err)
    }
    pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{})
    if err != nil {
        panic(err)
    }
    for i := range pods.Items {
        fmt.Printf("%s\n", pods.Items[i].Name)
    }

    deployments, err := clientset.AppsV1().Deployments(namespace).List(context.TODO(), metav1.ListOptions{})
    if err != nil {
        panic(err)
    }
    for i := range deployments.Items {
        fmt.Printf("%s\n", deployments.Items[i].Name)
    }
}

using the following Dockerfile

FROM golang:1.19.2-alpine3.15 as builder

COPY src /src

WORKDIR /src

RUN go build -race -ldflags "-s -w" -a -o client-go

FROM scratch

COPY --from=builder client-go /client-go

ENTRYPOINT [ "./client-go" ]

The build fails as folows:

#8 21.92 # runtime/cgo
#8 21.92 cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in $PATH

Where exactly is gcc needed since I am not using any cgo extensions?

Is there an a priori way of identifying when gcc for cgo is needed?

CodePudding user response:

You need to set CGO_ENABLED=0 and not enable the race detector.


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. The go tool will set the build constraint "cgo" if cgo is enabled. The special import "C" implies the "cgo" build constraint, as though the file also said "// build cgo". Therefore, if cgo is disabled, files that import "C" will not be built by the go tool.

https://pkg.go.dev/cmd/cgo

See also Why is CGO_ENABLED=1 default?

With CGO_ENABLED=0 and the race flag set, you'll get an error:

#8 0.857 go: -race requires cgo; enable cgo by setting CGO_ENABLED=1

So to get this to compile without gcc you'll want to use:

RUN CGO_ENABLED=0 go build -ldflags "-s -w" -a -o client-go
  • Related