golang / go

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

x/mobile: EGLNativeWindowType definition mismatch on Android Termux #68727

Closed vsm0 closed 1 month ago

vsm0 commented 1 month ago

I first encountered this issue when compiling an Ebitengine app in an Android Termux environment.

Full disclosure, there's the open build issue #47727 also for Termux, but doesn't seem related.

The package uses ebitenmobile, which is an extension of golang.org/x/mobile. From that discussion I was advised to report the issue in the upstream repo if I could reproduce the error there.

I did, so here I am. The following is more or less a replica of the original issue

Operating System

Go Version (go version)

1.22.5

Output of Go env (go env)

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/data/data/com.termux/files/home/.cache/go-build'
GOENV='/data/data/com.termux/files/home/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='android'
GOINSECURE=''
GOMODCACHE='/data/data/com.termux/files/home/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='android'
GOPATH='/data/data/com.termux/files/home/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/data/data/com.termux/files/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN=''
GOTOOLDIR='/data/data/com.termux/files/usr/lib/go/pkg/tool/android_arm64'
GOVCS=''
GOVERSION='go1.22.5'
GCCGO='gccgo'
AR='ar'
CC='aarch64-linux-android-clang'
CXX='aarch64-linux-android-clang++'
CGO_ENABLED='1'
GOMOD='/data/data/com.termux/files/home/tmp/mobile/example/basic/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 -pthread -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/data/data/com.termux/files/usr/tmp/go-build1234048493=/tmp/go-build -gno-record-gcc-switches'

What steps will reproduce the problem?

From within the Termux app, cd into a project directory and execute the following:

mkdir basic && cd basic
go mod init basic
go get golang.org/x/mobile/example/basic
go install golang.org/x/mobile/example/basic

What is the expected result?

A green triangle on green background should display.

What happens instead?

The program doesn't build.

The following error appears during compilation:

android.c:171:52: error: incompatible pointer to integer conversion passing 'ANativeWindow *' (aka 'struct ANativeWindow *') to parameter of type 'EGLNativeWindowType' (aka 'unsigned long') [-Wint-conversion]
../../../../usr/include/EGL/egl.h:136:109: note: passing argument to parameter 'win' here

Anything else you feel useful to add?

The compilation environment is Termux, which is non-standard Android.

After some investigation, the clash between parameter value and signature is possibly due an incorrect/incomplete appraisal of the compilation environment, within the header eglplatform.h, as noted by the error.

A standard Android target (as defined in eglplatform.h) has the following conditional definition:

#elif defined(__ANDROID__) || defined(ANDROID)
#include <android/native_window.h>
...
typedef struct ANativeWindow* EGLNativeWindowType;

However, Termux modifies this slightly:

#elif (defined(__ANDROID__) || defined(ANDROID)) && !defined(__TERMUX__)
...                                                                 
typedef struct ANativeWindow* EGLNativeWindowType;

Since this definition doesn't match, I suspect it falls through to the next defined variable 'unix' (which I confirmed by preprocessing gomobile/app/android.c using gcc -E -dM android.c):

#elif defined(__unix__)
...
typedef khronos_uintptr_t EGLNativeWindowType;

It's my first time digging so deep into library internals, but unless I'm way off mark, it's possible that gomobile uses the standard eglplatform.h header, which mistakes the Termux environment for a standard Android one.

EDIT: for clarification, the issue doesn't lie with ebiten, but with golang.org/x/mobile and its code that doesn't seem to account for the case of the TERMUX preprocessor macro, as in Termux's patched header files.

Despite being an Android environment, it doesn't work with typical Android rendering, and probably identifies as UNIX or some other non Android platform.

Also, Termux does support graphics and graphical programs. I can run x11 programs and use libraries like Java Swing, SDL and Raylib successfully, even other Go graphical libraries. It's just this one in particular that doesn't work.

hajimehoshi commented 1 month ago

From the script you executed, gomobile is not related.