* Go can't dynamically link to C libraries (.so). It can, however, dynamically link to DLLs, which is interesting.
* C can't dynamically link things built with Go
If I were to guess, they're trying to tackle the first problem.
The upshot is that while "go build" might be expected to create a static binary (that should be easy to run in a chroot) -- in practice it won't unless you manually rebuild your go toolchain, passing in a parameter to avoid cgo/linking to c libraries for name lookup.
Eg:
cd /tmp
git clone git@github.com:apg/wipes.git wipes.git
cd wipes.git/
go get github.com/gorilla/websocket
go get github.com/gorilla/websocket
go build
ldd wipes.git
# > libc.so.6 among others
export CGO_ENABLED=0
go build # makes no difference, produces identical binary
Afaik, in this case it's 'net/http' that pulls in a dependency on cgo
(again, unless we rebuild the whole go toolchain with cgo_enabled=0).Not that this is terrible as such, but it's a gotcha if you want to run the resulting binary in a chroot, or on a host with a different version of libc...
it hasn't. i meant 'if you build go with CGO_ENABLED=0' but was unclear.
> Afaik, in this case it's 'net/http' that pulls in a
> dependency on cgo (again, unless we rebuild the whole
> go toolchain with cgo_enabled=0).
You can also build with '-tags netgo'[1], and use go for name resolution, but still use cgo for when else you may need it. go install -a -tags netgo std
go build -tags netgo
ldd wipes.git
not a dynamic executable
Thanks for the tip :)The Go linker does know how to link with external objects and use their symbols, and it does this without requiring the external object to be present at link time. It can do this, because the most basic relocations don't require any knowledge about the object. This was previously supported only on PE-COFF, as it was previously used by the Windows target, but now I have extended it to ELF too, and it's used on the Solaris target. In principle, it works on every other ELF platform too (Linux, *BSD).
Note that in all of these cases ABI translation needs to be done, and the internal machinery in the runtime that does this is in motion, just like with cgo. There's no difference in the runtime performance envelope, the only difference is that it doesn't require a target toolchain, like cgo does.
Please see my comment here: https://news.ycombinator.com/item?id=7679041
In short, The Go linker can link with ELF shared objects just fine, just as it can link with PE-COFF shared objects, but it supports only the most basic of relocations in both cases (and this is a property of the design, as we can't expect the presence of the shared object because that would break cross-compilation), and it's not what you probably want anyway.
Although, the most recent discussion I can find seems to suggest disagreement on how to approach this for a final solution, so not likely to see anything soon: https://groups.google.com/d/topic/golang-dev/Lp59oYc4Ta8/dis...