Search code examples
gobuildcompilation

Flags needed to create static binaries in golang


I was building a Docker image using scratch as base.

The following build command:

RUN go build -o /go/bin/myapp

created a binary that kept failing when executed:

standard_init_linux.go:211: exec user process caused "no such file or directory"

By trial and error I found out that I needed to build as follows:

RUN CGO_ENABLED=0 go build -o /go/bin/myapp -a -ldflags '-extldflags "-static"' . 

Why are both CGO_ENABLED=0 and -ldflags '-extldflags "-static"' necessary?

Don't both options create static binaries? (i.e. binaries that will need absolutely nothing in terms of libraries from the environments they will run on?)


Solution

  • Just before we start, a heads up by Russ Cox's: Comment

    Read this as well: Comment

    Yes, I agree with Volker's comment that some systems don't really allow static binaries.

    Read on: Compile packages and dependencies

    -a
        force rebuilding of packages that are already up-to-date.
    
    -ldflags '[pattern=]arg list'
        arguments to pass on each go tool link invocation.
    

    Read: go tool link

    -extldflags flags
        Set space-separated flags to pass to the external linker.
    

    Hence, it tries to rebuild all the packages (dependencies as well) with CGO disabled and also -static means do not link against shared libraries.

    Some of the points related to static linking are explained well: Linking golang statically