Golang中gomobile bind失败:重复符号问题
Golang中gomobile bind失败:重复符号问题 我有一个简单的文件:
$ cat goTest.go
package goTest
type Hello interface {
SayHello()
}
func CallJava(h Hello) {
h.SayHello()
}
我在目录中执行了 go mod init goTest。
然后我执行 gomobile bind 失败了:
$ gomobile bind -target=android -v
write /tmp/gomobile-work-794247297/src/go.mod
go: downloading golang.org/x/mobile v0.0.0-20200801112145-973feb4309de
go: found goTest in goTest v0.0.0-00010101000000-000000000000
runtime/cgo
# runtime/cgo
ld: error: duplicate symbol: x_cgo_inittls
>>> defined at gcc_android.c:90
>>> $WORK/b040/_x003.o:(x_cgo_inittls)
>>> defined at gcc_linux_arm.c:13
>>> $WORK/b040/_x006.o:(.bss+0x4)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
gomobile: go build -v -buildmode=c-shared -o=/tmp/gomobile-work-794247297/android/src/main/jniLibs/armeabi-v7a/libgojni.so ./gobind failed: exit status 2
我的系统:
- 5.9.8-arch1-1 #1 SMP PREEMPT Tue, 10 Nov 2020 22:44:11 +0000 x86_64 GNU/Linux
- go version go1.15.5 linux/amd64
- gcc (GCC) 10.2.0
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/rems14/.cache/go-build"
GOENV="/home/rems14/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/rems14/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/rems14/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/rems14/test/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build471762076=/tmp/go-build -gno-record-gcc-switches"
$ env | grep PATH
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/home/rems14/go/bin:/usr/lib/go/bin:/home/rems14/Android/Sdk/build-tools/30.0.2:/home/rems14/Android/Sdk/platform-tools:/home/rems14/Android/Sdk/ndk/22.0.6917172
GOPATH=/home/rems14/go
$ env | grep ANDROID
ANDROID_NDK_HOME=/home/rems14/Android/Sdk/ndk/22.0.6917172
ANDROID_HOME=/home/rems14/Android/Sdk
我尝试的步骤:
- 将 go 版本更改为 1.15.3(我知道这个版本在另一台 PC 上可以工作)并删除 ~/go 目录
- 将 gcc 版本更改为 9
更多关于Golang中gomobile bind失败:重复符号问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
更多关于Golang中gomobile bind失败:重复符号问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个典型的gomobile重复符号问题,通常与NDK版本和gomobile的兼容性有关。错误信息显示x_cgo_inittls符号重复定义,这通常发生在gomobile使用了不兼容的NDK版本时。
根据你的环境变量,你使用的是NDK 22.0.6917172。gomobile对NDK版本比较敏感,建议使用NDK r20b或r21d版本。
解决方案:
- 降级NDK版本(推荐):
# 下载NDK r21d
wget https://dl.google.com/android/repository/android-ndk-r21d-linux-x86_64.zip
unzip android-ndk-r21d-linux-x86_64.zip -d ~/Android/Sdk/ndk/
# 更新环境变量
export ANDROID_NDK_HOME=~/Android/Sdk/ndk/android-ndk-r21d
- 清理gomobile缓存并重新初始化:
# 清理gomobile缓存
rm -rf ~/go/pkg/gomobile
# 重新初始化gomobile
gomobile init -ndk $ANDROID_NDK_HOME
- 如果问题仍然存在,尝试指定NDK路径:
gomobile bind -target=android -v -ndk $ANDROID_NDK_HOME
- 另一种方法是使用gomobile的修复版本:
go get golang.org/x/mobile/cmd/gomobile@latest
gomobile init
- 检查你的go.mod文件,确保gomobile依赖正确:
// go.mod
module goTest
go 1.15
require (
golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f
)
- 完整示例代码,确保接口定义正确:
// goTest.go
package goTest
import "fmt"
type Hello interface {
SayHello()
}
type HelloImpl struct{}
func (h *HelloImpl) SayHello() {
fmt.Println("Hello from Go")
}
func CallJava(h Hello) {
h.SayHello()
}
// 导出函数供Java调用
func NewHello() *HelloImpl {
return &HelloImpl{}
}
执行绑定命令:
# 设置正确的NDK路径
export ANDROID_NDK=~/Android/Sdk/ndk/android-ndk-r21d
gomobile bind -target=android -o goTest.aar .
这个问题主要是由于NDK 22与gomobile的兼容性问题导致的。使用NDK r21d通常可以解决重复符号的链接错误。

