Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/mobile/app: support all-Go app development on windows #9306

Open
crawshaw opened this issue Dec 13, 2014 · 25 comments
Open

x/mobile/app: support all-Go app development on windows #9306

crawshaw opened this issue Dec 13, 2014 · 25 comments
Assignees
Labels
mobile Android, iOS, and x/mobile OS-Windows
Milestone

Comments

@crawshaw
Copy link
Member

The http://golang.org/x/mobile/app package lets you run all-Go apps on desktop darwin and linux with nothing more than the stock Go build. Just go get and you're programming. This is done via cgo: we ask for a window, get an OpenGL context, and map mouse events to touch events.

We should do the same for Windows. There are a few complications.

The first is by default there is C compiler for cgo on windows. On both linux and OS X we can rely on the user to install gcc/xcode because the platform makes it easy. By comparison MinGW is an extra, non-obvious step for windows users and VC++ isn't supported (and not necessarily any more obvious).

The second is there is no OpenGL. Well, there is kinda, as provided by graphics card makers, but support in particular for OpenGL ES 2 and EGL is spotty. Luckily, Chrome has this problem too and maintain an open source project implementing ES 2 and EGL for Windows on top of DirectX: https://code.google.com/p/angleproject/

I want to avoid importing angleproject directly into the mobile repository as it has several licenses and I want to keep the notices story for the Go repository simple. So we will need another repository that contains a package that links against angleproject and creates the window.

Is there any way about needing windows users to install a C compiler? Can we ship a binary .dll in a repository that is downloaded with go get? If we do, what about the cgo parts of mobile/app and mobile/gl? Can they be provided by the .dll even if we fetch it as part of a different repository? For mobile/app probably, but mobile/gl is harder.

@minux
Copy link
Member

minux commented Dec 13, 2014

you can use the syscall package to access dll exported functions without
cgo. But be aware that floating point arguments and return are not
supported.

@alexbrainman
Copy link
Member

Like @minux said. And yes you can download any .DLL as part of go get, but you would have to put it somewhere in your PATH to be able to use it.

@crawshaw
Copy link
Member Author

syscall.LoadLibrary looks like it would work, but it would mean generating a lot of code for the mobile/gl package. That is, something like https://github.com/golang/mobile/blob/master/gl/gldebug.go that replaces all the cgo calls with syscall.GetProcAddress+syscall.Syscall in a gl_windows.go file.

That's probably the way to go.

@minux
Copy link
Member

minux commented Dec 13, 2014

If you really want to avoid cgo on windows, that is probably the way to go. The generator
need to take care of floating point arguments and returns and probably you also need
to generate the corresponding C wrapper for functions taking floating point arguments
and returning floating point result.

That said, there does exist an easier way to avoid gcc, which I'd call frozen cgo. The idea
is that we preprocess all the cgo files, and compile the cgo.o and include it as cgo.syso
in the package directory.

This approach should work well for cases where we know the interface won't change
(for example, all the C code is statically linked in the syso file). And it also relies on the
fact windows does not support external linking. However, not supporting external linking
also means the syso can't use much C++.

The frozen cgo approach does work. As an example, given this simple cgo program:
package main
/*
int f() { return 42; }
*/
import "C"
func main() {
println(C.f())
}

First go build -work cgo.go, record the $WORK it showed.

And then create a new directory, and copy these four files into it:
cp $WORK/command-line-arguments/obj/all.o cgo$GOOS$GOARCH.syso
cp $WORK/command-line-arguments/obj/cgo_gotypes.o z_cgo_gotypes$GOOS$GOARCH.go
cp $WORK/command-line-arguments/obj/cgo_imports.go z_cgo_imports$GOOS$GOARCH.go
cp $WORK/command-line-arguments/obj/cgo.cgo1.go z_cgo$GOOS_$GOARCH.go

And go build -x inside that directory. You will see that cgo and gcc are not invoked.

