golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.67k stars 17.49k forks source link

x/mobile: does not work with Go 1.22 if a vendor folder is present, even with the `GO111MODULE=off` workaround #67927

Open benma opened 2 months ago

benma commented 2 months ago

Go version

go1.22.4 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/opt/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/opt/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/go_dist/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/go_dist/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.4'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/mobiletest/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2991625483=/tmp/go-build -gno-record-gcc-switches'

What did you do?

Using a dummy main.go:

main.go 
package mobiletest

func Foo() {
}
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
go mod init mobiletest
go mod vendor
gomobile bind -a -target android .
go get golang.org/x/mobile/bind

What did you see happen?

The above fails with:

"golang.org/x/mobile/bind" is not found; run go get golang.org/x/mobile/bind: no Go package in golang.org/x/mobile/bind                                                                                            

As a workaround, before Go1.22, one could install mobile/bind to $GOPATH and use gomobile bind without modules to side-step this issue completely:

GO111MODULE=off go get -u golang.org/x/mobile/cmd/gomobile
GO111MODULE=off gomobile bind -a -target android .

Since GO 1.22 however, go get is not allowed anymore outside of modules.

What did you expect to see?

No error running gomobile bind.

gomobile bind seems to be unworkable using Go 1.22 when a vendor folder is present. The only workaround seems to be to delete the vendor folder before using gomobile bind.

Related: https://github.com/golang/go/issues/34181, but the GO111MODULE=off workaround does not work anymore as of Go 1.22.

gabyhelp commented 2 months ago

Similar Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

benma commented 2 months ago

Another thing I tried is https://github.com/golang/go/issues/43736#issuecomment-1010559154:

Import _ "golang.org/x/mobile/cmd/gobind", then go mod vendor.

But then gomobile bind seems to invoke go mod tidy on a package that is not module aware and results in:

PWD=$WORK/src-android-386 GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=386 CC=$ANDROID_HOME/ndk/21.2.6472646/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android16-clang CXX=$ANDROID_HOME/ndk/21.2.6472646/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android16-clang++ CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go mod tidy
rm -r -f "$WORK"
gomobile: go mod tidy failed: exit status 1
go: error reading go.mod: missing module declaration. To specify the module path:
        go mod edit -module=example.com/mod
hyangah commented 2 months ago

