how to create a statically linked golang executable with go 1.5+
Asked Answered
B

3

10

golang version < 1.5 - there are plenty of static linking examples, posts and recipes. What about >= 1.5? (google search has returned no useful results for my search terms.) Anyone have any recommendations on how to produce a statically linked binary that can be executed inside a basic rkt (from CoreOS) container?

my go:

$go version
go version go1.5 linux/amd64

when I try to run my container:

sudo rkt --insecure-skip-verify run /tmp/FastBonusReport.aci

I get:

[38049.477658] FastBonusReport[4]: Error: Unable to open "/lib64/ld-linux-x86-64.so.2": No such file or directory

suggesting that the executable in the container is depending on this lib and hence not static.

my manifest looks like:

cat <<EOF > /tmp/${myapp}/manifest
{
    "acKind": "ImageManifest",
    "acVersion": "0.9.0",
    "name": "${lowermyapp}",
    "labels": [
        {"name": "os", "value": "linux"},
        {"name": "arch", "value": "amd64"}
    ],
    "app": {
        "exec": [
            "/bin/${myapp}"
        ],
        "user": "0",
        "group": "0"
    }
}
EOF

my command line to build the binary looks like:

go build ${myapp}.go

This article has a few examples golang < 1.5. And then there is this getting started article on the CoreOS site.

Byars answered 13/10, 2015 at 21:45 Comment(7)
Can you show us how you're building your app? The process hasn't really changed.Calyptrogen
and I added some links to articles.Byars
have you set CGO_ENABLED=0?Calyptrogen
Not required but could you possibly provide some context and/or links to information about rkt? Yours is the first use of the tag and I at least am not familiar with it.Meteorite
JimB's comment seems right. 1.5 doesn't dynamically link Go code by default, so your problem is probably with Go linking to the system's C library for DNS reoslution, which was also what older versions did. CGO_ENABLED=0 turns that off.Plunk
@evanmcdonnal: rkt: github.com/coreos/rktMarinmarina
While I still like to create static binaries from my go projects I have also started using rkt-builder to build my projects inside a rkt container. This has a number of cool side effects.Byars
B
11

I hate to answer my own question. The comments have been correct CGO_ENABLED=0 go build ./... seems to have have done the trick.

While it was not part of the original question, once the program started executing in the rkt container it could not perform a proper DNS request. So there must be something else going on too.

Byars answered 14/10, 2015 at 1:6 Comment(3)
Is this running on Mac OS X (darwin)? I thought this was the only platform where DNS lookups are not done by Go itself.Lodged
@Volker: dns lookups are done in go when nsswitch.conf permits, but the cgo resolver is still linked so it can be used when needed (there's also a ` GODEBUG=netdns=` option for switching back and forth at runtime, which needs both available)Calyptrogen
@Byars you have to add your own /etc/hosts to your container, like they do here, in the etcd project.Smallpox
P
10

Static linking:

Go 1.5:

go build -ldflags "-extldflags -static" ...

With Go 1.6 I had to use:

go build -ldflags "-linkmode external -extldflags -static" ...
Pennon answered 11/8, 2016 at 15:16 Comment(0)
M
2

try to build static link version :

go build -ldflags '-extldflags "-static"' -tags netgo,osusergo .

use -tags osusergo,netgo to force static build without glibc dependency library.

Millard answered 20/7, 2022 at 6:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.