This generalizes all cgo programs, just copy all.o to cgo$GOOS_$GOARCH.syso,
and all the Go files inside work directory, replace their leading underscore (go build won't build
any files with underscore as prefix) and append $GOOS$GOARCH to their base name
(we must treat all these as platform dependent).

Although this means that you need to separate windows support to separate package and
precompile for both 386 and amd64, this should be much easier than to use the syscall package
and create wrappers because all this can be automated.

This is the first time I publicly discuss this concept, hopefully it has not been proposed before. :-)

@alexbrainman
Copy link
Member

@minux, I tried following your instructions, but it fails.

C:\go\path\mine\src\foo>dir
Volume in drive C has no label.
Volume Serial Number is XXXX-YYYY

Directory of C:\go\path\mine\src\foo

16/12/2014 10:36 AM

.
16/12/2014 10:36 AM ..
16/12/2014 10:12 AM 87 cgo.go
1 File(s) 87 bytes
2 Dir(s) 112,487,620,608 bytes free

C:\go\path\mine\src\foo>type cgo.go
package main

/*
int f() { return 42; }
*/
import "C"

func main() {
println(C.f())
}

C:\go\path\mine\src\foo>go build -work cgo.go
WORK=C:\DOCUME1\brainman\LOCALS1\Temp\go-build029113339

C:\go\path\mine\src\foo>set WORK=C:\DOCUME1\brainman\LOCALS1\Temp\go-build029113339

C:\go\path\mine\src\foo>copy %WORK%\command-line-arguments_obj_all.o cgo_windows_386.syso
1 file(s) copied.

C:\go\path\mine\src\foo>copy %WORK%\command-line-arguments_obj_cgo_gotypes.o z_cgo_gotypes_windows_386.go
The system cannot find the file specified.

C:\go\path\mine\src\foo>

I am also not convinced that general C code can be packaged into executable on Windows. Some C libs might be configured to be built as DLLs. Then you have to ship these DLLs as part of your app. Some C libs might rely on external libs (DLLs) (for example Microsoft C runtime or similar). Then again you have to distribute these along with your app.

Mind you, you could, probably, create DLL file in /tmp on the fly and load it on your app startup. I have never tried that, but I don't see why it won't work. Maybe anti-virus might complain ...

I am also not sure why you want to run mobile app natively on Windows desktop. I think it would be nuch more useful to be able to launch mobile app inside of some emulator that runs on Windows desktop. The emulator that creates environment that looks as close as possible to real device. Or just launch mobile app on real device.

Alex

@crawshaw
Copy link
Member Author

Configuring build environments for mobile devices is hard. For iOS, you just cannot do it on windows. For android, you need to install the SDK+NDK+Go cross compiler.

What we have right now for Mac and Linux lets you download the stock Go build, write a 15-line app and type go build. Compile+test cycles are dramatically faster than working on the real device, and the whole experience is a lot more fun. I'd like to bring that to windows users. I'm sure we can, there's just work to do.

@alexbrainman
Copy link
Member

Sure, lets try.

@minux
Copy link
Member

minux commented Dec 16, 2014

@alexbrainman,
the essence is that you copy all generated source files in $WORK to the new
directory.
My procedure is for tip. If you're using 1.4, then you need to adjust it
accordingly (1.4
still generates C files to be compiled by the Plan 9 C compiler.)

If you're using tip, copy all Go files in $WORK, but rename them so that
they don't have
a underscore as prefix as the go tool will ignore filenames starting with
underscore.

@minux
Copy link
Member

minux commented Dec 16, 2014

I think doing iOS development on Linux is possible, if we tried hard
enough, we might be
able to get it work on windows.

clang is definitely buildable on windows, as and ld64 are harder. The code
signing tools
are even harder. But at least it's possible to build everything on Linux.

I doubt any iOS app developer want to develop on Windows, though.

@alexbrainman
Copy link
Member

@minux I am using

C:\go\path\mine\src\foo>go version
go version devel +ab96371 Mon Dec 15 01:55:29 2014 +0000 windows/386

