Cross-compilation and binary size optimization - compiling Chisel written in Golang for OpenWRT device

What is Chisel?

Chisel is a lightweight tool that allows to tunnel TCP/UDP traffic over HTTP/Websocket protocol. It was described, along with it’s use case in another post.

Cross-compilation? Why?

My main use-case of Chisel is to allow my OpenWRT based routers to connect to my network infrastructure, even when router is behind the strict firewall that blocks 51820/UDP port, or performs Wireguard protocol detection, and blocks it. Vast majority of OpenWRT devices are using non-x86 architecture, in my case it was MIPS. That means, that every software - including Chisel - should be compiled for target architecture. Performing compilation for specific architecture on different one(for example x86_64) is called cross-compilation.

Weaponized OpenWRT device - Access Point equiped with 33dBm amplifier for 2.4GHz band😈
Teardown of OpenWRT device

Cross-compilation of Golang software

Compiling for MIPS is simple, we have to define three Envrionmental variables prior to compilation command(run inside root directory of source code).

GOOS=linux GOARCH=mips GOMIPS=softfloat go build

Compiled file size is 12.5MB, it’s a lot for embedded device, which has 4 to 8 MB of flash memory. Let’s try to optimize it.


Adding -s -w flags allowed to decrease binary size to 8.9MB, still a lot!

GOOS=linux GOARCH=mips GOMIPS=softfloat go build -ldflags="-s -w"


Binary package can also be compressed by upx.

upx --best --lzma [BinaryName]
Result of UPX compression. 8.9MB compressed down to 1.6MB!!
aaaaand, IT WORKS on target device!!