3 ms·
I am going to post here what seems to be the two least shabby recipes (Ethan Lee is aware of them) to generate elf/linux binaries which will run on "old" and "r
by sylware 3y ago
I am going to post here what seems to be the two least shabby recipes (Ethan Lee is aware of them) to generate elf/linux binaries which will run on "old" and "recent" distros. Then you will understand why normal game devs are not welcome on elf/linux, thx to the very nice and video game caring glibc and gcc devs (irony):
First recipe:
You must not link in the glibc "startup" runtime objects, aka you must not have main(): your executable must be a pure ELF64 binary, only the "_start" ELF entry point and the ELF ABI ("_start" is basically a main() anyway). Careful: all glibc runtime services which require those "startup" runtime objects are gone (you need to be able to find out which ones... good luck browsing glibc code...). Because those glibc "startup" runtime objects often require the same version or above glibc runtime being around (it is very vicious, look at glibc 2.33->2.34 with the new version of the libc_startup symbol... delicious).
It means your build script on elf/linux must have fined grained compilation/linking (don't use the gcc compiler driver unless to discover static libgcc and static libstdc++ filesystem location... if you don't need to fork them).
All host system dependencies must be libdl (dlopen/dlsym/dlclose), yes even the libc, memcpy, errno, etc. Of course you will have to use the static libgcc and static libstdc++ (if c++ is used). Namely if your game binaries are pulling code paths from libgcc and libstdc++ which requires glibc services, you have to fork the libgcc and libstdc++ from the gcc you use in order to properly "libdl-ized" those code paths (readelf command will tell you that while you have a look at the undefined dynamic symbols... and their required version).
Then, you have the abomination of the ELF static flag: many glibc libraries have this flag, namely those libraries must be "statically loaded", namely have a ELF dynamic DT_NEED entry. You will find a ELF dynamic DT_NEED entry for libdl since you use (dlopen/dlsym/dlclose), and probably libpthread/libm(yes...!!!)/etc. Use the binutils readelf command to know if a library has the ELF static flag and must have such an entry (but you must still libdl it and its symbols to work around GNU symbol versioning issues!!). Some TLS code expect some TLS storage to be allocated and inited at executable startup, namely "static".
Of course, all distributed binaries must follow those guidelines... even from third party.
You want to expect normal game devs to be able to do that? ABSURD
2nd recipe:
you get your hands on the most recent gcc, and the oldest glibc you want to support (~10years, more?). Compile such glibc, then this gcc to use only this very glibc (good luck configuring that cleanly). You can use main() and directly glibc services here, but still, you must libdl everything from the video game core libs (you need the headers only).
Expecting that to go smoothly is just unreasonable, it will probably be a nightmare.
All your distributed binaries must be built using this gcc and glibc.
Expecting normal game devs to do that? GROTESQUE
Both recipes must not generate binaries with the latest ELF relative relocations.
The video game core libs on elf/linux are:
wayland(static code in binaries)/libxkbcommon fallback-to-> x11/libxkbcommon-x11 (don't use libX11, only xcb libs).
vulkan fallback-to-> GL fallback-to->CPU, be very conservative with shaders, VERY.
libasound: alsa-lib, the software mixer is hidden behind the API, as it could be pulseaudio1/pulseaudio2(pipewire/wireplumber)/dmix/dsnoop/jack/whatever, have a ffmpeg resampling library ready if your audio formats are weird, or the user microphone audio format is weird. The trick: make user configurable the "speaker configuration" (5.1/7.1/headphones/stereo/etc), but with a automatic fallback to stereo if unable to open the device (all software mixers should support stereo mixing).
joypad: linux /dev/input/eventXX files, check write access if you want to configure the rumbles. You can implement dynamic detection with linux inotify there (usually overkill though).