@dmitshur
Copy link
Contributor

What we have right now for Mac and Linux lets you download the stock Go build, write a 15-line app and type go build. Compile+test cycles are dramatically faster than working on the real device, and the whole experience is a lot more fun. I'd like to bring that to windows users. I'm sure we can, there's just work to do.


Does x/mobile/gl support windows yet? (I can't remember if either Hana or I added it.) I hope it's not to hard to add, but I wouldn't want to break any gxui users on windows.

So AFAICT, no it doesn't. It doesn't seem trivial to add either. The problem is windows doesn't really have an OpenGL header that's worth using (the system one is OpenGL 1.1, which is pretty worthless). Typically, the drivers support more up to date versions of GL - GXUI has shown that most windows users have a driver that supports at least OpenGL 2.1, but the function pointers need to be obtained using something like wglGetProcAddress.

I'm not sure what the best course of action is for adding Windows support into x/mobile/gl. Really all you're going to end up with is something using GLEW or something that looks very similar to GLOW.

/cc @crawshaw @ben-clayton

It seems the end goal is to make it work very seamless on Windows, but it sounds hard to do right away.

What do you think about taking a smaller step first, getting it to work at least as well as github.com/go-gl/gl/v2.1/gl works on Windows, and then creating a new issue to improve the experience?

Doing that can be done very quickly and allow google/gxui#86 to proceed.

There are a few ways to make it happen:

  • Import and use github.com/go-gl/gl/v2.1/gl to implement the GL interface using windows build constraint.
  • Use glow (the GL bindings generator that is used to generate all go-gl/gl/... packages) to generate the implementation of GL needed for windows build constraint.
  • Similar to above, but outright copy the code of github.com/go-gl/gl/v2.1/gl to implement the GL interface using windows build constraint.
  • Other ways?

@ben-clayton
Copy link

I like the idea of using GLOW - I didn't realise that it was usable outside of the go-gl library.
I'm wondering if we could use GLOW to generate the GLES 2 bindings for all platforms, then wrap these with x/mobile/gl's types.
It seems like GLOW might need to add an Android branch to the procaddr.go generated code. This however is certainly doable.

@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@rsc rsc removed the release-none label Apr 10, 2015
@rsc rsc changed the title mobile/app: support all-Go app development on windows x/mobile/app: support all-Go app development on windows Apr 14, 2015
@rsc rsc modified the milestones: Unreleased, Unplanned Apr 14, 2015
@crawshaw crawshaw self-assigned this Aug 19, 2015
crawshaw added a commit to golang/exp that referenced this issue Dec 11, 2015
A Windows version of the gldriver shares a lot of common code with
the existing windriver. This CL factors it out into a new internal
pacakge, win32.

For golang/go#9306

Change-Id: If602bb42946f1df662b2529d5b277257ae7706d3
Reviewed-on: https://go-review.googlesource.com/17676
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
crawshaw added a commit to golang/exp that referenced this issue Dec 11, 2015
For golang/go#9306

Change-Id: Ib6a7b23288bebebb5e111221338323a2692187b0
Reviewed-on: https://go-review.googlesource.com/17721
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
crawshaw added a commit to golang/exp that referenced this issue Dec 11, 2015
For golang/go#9306

Change-Id: I2e4029e261307e08748b7088c495512247f10d21
Reviewed-on: https://go-review.googlesource.com/17722
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
crawshaw added a commit to golang/mobile that referenced this issue Dec 14, 2015
This allows a subsequent CL to introduce windows support by directly
calling an ANGLE dll.

For golang/go#9306

Change-Id: I7dbe8f2b77b9e2c744f0d848f716ee4448916fe7
Reviewed-on: https://go-review.googlesource.com/17674
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
crawshaw added a commit to golang/mobile that referenced this issue Dec 14, 2015
ANGLE is an open source project that implements OpenGL ES on top of
DirectX. It is used by Chrome to implement WebGL:

	https://github.com/google/angle

It can be compiled into libGLESv2.dll/libEGL.dll and used directly
from Go. This CL includes the changes necessary to the gl package
to use ANGLE.

For the EGL changes, I intend to get x/exp/shiny/driver/gldriver
working, and then make x/mobile/app use it when compiling for
GOOS=windows. (The dependency on shiny's screen package will only
hold when building for desktop OSs.)

For golang/go#9306

Change-Id: I01cb39bc8b56547584b7992eab437bd7ed0312b5
Reviewed-on: https://go-review.googlesource.com/17675
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
crawshaw added a commit to golang/mobile that referenced this issue Dec 14, 2015
Each GL context is used serially, so make the map context-specific.

For golang/go#9306

Change-Id: Ic8261795312bf404f765a9ae8969468f4d170dae
Reviewed-on: https://go-review.googlesource.com/17772
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
crawshaw added a commit to golang/mobile that referenced this issue Dec 14, 2015
For golang/go#9306

Change-Id: Ia8778f5b371371d103c55c12606257ee7ca45fd4
Reviewed-on: https://go-review.googlesource.com/17778
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
@gopherbot
Copy link

CL https://golang.org/cl/17777 mentions this issue.

@gopherbot
Copy link

CL https://golang.org/cl/17810 mentions this issue.

crawshaw added a commit to golang/mobile that referenced this issue Dec 15, 2015
For golang/go#9306

Change-Id: Ibb469d843d2bddeaa3690c59bc9ad532ea3473f7
Reviewed-on: https://go-review.googlesource.com/17810
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
crawshaw added a commit to golang/mobile that referenced this issue Dec 15, 2015
Combined with the outstanding shiny CLs and prebuilt ANGLE dlls in the
right place, this makes it possible to run example/basic on a windows
machine.

Eventually this shiny backend will also replace the app package's
custom darwin_amd64 and linux_x11 backends.

For golang/go#9306

Change-Id: Ia4bf9a85b9d903d79cee36abb470a0ad57f09f36
Reviewed-on: https://go-review.googlesource.com/17777
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
gopherbot pushed a commit to golang/exp that referenced this issue Jan 12, 2016
For golang/go#9306

Change-Id: Ib6a7b23288bebebb5e1d53917d67af72692187b0
Reviewed-on: https://go-review.googlesource.com/17677
Reviewed-by: Nigel Tao <nigeltao@golang.org>
@gonutz
Copy link

gonutz commented Apr 30, 2016

Although this is an old issue I still want to point you to my Direct3D9 wrapper.
It still needs a C compiler (it was tested with MinGW 32 and 64) but you do not have to install any extra libraries or drivers for it to work.
I am also thinking about providing a version of the wrapper that does not use CGo, similar to what w32 does but I have yet to find out how to do that. Until then, only installing MinGW seems OK.

imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 10, 2021
Fixes golang/go#12212
Workaround for golang/go#12261 until golang/go#9306 is fixed.

Change-Id: I51c1bcfc92c1553fe2132586a0234b1c1af6aeb1
Reviewed-on: https://go-review.googlesource.com/13745
Reviewed-by: David Crawshaw <crawshaw@golang.org>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 10, 2021
This allows a subsequent CL to introduce windows support by directly
calling an ANGLE dll.

For golang/go#9306

Change-Id: I7dbe8f2b77b9e2c744f0d848f716ee4448916fe7
Reviewed-on: https://go-review.googlesource.com/17674
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 10, 2021
ANGLE is an open source project that implements OpenGL ES on top of
DirectX. It is used by Chrome to implement WebGL:

	https://github.com/google/angle

It can be compiled into libGLESv2.dll/libEGL.dll and used directly
from Go. This CL includes the changes necessary to the gl package
to use ANGLE.

For the EGL changes, I intend to get x/exp/shiny/driver/gldriver
working, and then make x/mobile/app use it when compiling for
GOOS=windows. (The dependency on shiny's screen package will only
hold when building for desktop OSs.)

For golang/go#9306

Change-Id: I01cb39bc8b56547584b7992eab437bd7ed0312b5
Reviewed-on: https://go-review.googlesource.com/17675
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 10, 2021
Each GL context is used serially, so make the map context-specific.

For golang/go#9306

Change-Id: Ic8261795312bf404f765a9ae8969468f4d170dae
Reviewed-on: https://go-review.googlesource.com/17772
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 10, 2021
For golang/go#9306

Change-Id: Ia8778f5b371371d103c55c12606257ee7ca45fd4
Reviewed-on: https://go-review.googlesource.com/17778
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 10, 2021
For golang/go#9306

Change-Id: Ibb469d843d2bddeaa3690c59bc9ad532ea3473f7
Reviewed-on: https://go-review.googlesource.com/17810
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 10, 2021
Combined with the outstanding shiny CLs and prebuilt ANGLE dlls in the
right place, this makes it possible to run example/basic on a windows
machine.

Eventually this shiny backend will also replace the app package's
custom darwin_amd64 and linux_x11 backends.

For golang/go#9306

Change-Id: Ia4bf9a85b9d903d79cee36abb470a0ad57f09f36
Reviewed-on: https://go-review.googlesource.com/17777
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 11, 2021
Fixes golang/go#12212
Workaround for golang/go#12261 until golang/go#9306 is fixed.

Change-Id: I51c1bcfc92c1553fe2132586a0234b1c1af6aeb1
Reviewed-on: https://go-review.googlesource.com/13745
Reviewed-by: David Crawshaw <crawshaw@golang.org>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 11, 2021
This allows a subsequent CL to introduce windows support by directly
calling an ANGLE dll.

For golang/go#9306

Change-Id: I7dbe8f2b77b9e2c744f0d848f716ee4448916fe7
Reviewed-on: https://go-review.googlesource.com/17674
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 11, 2021
ANGLE is an open source project that implements OpenGL ES on top of
DirectX. It is used by Chrome to implement WebGL:

	https://github.com/google/angle

It can be compiled into libGLESv2.dll/libEGL.dll and used directly
from Go. This CL includes the changes necessary to the gl package
to use ANGLE.

For the EGL changes, I intend to get x/exp/shiny/driver/gldriver
working, and then make x/mobile/app use it when compiling for
GOOS=windows. (The dependency on shiny's screen package will only
hold when building for desktop OSs.)

For golang/go#9306

Change-Id: I01cb39bc8b56547584b7992eab437bd7ed0312b5
Reviewed-on: https://go-review.googlesource.com/17675
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 11, 2021
Each GL context is used serially, so make the map context-specific.

For golang/go#9306

Change-Id: Ic8261795312bf404f765a9ae8969468f4d170dae
Reviewed-on: https://go-review.googlesource.com/17772
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 11, 2021
For golang/go#9306

Change-Id: Ia8778f5b371371d103c55c12606257ee7ca45fd4
Reviewed-on: https://go-review.googlesource.com/17778
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 11, 2021
For golang/go#9306

Change-Id: Ibb469d843d2bddeaa3690c59bc9ad532ea3473f7
Reviewed-on: https://go-review.googlesource.com/17810
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
imWildCat pushed a commit to imWildCat/go-mobile that referenced this issue Apr 11, 2021
Combined with the outstanding shiny CLs and prebuilt ANGLE dlls in the
right place, this makes it possible to run example/basic on a windows
machine.

Eventually this shiny backend will also replace the app package's
custom darwin_amd64 and linux_x11 backends.

For golang/go#9306

Change-Id: Ia4bf9a85b9d903d79cee36abb470a0ad57f09f36
Reviewed-on: https://go-review.googlesource.com/17777
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
@changkun changkun added the mobile Android, iOS, and x/mobile label Feb 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mobile Android, iOS, and x/mobile OS-Windows
Projects
None yet
Development

No branches or pull requests