【发布时间】:2016-08-15 02:10:14
【问题描述】:
我正在尝试构建一个标准的“Hello, World!” Android 的命令行可执行文件。可执行文件将通过adb shell 运行。
0。 Go (Golang) 源码
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello, world!")
}
1A。构建命令
$ CGO_ENABLED=0 GOOS=android GOARCH=arm GOARM=7 go build .
1B。输出(重新排列换行符以防止滚动条)
# 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)
1℃。再次构建命令
以下命令给出相同的结果:
$ env CGO_ENABLED=0 GOOS=android GOARCH=arm GOARM=7 go build .
2。构建命令(详细)
我尝试过使用"-v",如下所述:
$ CGO_ENABLED=0 GOOS=android GOARCH=arm GOARM=7 go build \
-x -ldflags "-extldflags -v" .
它给了我超过 100 行的消息,所以我不会在这里发布,除非有必要。 go build 命令似乎尝试使用与Xcode 捆绑在一起的clang 编译源代码。
3A。构建命令(成功,但是...)
鉴于发现错误编译器的提示,我尝试像这样设置$CC:
$ CGO_ENABLED=0 GOOS=android GOARCH=arm GOARM=7 \
CC=/path/to/arm-linux-androideabi/bin/clang go build .
arm-linux-androideabi 是make_standalone_toolchain.py(或make-standalone-toolchain.sh)的输出。
3B。输出
可执行文件(名为cross)已成功构建,并带有以下消息:
# github.com/asukakenji/cross
warning: unable to find runtime/cgo.a
我试过adb push它并在Android上用adb shell运行它,它运行良好。
我的问题
- 为什么需要 C 编译器? Go 不是开箱即用的交叉编译吗?
-
在为 Linux(而不是 Android)构建时,编译工作正常:
$ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build .为什么?
-
go build命令一直在寻找runtime/cgo.a,即使我没有在源代码中使用 CGO,即使我设置了CGO_ENABLED=0。我怎样才能摆脱警告?没有一个有什么害处?
【问题讨论】:
-
为了方便起见,我认为您需要 Android NDK。 clang 也应该可以,但它不适用于 Android 原生编程,可能需要大量配置。
-
如上所述,我已经使用 Android NDK 成功编译了代码。问题是为什么需要它。当我以“Linux amd64”为目标时,永远不需要交叉编译器。有什么区别?
-
我猜想一些与
-D__ARM_ANDROID__ -DHAVE_PTHREADS相关的东西,我们总是在 NDK 构建中添加。 -
恐怕你没有抓住重点。我非常了解NDK可以完成工作。我只是想知道为什么需要 C 编译器。据我所知,除非使用 CGO,否则 Golang 编译器无需其他编译器即可将源代码编译为二进制文件。我已经在 Mac 上成功构建了这些,没有任何外部工具:“darwin amd64”(主机)、“linux 386”、“linux amd64”、“windows 386”、“windows amd64”。但是为什么“android arm”是个例外呢?重点不是使用的标志,重点是为什么首先需要 C 编译器!
-
我知道你的意思。但是 C-things (compiler/stdlib/macros/headers/#pragma) 严重依赖平台。另一个 C 编译器几乎不能与 android C-things 一起工作。仍然是我的猜测,没有深入挖掘。
标签: android go cross-compiling cgo