Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross compiling "Hello World" on Mac for Android

I'm trying to build a standard "Hello, World!" command-line executable for Android. The executable is to be run via adb shell.

0. The Go (Golang) Source

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello, world!")
}

1A. The Build Command

$ CGO_ENABLED=0 GOOS=android GOARCH=arm GOARM=7 go build .

1B. The Output (Line Breaks Rearranged to Prevent Scrollbars)

# github.com/asukakenji/cross
warning: unable to find runtime/cgo.a
/usr/local/go/pkg/tool/darwin_amd64/link: running clang failed: exit status 1
ld: warning: ignoring file
    /var/folders/dd/6k6vkzbd6d5803xj9zkjdhmh0000gn/T/go-link-150305609/go.o,
    file was built for unsupported file format
    ( 0x7F 0x45 0x4C 0x46 0x01 0x01 0x01 0x00
      0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 )
    which is not the architecture being linked (x86_64):
    /var/folders/dd/6k6vkzbd6d5803xj9zkjdhmh0000gn/T/go-link-150305609/go.o
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

1C. The Build Command, Again

The following command gives the same result:

$ env CGO_ENABLED=0 GOOS=android GOARCH=arm GOARM=7 go build .

2. The Build Command (Verbose)

I've tried using "-v" as mentioned like this:

$ CGO_ENABLED=0 GOOS=android GOARCH=arm GOARM=7 go build \
      -x -ldflags "-extldflags -v" .

It gives me more than 100 lines of messages, so I don't post it here unless it's necessary. The go build command seems to try compiling the source with the clang bundled with Xcode.

3A. The Build Command (Successful, but...)

Given the hint that the wrong compiler is found, I tried to set $CC like this:

$ CGO_ENABLED=0 GOOS=android GOARCH=arm GOARM=7 \
      CC=/path/to/arm-linux-androideabi/bin/clang go build .

arm-linux-androideabi is the output from make_standalone_toolchain.py (or make-standalone-toolchain.sh).

3B. The Output

The executable (named cross) is successfully built, with the following messages:

# github.com/asukakenji/cross
warning: unable to find runtime/cgo.a

I tried adb push it and run it with adb shell on Android, it worked fine.

My Questions

  1. Why does it need a C compiler? Doesn't Go cross-compile out-of-the-box?
  2. When building for Linux (instead of Android), the compilation works fine:

    $ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build .
    

    Why?

  3. The go build command keeps looking for runtime/cgo.a, even when I didn't use CGO in the source code, and even when I set CGO_ENABLED=0. How can I get rid of the warning? How is it harmful not having one?
like image 978
Siu Ching Pong -Asuka Kenji- Avatar asked Aug 15 '16 02:08

Siu Ching Pong -Asuka Kenji-


3 Answers

if you run that code you find the android as an official target platform listed as GOOS/GOARCH

$go tool dist list
like image 91
Annymosse Avatar answered Oct 16 '22 18:10

Annymosse


Android isn't official target platform for cross-compilation. If all you need are command-line executables then you can set GOOS=linux because android is a linux under the hood, else take a look at https://github.com/golang/go/wiki/Mobile

like image 3
Uvelichitel Avatar answered Oct 16 '22 19:10

Uvelichitel


The cgo requirement might be because go requires libc for DNS lookups on Android: https://github.com/golang/go/issues/8877

like image 2
tmm1 Avatar answered Oct 16 '22 18:10

tmm1