go: x/mobile/cmd/gomobile: gomobile build on simple program returns "ld: error: duplicate symbol: x_cgo_inittls"

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 https://github.com/golang/go/issues/42647#issuecomment-728608953

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 12
  • Comments: 16 (5 by maintainers)

Commits related to this issue

Most upvoted comments

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

I believe Go 1.16 RC1 contains the fix. The Go 1.15 backport is slated to be included in Go 1.15.8.

Hello guys! Sorry, the issue seems to be fixed but how can I get the fix?

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: https://github.com/golang/go/issues/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.