One of the reasons I love working with
GO is because I can compile go code into a
statically linked binary. Why bother? Well, it's hard to answer but simply putting it everything is needs is right inside the binary as opposed to a
dynamically linked binary. A dynamically linked binary is usually smaller in size as it
dynamically links to it's dependencies installed on an
OS. Lets take
LibC for example,
LibC contain certain library functions required by the application code, when I run a
dynamically linked binary, it will link to whatever
LibC found on the system whereas a statically linked binary has
LibC (and other dependent libraries) embeded inside the binary itself hence
statically linked binary is larger in size but does not use any of the system libraries. It has many advantages but those are out of scope of this article. This article answers
How and assumes you know
Now lets get started. It's easy to compile
go build .
does the job. It would produce a binary (dynamically linked) with the same name as the
directory. If you want to name the binary in a different name, you can do
go build -o app .
go build to set the
output binary name, the
. in the end tells the compiler to compile
package represented by
current directory. Go compiler compiles
packages as a smallest distributable unit is a
Now lets compile statically, in order to do so, we need to tell compiler for what OS to compile for and what system platform. In my case the OS is
darwin (os-x), you might be having
linux (any linux distribution), it also needs
CGO settings, to statically compile we have to tell compiler to disable
CGO by setting
CGO_ENABLED=0. You can optionally provide
linker arguments. There are many other configurations that you can pass during compiling or even writing code, but for this article we are only going to cover basic.
Following code will compile the binary statically.
env CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -a -o app
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o app
As I mentioned, go compiler looks for settings from environment variables as well. In above command line, we specify following environment variables:
CGO_ENABLED=0This tells compiler to disable
CGOand statically link
Cbindings as well.
GOOS=linuxThis tells compiler for which OS it needs to compile.
GOARCH=amd64This tells compiler to compile for an
amd64compatible system architecture (64 bit processor).
Platformlist gets bigger and bigger every day, you can use
go tool dist listto see current latest OS/ARCH combination that you can target. At time of writing this article, this is what I got
Go ahead and invoke
./app ... On a terminal you will not see any difference but typically I use statically build images for
Cheers and Happy coding!
Subscribe to Odd Code
Get the latest posts delivered right to your inbox