Building binary executables for Android in Go
Tue, Jan 26, 2016 Tweet Vote on HNI have a use-case to run an external Go binary from within an Android app. By external i mean something that was not bundled inside the APK, but rather (in my case) downloaded from the Internet. The reason for not bundling in-APK is that I need to be able to auto-upgrade the binary without upgrading the APK. APK updates either require user-action or play store or root - all three are not possible for my use-case. I spent an entire day on the issue(android n00b here), which turned out to be a very simple problem solution.
First thing I tried was building normal linux/arm
binaries that I use for normal arm devices.
<pre><code>sajal@sajal-lappy:~$ GOARCH="arm" go build /path/to/filewithmain.go
</code></pre>
android/arm
target. gomobile to the rescue.
gomobile allows us to either generate an .aar
library or an .apk
, both are not applicable here. Solution - use the toolchain gomobile installed but compile code by hand.
My compile command :-
sajal@sajal-lappy:~$ GOMOBILE="/home/sajal/go/pkg/gomobile" GOOS=android GOARCH=arm CC=$GOMOBILE/android-ndk-r10e/arm/bin/arm-linux-androideabi-gcc CXX=$GOMOBILE/android-ndk-r10e/arm/bin/arm-linux-androideabi-g++ CGO_ENABLED=1 GOARM=7 go build -p=8 -pkgdir=$GOMOBILE/pkg_android_arm -tags="" -ldflags="-extldflags=-pie" -o minion -x ~/go/src/github.com/turbobytes/pulse/minion.go
sajal@sajal-lappy:~$ file minion
minion: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
sajal@sajal-lappy:~$ ls -lh minion
- -rwxr-xr-x 1 sajal sajal 9.3M Jan 26 16:52 minion
sajal@sajal-lappy:~$
It took me a while to figure out the -ldflags="-extldflags=-pie"
portion, without it my phone complains about binary not being in PIE format.
Now need to wait for android/368
or android/amd64
support in gomobile so I can play with it in the emulator instead of real device…
PS: I know what I am doing is probably an anti-pattern, but this is not a normal end user app. It would run on devices dedicated to this and I will sign and validate downloads.
PSS: I figured this out by mucking around with gomobile using the -x
option.