Can you try to manually list the golang.org/x/mobild/bind/* packages in an ignored file, and run go mod tidy & go mod vendor, so the necessary dependencies are vendored if vendoring is required?

//go:build mobilex
// +build mobilex

package mobiletest

import (
    _ "golang.org/x/mobile/bind"
    _ "golang.org/x/mobile/bind/java"
        _ "golang.org/x/mobile/bind/objc"
)

Keeping up with all the Go, Android, Apple toolchains changes is a non-trivial task. Unfortunately, there is nobody actively working on x/mobile as of today.

benma commented 2 months ago

Thanks for the suggestion.

I tried this. Here is the go.mod file:

module mobiletest

go 1.22.4

require golang.org/x/mobile v0.0.0-20240604190613-2782386b8afd

require (
    golang.org/x/mod v0.18.0 // indirect
    golang.org/x/sync v0.7.0 // indirect
    golang.org/x/tools v0.22.0 // indirect
)

These are all the files:

$ find .
.
./go.mod
./main.go
./go.sum
./vendor
./vendor/modules.txt
./vendor/golang.org
./vendor/golang.org/x
./vendor/golang.org/x/mod
./vendor/golang.org/x/mod/PATENTS
./vendor/golang.org/x/mod/semver
./vendor/golang.org/x/mod/semver/semver.go
./vendor/golang.org/x/mod/LICENSE
./vendor/golang.org/x/tools
./vendor/golang.org/x/tools/PATENTS
./vendor/golang.org/x/tools/LICENSE
./vendor/golang.org/x/tools/internal
./vendor/golang.org/x/tools/internal/pkgbits
./vendor/golang.org/x/tools/internal/pkgbits/codes.go
./vendor/golang.org/x/tools/internal/pkgbits/sync.go
./vendor/golang.org/x/tools/internal/pkgbits/support.go
./vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go
./vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go
./vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go
./vendor/golang.org/x/tools/internal/pkgbits/doc.go
./vendor/golang.org/x/tools/internal/pkgbits/reloc.go
./vendor/golang.org/x/tools/internal/pkgbits/flags.go
./vendor/golang.org/x/tools/internal/pkgbits/encoder.go
./vendor/golang.org/x/tools/internal/pkgbits/decoder.go
./vendor/golang.org/x/tools/internal/versions
./vendor/golang.org/x/tools/internal/versions/versions.go
./vendor/golang.org/x/tools/internal/versions/toolchain.go
./vendor/golang.org/x/tools/internal/versions/gover.go
./vendor/golang.org/x/tools/internal/versions/toolchain_go121.go
./vendor/golang.org/x/tools/internal/versions/types.go
./vendor/golang.org/x/tools/internal/versions/toolchain_go120.go
./vendor/golang.org/x/tools/internal/versions/types_go121.go
./vendor/golang.org/x/tools/internal/versions/toolchain_go119.go
./vendor/golang.org/x/tools/internal/versions/types_go122.go
./vendor/golang.org/x/tools/internal/versions/features.go
./vendor/golang.org/x/tools/internal/packagesinternal
./vendor/golang.org/x/tools/internal/packagesinternal/packages.go
./vendor/golang.org/x/tools/internal/aliases
./vendor/golang.org/x/tools/internal/aliases/aliases_go121.go
./vendor/golang.org/x/tools/internal/aliases/aliases.go
./vendor/golang.org/x/tools/internal/aliases/aliases_go122.go
./vendor/golang.org/x/tools/internal/gcimporter
./vendor/golang.org/x/tools/internal/gcimporter/support_go118.go
./vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go
./vendor/golang.org/x/tools/internal/gcimporter/unified_no.go
./vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
./vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go
./vendor/golang.org/x/tools/internal/gcimporter/iimport.go
./vendor/golang.org/x/tools/internal/gcimporter/bimport.go
./vendor/golang.org/x/tools/internal/gcimporter/iexport.go
./vendor/golang.org/x/tools/internal/gcimporter/exportdata.go
./vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go
./vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go
./vendor/golang.org/x/tools/internal/typesinternal
./vendor/golang.org/x/tools/internal/typesinternal/recv.go
./vendor/golang.org/x/tools/internal/typesinternal/errorcode.go
./vendor/golang.org/x/tools/internal/typesinternal/types.go
./vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go
./vendor/golang.org/x/tools/internal/typesinternal/toonew.go
./vendor/golang.org/x/tools/internal/tokeninternal
./vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go
./vendor/golang.org/x/tools/internal/gocommand
./vendor/golang.org/x/tools/internal/gocommand/invoke.go
./vendor/golang.org/x/tools/internal/gocommand/version.go
./vendor/golang.org/x/tools/internal/gocommand/vendor.go
./vendor/golang.org/x/tools/internal/event
./vendor/golang.org/x/tools/internal/event/keys
./vendor/golang.org/x/tools/internal/event/keys/standard.go
./vendor/golang.org/x/tools/internal/event/keys/keys.go
./vendor/golang.org/x/tools/internal/event/keys/util.go
./vendor/golang.org/x/tools/internal/event/label
./vendor/golang.org/x/tools/internal/event/label/label.go
./vendor/golang.org/x/tools/internal/event/doc.go
./vendor/golang.org/x/tools/internal/event/core
./vendor/golang.org/x/tools/internal/event/core/fast.go
./vendor/golang.org/x/tools/internal/event/core/event.go
./vendor/golang.org/x/tools/internal/event/core/export.go
./vendor/golang.org/x/tools/internal/event/event.go
./vendor/golang.org/x/tools/internal/stdlib
./vendor/golang.org/x/tools/internal/stdlib/manifest.go
./vendor/golang.org/x/tools/internal/stdlib/stdlib.go
./vendor/golang.org/x/tools/go
./vendor/golang.org/x/tools/go/types
./vendor/golang.org/x/tools/go/types/objectpath
./vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
./vendor/golang.org/x/tools/go/gcexportdata
./vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go
./vendor/golang.org/x/tools/go/gcexportdata/importer.go
./vendor/golang.org/x/tools/go/internal
./vendor/golang.org/x/tools/go/internal/packagesdriver
./vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
./vendor/golang.org/x/tools/go/packages
./vendor/golang.org/x/tools/go/packages/packages.go
./vendor/golang.org/x/tools/go/packages/external.go
./vendor/golang.org/x/tools/go/packages/visit.go
./vendor/golang.org/x/tools/go/packages/golist.go
./vendor/golang.org/x/tools/go/packages/doc.go
./vendor/golang.org/x/tools/go/packages/golist_overlay.go
./vendor/golang.org/x/tools/go/packages/loadmode_string.go
./vendor/golang.org/x/mobile
./vendor/golang.org/x/mobile/PATENTS
./vendor/golang.org/x/mobile/LICENSE
./vendor/golang.org/x/mobile/bind
./vendor/golang.org/x/mobile/bind/objc
./vendor/golang.org/x/mobile/bind/objc/seq_darwin.m.support
./vendor/golang.org/x/mobile/bind/objc/SeqBench.m
./vendor/golang.org/x/mobile/bind/objc/SeqWrappers.m
./vendor/golang.org/x/mobile/bind/objc/seq_darwin.h
./vendor/golang.org/x/mobile/bind/objc/doc.go
./vendor/golang.org/x/mobile/bind/objc/SeqTest.m
./vendor/golang.org/x/mobile/bind/objc/seq_darwin.go.support
./vendor/golang.org/x/mobile/bind/objc/SeqCustom.m
./vendor/golang.org/x/mobile/bind/objc/ref.h
./vendor/golang.org/x/mobile/bind/seq.go.support
./vendor/golang.org/x/mobile/bind/genobjc.go
./vendor/golang.org/x/mobile/bind/types.go
./vendor/golang.org/x/mobile/bind/seq
./vendor/golang.org/x/mobile/bind/seq/seq.go
./vendor/golang.org/x/mobile/bind/seq/string.go
./vendor/golang.org/x/mobile/bind/seq/ref.go
./vendor/golang.org/x/mobile/bind/gen.go
./vendor/golang.org/x/mobile/bind/bind.go
./vendor/golang.org/x/mobile/bind/gengo.go
./vendor/golang.org/x/mobile/bind/genjava.go
./vendor/golang.org/x/mobile/bind/genclasses.go
./vendor/golang.org/x/mobile/bind/implicit.go
./vendor/golang.org/x/mobile/bind/genobjcw.go
./vendor/golang.org/x/mobile/bind/printer.go
./vendor/golang.org/x/mobile/bind/java
./vendor/golang.org/x/mobile/bind/java/SeqBench.java
./vendor/golang.org/x/mobile/bind/java/CustomPkgTest.java
./vendor/golang.org/x/mobile/bind/java/ClassesTest.java
./vendor/golang.org/x/mobile/bind/java/seq_android.c.support
./vendor/golang.org/x/mobile/bind/java/context_android.c
./vendor/golang.org/x/mobile/bind/java/seq_android.go.support
./vendor/golang.org/x/mobile/bind/java/SeqTest.java
./vendor/golang.org/x/mobile/bind/java/seq_android.h
./vendor/golang.org/x/mobile/bind/java/doc.go
./vendor/golang.org/x/mobile/bind/java/Seq.java
./vendor/golang.org/x/mobile/bind/java/context_android.go
./vendor/golang.org/x/mobile/internal
./vendor/golang.org/x/mobile/internal/importers
./vendor/golang.org/x/mobile/internal/importers/objc
./vendor/golang.org/x/mobile/internal/importers/objc/objc.go
./vendor/golang.org/x/mobile/internal/importers/ast.go
./vendor/golang.org/x/mobile/internal/importers/java
./vendor/golang.org/x/mobile/internal/importers/java/java.go
./vendor/golang.org/x/mobile/internal/mobileinit
./vendor/golang.org/x/mobile/internal/mobileinit/mobileinit_android.go
./vendor/golang.org/x/mobile/internal/mobileinit/mobileinit.go
./vendor/golang.org/x/mobile/internal/mobileinit/ctx_android.go
./vendor/golang.org/x/mobile/internal/mobileinit/mobileinit_ios.go
./vendor/golang.org/x/sync
./vendor/golang.org/x/sync/errgroup
./vendor/golang.org/x/sync/errgroup/errgroup.go
./vendor/golang.org/x/sync/errgroup/go120.go
./vendor/golang.org/x/sync/errgroup/pre_go120.go
./vendor/golang.org/x/sync/PATENTS
./vendor/golang.org/x/sync/LICENSE
./mobilex.go

(mobilex.go is the file with the dummy imports you suggested).

Running (using Go 1.22.4)

ANDROID_HOME=/opt/android-sdk/ gomobile bind -x -a -target android .

results in

GOMOBILE=/opt/go/pkg/gomobile
WORK=/tmp/gomobile-work-1097734853
GOOS=android CGO_ENABLED=1 $GOPATH/bin/gobind -lang=go,java -outdir=$WORK mobiletest
mkdir -p $WORK/src-android-arm64
mkdir -p $WORK/src-android-amd64
mkdir -p $WORK/src-android-386
mkdir -p $WORK/src-android-arm
PWD=$WORK/src-android-386 GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=386 CC=$ANDROID_HOMEndk/21.2.6472646/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android16-clang CXX=$ANDROID_HOMEndk/21.2.6472646/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android16-clang++ CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go mod tidy
PWD=$WORK/src-android-arm GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=arm CC=$ANDROID_HOMEndk/21.2.6472646/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi16-clang CXX=$ANDROID_HOMEndk/21.2.6472646/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi16-clang++ CGO_ENABLED=1 GOARM=7 GOPATH=$WORK:$GOPATH go mod tidy
PWD=$WORK/src-android-arm64 GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=arm64 CC=$ANDROID_HOMEndk/21.2.6472646/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang CXX=$ANDROID_HOMEndk/21.2.6472646/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++ CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go mod tidy
PWD=$WORK/src-android-amd64 GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=amd64 CC=$ANDROID_HOMEndk/21.2.6472646/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang CXX=$ANDROID_HOMEndk/21.2.6472646/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang++ CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go mod tidy
rm -r -f "$WORK"
gomobile: go mod tidy failed: exit status 1
go: error reading go.mod: missing module declaration. To specify the module path:
    go mod edit -module=example.com/mod

Unfortunately, there is nobody actively working on x/mobile as of today.

This is unfortunate indeed. We heavily rely on gomobile and it has been a huge success for us so far. See also this post of appreciation.

Paging a person who recently committed to x/mobile: @hajimehoshi - maybe you also have some suggestions for how to fix this? I'd be happy to contribute, but I am afraid I am a bit out of my depth.

baizon commented 1 month ago

Hi, The issue is, that go list is running without -mod=mod.

By default, if the go version in go.mod is 1.14 or higher and a vendor directory is present, the go command acts as if -mod=vendor were used. Otherwise, the go command acts as if -mod=readonly were used.

I've added a go list args logic that gives the possibility to add flags and resolves the issue (see https://github.com/golang/mobile/pull/105) My test:

$ ./gomobile bind -x -a -glflags="-mod=mod" -target android .
GOMOBILE=/home/baizon/go/pkg/gomobile
WORK=/tmp/gomobile-work-1956788412
GOOS=android CGO_ENABLED=1 /usr/bin/gobind -lang=go,java -outdir=$WORK mobiletest
mkdir -p $WORK/src-android-386
mkdir -p $WORK/src-android-arm
mkdir -p $WORK/src-android-amd64
mkdir -p $WORK/src-android-arm64
PWD=$WORK/src-android-amd64 GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=amd64 CC=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang CXX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang++ CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go mod tidy
PWD=$WORK/src-android-arm GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=arm CC=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang CXX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang++ CGO_ENABLED=1 GOARM=7 GOPATH=$WORK:$GOPATH go mod tidy
PWD=$WORK/src-android-386 GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=386 CC=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android21-clang CXX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android21-clang++ CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go mod tidy
PWD=$WORK/src-android-arm64 GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=arm64 CC=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang CXX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++ CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go mod tidy
PWD=$WORK/src-android-arm GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=arm CC=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang CXX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi21-clang++ CGO_ENABLED=1 GOARM=7 GOPATH=$WORK:$GOPATH go build -x -buildmode=c-shared -o=$WORK/android/src/main/jniLibs/armeabi-v7a/libgojni.so ./gobind
PWD=$WORK/src-android-386 GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=386 CC=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android21-clang CXX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android21-clang++ CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go build -x -buildmode=c-shared -o=$WORK/android/src/main/jniLibs/x86/libgojni.so ./gobind
PWD=$WORK/src-android-amd64 GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=amd64 CC=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang CXX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android21-clang++ CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go build -x -buildmode=c-shared -o=$WORK/android/src/main/jniLibs/x86_64/libgojni.so ./gobind
PWD=$WORK/src-android-arm64 GOMODCACHE=$GOPATH/pkg/mod GOOS=android GOARCH=arm64 CC=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang CXX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++ CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go build -x -buildmode=c-shared -o=$WORK/android/src/main/jniLibs/arm64-v8a/libgojni.so ./gobind
PWD=$WORK/java javac -d $WORK/javac-output -source 1.8 -target 1.8 -bootclasspath $ANDROID_HOMEplatforms/android-21/android.jar go/Seq.java go/Universe.java go/error.java mobiletest/Mobiletest.java
jar c -C $WORK/javac-output .
rm -r -f "$WORK"
$ ls
go.mod  go.sum  gomobile  implicit.go  main.go  mobiletest-sources.jar  mobiletest.aar  vendor