x/mobile/cmd/gomobile: gomobile build on simple program returns "ld: error: duplicate symbol: x_cgo_inittls"
nicklasaven opened this issue ยท 16 comments
What version of Go are you using (go version
)?
$ go version go version go1.15.5 linux/amd64
Does this issue reproduce with the latest release?
Yes, latest release is 1.15.5
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/nicklas/.cache/go-build" GOENV="/home/nicklas/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/nicklas/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/nicklas/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" 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-build465769179=/tmp/go-build -gno-record-gcc-switches"
What did you do?
run
gomobile build
on a simple script like:
package main
/*
double Square(double a)
{
return a * a;
}
*/
import "C"
import "fmt"
func main() {
a := C.double(10)
b := C.Square(a)
fmt.Println(b)
}
What did you expect to see?
That the process succeeded
What did you see instead?
ld: error: duplicate symbol: x_cgo_inittls
>>> defined at gcc_android.c:90
>>> $WORK/b059/_x003.o:(x_cgo_inittls)
>>> defined at gcc_linux_arm.c:13
>>> $WORK/b059/_x006.o:(.bss+0x4)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I think this comes from latest NDK upgrade
I have had a quite hard time to prove that the ndk is at least part of the issue since ndk-bundle precedence is hard coded in env.go
https://github.com/golang/mobile/blob/973feb4309de5c3aad0553fc987d76abf1fa58f7/cmd/gomobile/env.go#L181
So I renamed ndk-bundle folder temporary so I could change ndk with ANDROID_NDK_HOME
Then:
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/22.0.6917172
gomobile build -x -v
fails with the error in this issue
but this works without issue:
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/21.3.6528147
gomobile build -x -v
and
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/20.0.5594570
gomobile build -x -v
By using the -x flag I could confirm that the older NDK then was used instead of ndk-bundle.
This issue was also mentioned in #42647 (comment)
Exporting ANDROID_NDK_HOME may also fail.
ndkRoot := filepath.Join(androidHome, "ndk-bundle")
Yes, exactly, that is why I renamed ndk-bundle so it couldn't find it as I wrote in the issue.
I would have preferred if ANDROID_NDK_HOME tok precedence over the presence of ndk-bundle, but that is another issue I guess :-)
Any idea what the root problem is? I can confirm that compiling a simple go program (anything that uses net) fails for me on NDK version 22, but works for NDK 21. I'm not using gomobile, but invoking the compiler directly like this:
GOOS=android GOARCH=arm64 CGO_ENABLED=1 CC=$NDK_ROOT/21.3.6528147/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang go build
See my issue (resolved for now by downgrading NDK version) here: #42725
I think "extern" keyword is needed before
void (*x_cgo_inittls)(void **tlsg, void **tlsbase);
in each of src/runtime/cgo/gcc_linux_*.c, when used with Android NDK r22-beta1.
What version of Go are you using (
go version
)?$ go version
go version go1.15.5 linux/amd64Does this issue reproduce with the latest release?
Yes, latest release is 1.15.5
What operating system and processor architecture are you using (
go env
)?
go env
OutputWhat did you do?
run
gomobile build
on a simple script like:package main /* double Square(double a) { return a * a; } */ import "C" import "fmt" func main() { a := C.double(10) b := C.Square(a) fmt.Println(b) }
What did you expect to see?
That the process succeeded
What did you see instead?
ld: error: duplicate symbol: x_cgo_inittls >>> defined at gcc_android.c:90 >>> $WORK/b059/_x003.o:(x_cgo_inittls) >>> defined at gcc_linux_arm.c:13 >>> $WORK/b059/_x006.o:(.bss+0x4) clang: error: linker command failed with exit code 1 (use -v to see invocation)
I think this comes from latest NDK upgrade
I have had a quite hard time to prove that the ndk is at least part of the issue since ndk-bundle precedence is hard coded in env.go
https://github.com/golang/mobile/blob/973feb4309de5c3aad0553fc987d76abf1fa58f7/cmd/gomobile/env.go#L181So I renamed ndk-bundle folder temporary so I could change ndk with ANDROID_NDK_HOME
Then:
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/22.0.6917172 gomobile build -x -v
fails with the error in this issue
but this works without issue:
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/21.3.6528147 gomobile build -x -v
and
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/20.0.5594570 gomobile build -x -v
By using the -x flag I could confirm that the older NDK then was used instead of ndk-bundle.
This issue was also mentioned in #42647 (comment)
Solved by downloading older version of NDK 21.3.6528147
https://developer.android.com/ndk/downloads
Adding extern to the gcc_linux_*
files makes the android build work, but then building for linux fails:
[linux-x86_64] Building packages and commands for linux/amd64.
[linux-x86_64] # runtime/cgo
[linux-x86_64] /tmp/go-build668149361/b038/_x006.o: In function `x_cgo_init':
[linux-x86_64] src/runtime/cgo/gcc_linux_amd64.c:51: undefined reference to `x_cgo_inittls'
[linux-x86_64] collect2: error: ld returned 1 exit status
Adding extern to the android file doesn't work:
# runtime/cgo
gcc_android.c:90:15: error: 'extern' variable has an initializer [-Werror,-Wextern-initializer]
Change https://golang.org/cl/280312 mentions this issue: runtime/cgo: fix Android build with NDK 22
@gopherbot Please open backport issues
Although this was filed against x/mobile, the fix is to runtime/cgo in the standard library. This is caused by a change in the default behavior of the C compiler. Anybody using an older release of Go with a new C compiler will run into this problem. Since the fix is small and safe, we should backport it.
Backport issue(s) opened: #43405 (for 1.14), #43406 (for 1.15).
Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://golang.org/wiki/MinorReleases.
NDK 22.0.7026061 same problem, 21.3.6528147 works.
gomobile version +e6ae53a Thu Dec 17 15:07:44 2020 +0000 (android); androidSDK=/home/m/app/android-sdk/platforms/android-30
@eliasnaur would you mind creating the backport CL's for 1.14 and 1.15?
Done.
Hello guys! Sorry, the issue seems to be fixed but how can I get the fix?
I believe Go 1.16 RC1 contains the fix. The Go 1.15 backport is slated to be included in Go 1.15.8.
Thank you @eliasnaur