The love2d static build story was a tangent to my 2016 challenge to ship one game every month of the year. The tangent ended up delaying the March game indefinitely, and thus ending the challenge... My memory is a bit hazy, so apologies for the scarce/imprecise details.
I really, really wanted to ship binary builds for the three major platforms: Windows, Mac, and Linux; so that my friends and strangers could actually play the games, without dicking around downloading some framework. Love2d uses the relatively well-known hack of opening "argv[0]" as a ZIP file (the ZIP header starts at the end of a file, so this usually[0] just works).
Creating and testing the builds for Windows was trivial - even though I didn't even have Windows on any of my computers; I borrowed a friend's laptop to verify that "cat love.exe game.love > game.exe" just works, and indeed it did. They got some scary warnings about binaries downloaded from the Internet, but the game ran well.
The Mac needed a bit more fiddling, and I didn't have a Mac back then to sign or test the build. But I followed the instructions and someone reported success (modulo scary warnings). Woohoo.
On to Linux... I already knew it was going to be the most "fun", despite being the only platform among these three that didn't do code signing or scary warnings. I didn't even realize at the time, how much of a clusterfuck glibc actually is; my primary motivation was that Love2d kept breaking their Lua APIs, and I've already found that lots of older (and even recent) Love2d games simply couldn't cope. My game had to be bound to a specific version of Love2d, and many distributions shipped different versions, so the only reasonable path forward was to bundle, just like on Windows/Mac.
I started by downloading the Love2d sources, verifying that I can make a standard/dynamic build, and then "cat love game.love > game && chmod +x game && ./game". Indeed that was easy, but "ldd game" revealed several dozen shared libraries for things like PNG, Vorbis, etc, etc. I've looked at the .so numbers, and realized Love2d breaking is gonna be the lesser of my worries - judging by how high these numbers were, I was signing up for DLL hell. I didn't even want PNG or Vorbis - all of my graphics were 100% procedural, and I was yet to try adding sound to any game. So I've disabled most options, and this is where the easy part ended.
I don't recall where exactly I gave up... I managed to find & download the sources for a whole bunch of these libraries, make the ".a" archives for static builds, and so on... I think at some point I've ran into Mesa (Love2d actually requires GPU acceleration) and decided that this is enough insanity.
I still firmly believe in static linking on Linux! I only changed my approach: just use Go (with CGO_ENABLED=0). Unfortunately, Go is not without its own share of problems[0]; while XGB allows cgo-less X11, Mesa remains elusive.
Thanks for sharing this journey! I've been considering Love2D for a while so it's important to read about the challenges others run into. You should definitely not have to package Mesa to ship a game! I wonder why it hooks so far deeply..
Coming from PICO-8 myself, I'm wondering if I should just skip the frameworks to babystep and just jump into C+SDL, or pygame or something. I like the different ways that games can be made -- like your procedural graphics not needing a graphics library.
The "can I link Mesa statically" journey was futile, I had much less understanding how things worked back then (not that I'm any kind of an expert now, but you shouldn't be one to ship a f.in game). See, a pretty big chunk of the graphics driver stack on Linux sits in the .so's provided by Mesa: the i915_dri.so, r600_dri.so, nouveau_dri.so, libvulkan_intel.so, libvulkan_radeon.so, etc are ALL exactly what it says on the package. It's not just 50+MB of x86-64 code, it's also your peace of mind that whenever AMD/Intel/NVidia/Apple/RPi/etc drop a new GPU model, or whenever the kernel changes things on their end, you don't need to relink and re-release.
I'm torn between "all of this stuff belongs in the kernel goddammit" and "these guys probably know better". OpenBSD and macOS actually force all syscalls to go through a dynamically linked libc, so perhaps it's the latter.
Libraries/frameworks/engines such as PICO-8, Love2d, SDL, Allegro, Pygame, Godot, etc exist precisely to abstract away these details; you're not meant to care for libGL.so.1, you're meant to care for fixing your physics engine's timestep and using cubic splines to interpolate animation. Love2d was not a mature choice in 2016, so don't take my horror story or my hubris as any indication of what it looks like today; do your own research and pick the tool for the job ;)
TBH I would love to go back to making games, but recently got too absorbed by StarCraft 2 and shitposting.
Part of my interest is also getting better at Lua, and it seems to excel in embedded contexts like making small 2D games. So maybe Love2D will still be good for that, and maybe the statically linking story is better now. My eventual goal is similar to yours -- I want to ship a game with a single binary per platform that players don't have to get confused about. Completing a game at all would be good enough, but I want to do it right!
I was recently surprised that CGO only works on Windows with a msys2 compiler, while everyone else works just fine with Visual C++, or VS provided clang.
I'm yet to tackle actually testing any of my software on a real Windows machine; I usually just smoke-test things through Wine. (That's already more effort than what Linux devs do towards BSD so I award myself a point for that.)
I have my eyes on AppImage - it looks the most sane, vs Flatpak or Snap. For CLI apps, Go is great at making static binaries that Just Work.
Most of my past interactions with LD_PRELOAD caused some trouble down the line. It likes to leak into unexpected places, sowing discord and heisenbugs. I'd rather never touch it again unless out of other options.
I really, really wanted to ship binary builds for the three major platforms: Windows, Mac, and Linux; so that my friends and strangers could actually play the games, without dicking around downloading some framework. Love2d uses the relatively well-known hack of opening "argv[0]" as a ZIP file (the ZIP header starts at the end of a file, so this usually[0] just works).
Creating and testing the builds for Windows was trivial - even though I didn't even have Windows on any of my computers; I borrowed a friend's laptop to verify that "cat love.exe game.love > game.exe" just works, and indeed it did. They got some scary warnings about binaries downloaded from the Internet, but the game ran well.
The Mac needed a bit more fiddling, and I didn't have a Mac back then to sign or test the build. But I followed the instructions and someone reported success (modulo scary warnings). Woohoo.
On to Linux... I already knew it was going to be the most "fun", despite being the only platform among these three that didn't do code signing or scary warnings. I didn't even realize at the time, how much of a clusterfuck glibc actually is; my primary motivation was that Love2d kept breaking their Lua APIs, and I've already found that lots of older (and even recent) Love2d games simply couldn't cope. My game had to be bound to a specific version of Love2d, and many distributions shipped different versions, so the only reasonable path forward was to bundle, just like on Windows/Mac.
I started by downloading the Love2d sources, verifying that I can make a standard/dynamic build, and then "cat love game.love > game && chmod +x game && ./game". Indeed that was easy, but "ldd game" revealed several dozen shared libraries for things like PNG, Vorbis, etc, etc. I've looked at the .so numbers, and realized Love2d breaking is gonna be the lesser of my worries - judging by how high these numbers were, I was signing up for DLL hell. I didn't even want PNG or Vorbis - all of my graphics were 100% procedural, and I was yet to try adding sound to any game. So I've disabled most options, and this is where the easy part ended.
I don't recall where exactly I gave up... I managed to find & download the sources for a whole bunch of these libraries, make the ".a" archives for static builds, and so on... I think at some point I've ran into Mesa (Love2d actually requires GPU acceleration) and decided that this is enough insanity.
I still firmly believe in static linking on Linux! I only changed my approach: just use Go (with CGO_ENABLED=0). Unfortunately, Go is not without its own share of problems[0]; while XGB allows cgo-less X11, Mesa remains elusive.
[0]: https://flak.tedunangst.com/post/the-three-line-single-binar...