The TinyGo Homepage says that it is designed for micro controllers (or MCU). I wonder if it is possible to use TinyGo to compile go into small binary for ARM/Linux system?
Currently with UPX --best --lzma
, my go code compiles to arm binary about 1MB, I hope to make it even smaller, because the system has limited storage.
At first, use two go build flags, and create your executable like this: go build -ldflags="-s -w" . And then use UPX to make your executable smaller.
in Go 1.2, a decision was made to pre-expand the line table in the executable file into its final format suitable for direct use at run-time, without an additional decompression step. In other words, the Go team decided to make executable files larger to save up on initialization time.
At the start of the study, the size of the Go binary was eleven MB.
At the start of the study, the size of the Go binary was eleven MB. The compiled binary contains debug information. In my situation, it is not needed – it is still impossible to debug on target machines due to lack of access. So you can safely remove it by compiling with the necessary flags or using the strip utility.
Ok, I lied, there's no weird trick. However, you can easily reduce a Go binary size by more than 6 times with some flags and common tools.
One final note: a lot of work went into the 1.7 cycle to shrink the binaries, including new conditional tree pruning and generic SSA savings. Here's the size of the same binaries built with Go tip, where 100% is the size of the default 1.6.1 build.
So we went the way with eleven Mb to 1.9 MB, that is, we have reduced the size of the Go-binary by almost 6 times! Stripping a binary and then packing it with upx is a very effective measure to reduce size. You should not neglect and remove unnecessary dependencies.
tl;dr: basically yes, but you might have to port your program.
I wonder if it is possible to use TinyGo to compile go into small binary for ARM/Linux system?
Yes (reference: https://tinygo.org/docs/guides/linux/)
TinyGo also lets you compile programs for Linux systems, both 32-bit and 64-bit, on both x86 and ARM architectures.
For cross compiling, you can use GOOS and GOARCH as usual.
For example:
GOARCH=arm GOOS=linux tinygo build -o example ./...
As for how smaller the executable will be compared with one with the official go
compiler/runtime, it will likely depend on the specifics of your program. It is true though that TinyGo raison d'etre is to provide smaller binaries.
So, we can try building some executables and empirically compare sizes. BTW, I realized that this comparison is available in TinyGo overview page. We can reproduce it here anyway with a few additional details:
First, Go 1.17 is not supported yet (GitHub issue). You have to have Go 1.16 or lower installed in your system to be able to build, or use TinyGo dev
branch.
Then, as I mentioned in the comments, keep in mind that TinyGo doesn't support compiling all standard library packages, so if your code makes use of one of them you'll have to port it. This is the list of supported and unsupported packages: https://tinygo.org/docs/reference/lang-support/stdlib/
To run the comparison, I download Go 1.16.5, which TinyGo supports as of today.
# reference: https://golang.org/doc/manage-install
$ go install golang.org/dl/go1.16.5@latest
$ go1.16.5 download
The program:
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello World!")
}
I'm on a mac, so I have to build with the appropriate env vars. I include building with -ldflags="-s -w"
as suggested in the comments.
$ go env | grep -E "(GOOS|GOARCH)"
GOARCH="amd64"
GOOS="darwin"
$ go1.16.5 build -o example_go ./...
$ go1.16.5 build -ldflags="-s -w" -o example_go_ldflags ./...
$ GOROOT="/Users/blackgreen/sdk/go1.16.5" GOARCH=amd64 GOOS=darwin tinygo build -o example_tinygo ./...
$ du -hs example_*
1.9M example_go
1.5M example_go_ldflags
64K example_tinygo
For a simple hello world program, there is a conspicuous gain. Unsurprisingly, it's significantly better than ldflags
too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With