Go program isn't compiled to static binary if uses "net" package

3,817 views
Skip to first unread message

ziutek

unread,
Dec 7, 2011, 11:42:24 AM12/7/11
to golang-nuts
It seems that using of "net" package causes dynamic linking in Linux.

package main
import "net"
func main() {
net.Dial("tcp", "127.0.0.1")
}

$ 8g net_so.go && 8l net_so.8
$ ldd 8.out
linux-gate.so.1 => (0xb7821000)
libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb76ab000)
libpthread.so.0 => /lib/i386-linux-gnu/i686/cmov/libpthread.so.0
(0xb7692000)
/lib/ld-linux.so.2 (0xb7822000)

Static binary can be obtain using Go release.r56:

package main
import "net"
func main() {
net.Dial("tcp", "", "127.0.0.1")
}

$ 8g net_so.go && 8l net_so.8
$ ldd 8.out
statically linked

An important reason for which I've started using Go was static
linking. Static linking is still important for one of my network
applications. Is there any chance to see static linking back in the
future releases of Go?

John Asmuth

unread,
Dec 7, 2011, 11:51:15 AM12/7/11
to golan...@googlegroups.com
There is a way to build the net package such that you get static linking.

I haven't done it, but taking a look at the package's makefile, it looks like if you set the env var CGO_ENABLED=0 it will be statically linked.

Brad Fitzpatrick

unread,
Dec 7, 2011, 11:53:26 AM12/7/11
to ziutek, golang-nuts
Modify src/pkg/net/Makefile and set CGO_ENABLED=0.  Then rebuild Go, and the net package won't use cgo and you'll have static linking again.

Matt Kane's Brain

unread,
Dec 7, 2011, 11:54:35 AM12/7/11
to golan...@googlegroups.com
I think this message from Russ last year is relevant, at least to
understand why this is done:
http://groups.google.com/group/golang-nuts/browse_thread/thread/1765f7f1ce0970ab/61f7240805e59f4d?lnk=gst&q=dns#61f7240805e59f4d

--
matt kane's brain
http://hydrogenproject.com

ziutek

unread,
Dec 7, 2011, 12:24:20 PM12/7/11
to golang-nuts
On 7 Gru, 17:53, Brad Fitzpatrick <bradf...@golang.org> wrote:
> Modify src/pkg/net/Makefile and set CGO_ENABLED=0.  Then rebuild Go, and
> the net package won't use cgo and you'll have static linking again.

I compile Go weekly.2011-12-06 this way:

$ export CGO_ENABLED=0
$ ./all.bash

and now ldd 8.out says:

/usr/bin/ldd: line 161: /lib64/ld-linux-x86-64.so.2: cannot execute
binary file
not a dynamic executable

Thanks!

But now I wonder why ldd doesn't simply say "statically linked"?

Ian Lance Taylor

unread,
Dec 7, 2011, 1:33:28 PM12/7/11
to ziutek, golang-nuts
ziutek <ziu...@Lnet.pl> writes:

> and now ldd 8.out says:
>
> /usr/bin/ldd: line 161: /lib64/ld-linux-x86-64.so.2: cannot execute
> binary file
> not a dynamic executable
>
> Thanks!
>
> But now I wonder why ldd doesn't simply say "statically linked"?

ldd is just a shell script on GNU/Linux systems, take a look.

Ian

ron minnich

unread,
Dec 7, 2011, 2:40:04 PM12/7/11
to golang-nuts
or if you think (like me) that the shell script is not pretty, there
is a go implementation of ldd that is 1/2 the size of the shell
script:

https://bitbucket.org/rminnich/ldd/overview

Code corrections welcome. I'm still learning.

ron

Vesa Kaihlavirta

unread,
Dec 11, 2011, 6:42:04 AM12/11/11
to ziutek, golang-nuts
On Wed, Dec 7, 2011 at 7:24 PM, ziutek <ziu...@lnet.pl> wrote:
> On 7 Gru, 17:53, Brad Fitzpatrick <bradf...@golang.org> wrote:
>> Modify src/pkg/net/Makefile and set CGO_ENABLED=0.  Then rebuild Go, and
>> the net package won't use cgo and you'll have static linking again.
>
> I compile Go weekly.2011-12-06 this way:
>
>  $ export CGO_ENABLED=0
>  $ ./all.bash
>

Note that this seems to break CGO for everything for the Go you built.
See for instance https://bugs.archlinux.org/task/26884

