hajimehoshi / ebiten

Ebitengine - A dead simple 2D game engine for Go
https://ebitengine.org
Apache License 2.0
10.4k stars 633 forks source link

remove Cgo from Linux #2284

Open hajimehoshi opened 1 year ago

hajimehoshi commented 1 year ago

This is basicaly the same as #1162 but for Linux.

Would the ideas in https://github.com/jart/cosmopolitan/issues/303 be a hint?

TotallyGamerJet commented 1 year ago

I believe the same technique used for macOS in purego should work for Linux. Especially now that we are using the normal Cgo calling function runtime.cgocall instead of runtime.libcCall which isn't available on Linux.

hajimehoshi commented 1 year ago

For Linux, the problem is that we cannot use a fixed path for libdl.

TotallyGamerJet commented 1 year ago

I skimmed through the discussion you posted but didn't read why we can't have a fixed path. Isn't it at usr/lib/libdl.so.2 or just do libdl.so.2 and just have the dynamic linker find it? Either way, glibc has merged dl into itself according to this StackOverflow so you could just link to that. You'd probably have to wait until that version of glibc was standard since it quite new.

hajimehoshi commented 1 year ago

I skimmed through the discussion you posted but didn't read why we can't have a fixed path.

Sorry I left the URL but without thinking carefully. I just thought they were trying to solve an issue without depending on libc (at least when compiling). I think the URL has nothing to do with the fixed-path issue.

Isn't it at usr/lib/libdl.so.2 or just do libdl.so.2 and just have the dynamic linker find it? Either way, glibc has merged dl into itself according to this StackOverflow so you could just link to that. You'd probably have to wait until that version of glibc was standard since it quite new.

Oh I see. So we will assume the existence of (g)libc in the user's environment, right?

TotallyGamerJet commented 1 year ago

Oh I see. So we will assume the existence of (g)libc in the user's environment, right?

Well it depends on if libdl.so.2 is truly unable to be found by the dynamic linker than I guess so?

hajimehoshi commented 1 year ago

Well it depends on if libdl.so.2 is truly unable to be found by the dynamic linker than I guess so?

OK that makes sense. It is ok if we don't use it when building an Ebitengine app.

hajimehoshi commented 1 year ago

Another issue is that we would have to support various architectures not only 386, amd64, arm, and arm64 but also mips, ppc, and so on:

$ go tool dist list | grep linux
linux/386
linux/amd64
linux/arm
linux/arm64
linux/loong64
linux/mips
linux/mips64
linux/mips64le
linux/mipsle
linux/ppc64
linux/ppc64le
linux/riscv64
linux/s390x
TotallyGamerJet commented 1 year ago

I'd think that doing it for SyscallN would be easy but I'm not sure we'd need to do NewCallback which is a lot of extra code

hajimehoshi commented 1 year ago

As new architectures will likely be added in the future for Linux, I think having a Cgo version as a fallback would be feasible (but this might be a tough work for you...)

TotallyGamerJet commented 1 year ago

As long as we keep Linux limited to just SyscallN it won’t be. That’s pretty easy to emulate in C

superloach commented 1 year ago

Is the work in https://github.com/notti/nocgo at all relevant? It seems they're using //go:cgo_import_dynamic to load in libdl.so.2 without actually using cgo.

TotallyGamerJet commented 1 year ago

Yes. That is the inspiration behind purego

hajimehoshi commented 1 year ago

Note to myself: If this issue is resolved, Ebitengine will be able to run on the Go playground (by using IMAGE:) lol

TotallyGamerJet commented 1 year ago

I had not heard of IMAGE: so I looked it up. Very cool! However, I'm not sure purego or some other mechanism would make this possible. Since Ebitengine uses X11/Wayland and OpenGL neither of which exist on the playground right?

hajimehoshi commented 1 year ago

Yeah we would have to implement our own CPU rendering engine unfortunately.

TotallyGamerJet commented 1 year ago

But the good news is that if we have a general method for calling into C without Cgo then we can just modify or directly use a C software implementation

hajimehoshi commented 1 year ago

This sounds an interesting idea!

MetalMaxMX commented 10 months ago

Hello! I have a bit of a question here. If Ebitengine eventually supports the removal of Cgo, does that means that cross-compiling from one host to another would be possible? (Say, from Linux to Windows? or maybe even the BSDs)

hajimehoshi commented 10 months ago

from Linux to Windows

It's already possible :)

or maybe even the BSDs

In theory yes, though Ebitengine is not tested well for BSDs.

MetalMaxMX commented 10 months ago

Wait, it's already possible to cross-compile from Linux to Windows!? How? Is it documented anywhere? As for the BSDs, well, I believe they'll be fine. Though that's just a gut feeling of mine.

hajimehoshi commented 10 months ago

Wait, it's already possible to cross-compile from Linux to Windows!? How? Is it documented anywhere?

This is done basically by golang.org/x/sys/windows.NewLazySystemDll to call DLL functions. This is already done since Ebitengine 1.9.

MetalMaxMX commented 10 months ago

Oh, I see. Didn't know that admittedly, I saw on a much older issue that cross-building wasn't supported so I just assumed that it wasn't built-in, but now I know. Thanks!

hajimehoshi commented 3 months ago

I've created an experimental fix https://github.com/hajimehoshi/ebiten/commit/4e3b66440ab044e16eacb5dda1c2ad675571dd97

PureGo supports only amd64 and arm64, so unfortunately the code base would be much complicated for other architectures.

hajimehoshi commented 3 months ago

Hm? Shouldn't purego work for non-supported architectures with Cgo? Let me check