我一直在尝试在Android 10上运行Go应用程序,但遇到了问题。我相当确定现在知道为什么会遇到这个问题,但不确定如何解决它。首先,交叉编译可以使用简单的东西。例如,
可以通过以下命令编译成功:`GOARM=arm64 GOOS=linux go build`。但是如果现在添加一些网络代码:
并且编译的方式和运行的方式相同,但我会得到一个错误,例如:
起初我以为这是我的安卓设备上的一些网络配置问题,但经过了很多折腾后,我相信这与安卓的网络设置“不同”有关。也许这是一个Bionic vs libc的问题(?),但至少还有一个人似乎遇到了同样的问题,并通过使用NDK附带的工具链来解决。 但有没有人知道如何真正让它工作呢? 最初我希望它像
一些谷歌搜索结果显示 https://github.com/golang/go/issues/30216 - 其中提到您需要显式启用CGO。但是
我尝试了很多其他组合,最接近的是将Go指向我的NDK安装中的编译器。基本上是像这样:
我指向编译器的方式似乎有问题 - 例如,如果不指定sysroot,我将找不到任何头文件(stdlib.h),即使指定了它,也无法找到架构特定的包含文件(asm/types.h)而不指定其他包含路径。因此,错误可能是架构和编译器之间的不匹配,但我不确定在哪里或如何修复它。
如果您已经阅读了所有内容,感谢!一些额外的信息:
- Go版本:1.14.13 linux/amd64 - NDK版本:r16b
我也看了一些类似gomobile这样的东西,但那似乎更适用于构建Android应用程序(如apk),尽管我可能在这里错过了什么。
package main
import "fmt"
func main() {
fmt.Println("Hello, Android!")
}
可以通过以下命令编译成功:`GOARM=arm64 GOOS=linux go build`。但是如果现在添加一些网络代码:
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
fmt.Println("Hello, Android!")
client := &http.Client{}
resp, err := client.Get("https://www.google.com")
if err != nil {
fmt.Println(err)
return
}
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%s", bodyBytes)
}
并且编译的方式和运行的方式相同,但我会得到一个错误,例如:
Get "https://www.google.com": dial tcp: lookup www.google.com on [::1]:53: read udp [::1]:47618->[::1]:53: read: connection refused
起初我以为这是我的安卓设备上的一些网络配置问题,但经过了很多折腾后,我相信这与安卓的网络设置“不同”有关。也许这是一个Bionic vs libc的问题(?),但至少还有一个人似乎遇到了同样的问题,并通过使用NDK附带的工具链来解决。 但有没有人知道如何真正让它工作呢? 最初我希望它像
GOOS=android GOARCH=arm64 go build
那样容易,但失败了:# command-line-arguments
/usr/lib/golang/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-384615804/go.o: Relocations in generic ELF (EM: 183)
<bunch of these>
/usr/bin/ld: /tmp/go-link-384615804/go.o: error adding symbols: file in wrong format
collect2: error: ld returned 1 exit status
一些谷歌搜索结果显示 https://github.com/golang/go/issues/30216 - 其中提到您需要显式启用CGO。但是
GOARCH=arm64 GOOS=android CGO_ENABLED=1 go build
仍然失败,这次的错误信息是:# runtime/cgo
gcc_android.c:6:10: fatal error: android/log.h: No such file or directory
6 | #include <android/log.h>
| ^~~~~~~~~~~~~~~
compilation terminated.
我尝试了很多其他组合,最接近的是将Go指向我的NDK安装中的编译器。基本上是像这样:
GOARCH=arm64 GOOS=android CC=$NDKROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc CGO_ENABLED=1 CGO_CFLAGS="--sysroot $NDKROOT/sysroot -I$NDKROOT/sysroot/usr/include/arm-linux-androideabi/" go build
。但是这失败了:# runtime/cgo
In file included from _cgo_export.c:4:0:
cgo-gcc-export-header-prolog:25:14: error: size of array '_check_for_64_bit_pointer_matching_GoInt' is negative
我指向编译器的方式似乎有问题 - 例如,如果不指定sysroot,我将找不到任何头文件(stdlib.h),即使指定了它,也无法找到架构特定的包含文件(asm/types.h)而不指定其他包含路径。因此,错误可能是架构和编译器之间的不匹配,但我不确定在哪里或如何修复它。
如果您已经阅读了所有内容,感谢!一些额外的信息:
- Go版本:1.14.13 linux/amd64 - NDK版本:r16b
我也看了一些类似gomobile这样的东西,但那似乎更适用于构建Android应用程序(如apk),尽管我可能在这里错过了什么。
https://github.com/inconshreveable/ngrok
的安卓版本时遇到的同样问题,谢谢。 - undefined$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang
即可。 - undefined