Can somebody at least semi-officially say if this is a good idea to do
in general, and is there a way to get the net package to not cause the
plague of dynamic linking on Linux without breaking anything else?

--vk

ziutek

unread,
Dec 13, 2011, 4:37:02 AM12/13/11
to golang-nuts
> Note that this seems to break CGO for everything for the Go you built.
>  See for instancehttps://bugs.archlinux.org/task/26884

Yes. I obtain "cgocall unavailable" if I try compile some CGO code. I
don't like CGO, so I try not to use it at all but sometimes it is the
only tool to solve some problem.

Use "export CGO_ENABLED=0" is probably too orthodox in ordinary
applications but it seems to be useful if you don't want to have any
dynamic linking in GO package tree. I hope that this behavior will be
preserved in the future because it is very useful for embedded
applications.

Alexandre Fiori

unread,
Jul 18, 2013, 1:15:14 AM7/18/13
to golan...@googlegroups.com

Just wanted to share that I came across this recently and things changed a bit...
Not only Go has to be compiled with CGO_ENABLED=0, but also Go programs later.

To compile Go itself:
export CGO_ENABLED=0
./all.bash

And then Go programs:
$ cat foo.go 
package main

import "net"

func main() {
net.Dial("tcp", "")
}

$ go build foo.go
$ ls -l foo; ldd foo
-rwxr-xr-x 1 af af 1490504 Jul 18 05:19 foo
linux-vdso.so.1 =>  (0x00007fff2dc66000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007fbc91d96000)
libc.so.6 => /lib/libc.so.6 (0x00007fbc91a34000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbc91fb9000)

$ CGO_ENABLED=0 go build foo.go
$ ls -l foo; ldd foo
-rwxr-xr-x 1 af af 1457960 Jul 18 05:21 foo
not a dynamic executable

I also noticed that the static binary is usually slightly smaller.

Hans Stimer

unread,
Jul 18, 2013, 3:28:27 PM7/18/13
to Alexandre Fiori, golan...@googlegroups.com

Is the plan for Go to continue to function without cgo? Or are just waiting for cgo to work everywhere,

and then we will make it a requirement?


I vote for not ever requiring cgo.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

minux

unread,
Jul 18, 2013, 3:40:56 PM7/18/13
to Alexandre Fiori, golan...@googlegroups.com


On Thursday, July 18, 2013, Alexandre Fiori wrote:

Just wanted to share that I came across this recently and things changed a bit...
Not only Go has to be compiled with CGO_ENABLED=0, but also Go programs later.

To compile Go itself:
export CGO_ENABLED=0
./all.bash
you do not need to disable cgo entirely in Go 1.2, as there will be a build tag
named netgo that only disables cgo for the net package.
e.g. for Go tip, after running:
go install -tags netgo -a -v std 

your can rebuild your networking program and they won't require cgo (if it doesn't use
cgo directly or indirectly thru. its other deps.). 
And then Go programs:
$ cat foo.go 
package main

import "net"

func main() {
net.Dial("tcp", "")
}

$ go build foo.go
$ ls -l foo; ldd foo
-rwxr-xr-x 1 af af 1490504 Jul 18 05:19 foo
linux-vdso.so.1 =>  (0x00007fff2dc66000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007fbc91d96000)
libc.so.6 => /lib/libc.so.6 (0x00007fbc91a34000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbc91fb9000)

$ CGO_ENABLED=0 go build foo.go
$ ls -l foo; ldd foo
-rwxr-xr-x 1 af af 1457960 Jul 18 05:21 foo
not a dynamic executable

I also noticed that the static binary is usually slightly smaller.
the net package use cgo to do dns lookups so that your go program
can act like your other programs when resolving names (e.g. use local
nscd caches if possible). 

also, the pure go resolver in net has a few known bugs, please search the
issue tracker for details. (e.g. not retrying with tcp even if udp request provides
truncated response)

minux

unread,
Jul 18, 2013, 3:45:18 PM7/18/13
to Hans Stimer, Alexandre Fiori, golan...@googlegroups.com

On Friday, July 19, 2013, Hans Stimer wrote:

Is the plan for Go to continue to function without cgo? Or are just waiting for cgo to work everywhere,

and then we will make it a requirement?

yes, at least when it is achievable without reimplementing a lot of
things.
a case where it's not doable without cgo is the os/user package,
you surely do not want to include a ldap client just to support
a (small?) fraction of os/user use cases.

except for that, i believe non-cgo builds will continue to be supported.
Reply all
Reply to author
Forward
0 new messages