Provide stand-alone Love2d Linux binaries or build instructions

Issue #1168 resolved
Iwan Gabovitch created an issue

Please provide stand-alone executables for Linux which can be used for development, running games and packaging games. I believe the term is static binary? Alternatively, please provide instructions how to build this.

For example, the Godot Engine provides its editor stand-alone. As does Blender.

Common software on Linux usually is packaged and dependencies are packaged separately. But games are not common software, for example a 3d game would never want its physics library to be independently updated if it affects gameplay differently between versions.

Dependencies work for open source software. But Love2d shouldn't de facto require Linux games to be open source.

Love2d should be accessible to players and developers without admin rights.

Love2d games should be accessible to players who don't know anything about 0.6, 0.7, 0.8, 0.9, 0.10 etc. versions of Love2d.

Comments (37)

  1. Bart van Strien

    Let me first say you don't want a static binary, there's a number of reasons, but the primary one is that it violates the LGPL (it's so wonderful!). Ideally though, you want to reduce the number of dynamically linked libraries, and you definitely want to be able to store the dynamic libraries next to the binary, much like windows. There are a few ways to support this, but the easiest is to write a wrapper scripts that sets LD_LIBRARY_PATH (since you need to find the game directory anyway). To build a binary that is portable enough, the trick is mostly to build it on an old distro, so it requires only old kernel interfaces, and an old glibc version (glibc is very backwards-compatible too).

    Unfortunately I don't have the time to look into detailed instructions at the moment, but I will try to write them when I do, and maybe hook it into my nightlies.

  2. Bart van Strien
    • changed status to open

    Kind of by coincidence, I did build some a couple of days ago. I'm not sure what form it will take in the future, especially with projects like snap, appimage and flatpak, but I'll evaluate this again for our next releases.

  3. Iwan Gabovitch reporter

    Thanks, unfortunately this doesn't work on Arch Linux 64bit rolling release with open source AMD drivers (clearly their fault, I don't think steam would run either):

    $ ./love 
    libGL error: unable to load driver:
    libGL error: driver pointer missing
    libGL error: failed to load driver: radeonsi
    libGL error: unable to load driver:
    libGL error: failed to load driver: swrast

    I have to kill -9 the process, ctrl+c doesn't work.

    cat love > gamebin
    chmod +x gamebin

    The above results in the same result.

  4. Bart van Strien

    Just in case, that's using the wrapper script or LD_LIBRARY_PATH set manually?

    I wonder what the open-source amd drivers are doing differently, I compiled it against mesa, and have run it using nvidia drivers.

  5. Iwan Gabovitch reporter

    Whoops, I didn't realize this was a script file and assumed it's a binary.

    The results above are from just running the script.

    If I run ./love from love-0.10.1-amd64/usr/bin without the use of the script in love-0.10.1-amd64/ then it actually works and I see Super Toast No Game.

  6. Bart van Strien

    I'm guessing that's just using the love version you've installed on your system, though. This AskUbuntu topic seems to suggest removing libstdc++ and/or from the distribution might help.

  7. Iwan Gabovitch reporter

    You're probably right. I just know too little jack about Linux.

    Inside love-0.10.1-amd64/usr/bin/:

    $ ldd love (0x00007ffd7f39f000) => /usr/lib/ (0x00007fabedd72000) => /usr/lib/ (0x00007fabeda64000) => /usr/lib/ (0x00007fabed7a8000) => /usr/lib/ (0x00007fabed5a4000) => /usr/lib/ (0x00007fabed387000) => /usr/lib/ (0x00007fabed17f000) => /usr/lib/ (0x00007fabecec9000) => /usr/lib/ (0x00007fabeccb3000) => /usr/lib/ (0x00007fabec926000) => /usr/lib/ (0x00007fabec71d000) => /usr/lib/ (0x00007fabec4f0000) => /usr/lib/ (0x00007fabec2d7000) => /usr/lib/ (0x00007fabec0d0000) => /usr/lib/ (0x00007fabebe60000) => /usr/lib/ (0x00007fabebc01000) => /usr/lib/ (0x00007fabeb9d4000) => /usr/lib/ (0x00007fabeb64c000) => /usr/lib/ (0x00007fabeb348000) => /usr/lib/ (0x00007fabeb131000) => /usr/lib/ (0x00007fabead93000) => /usr/lib/ (0x00007fabeab83000) => /usr/lib/ (0x00007fabea94d000) => /usr/lib/ (0x00007fabea6d1000)
        /lib64/ (0x00007fabee221000) => /usr/lib/ (0x00007fabea3c2000) => /usr/lib/ (0x00007fabea196000) => /usr/lib/ (0x00007fabe9f23000)

    You're right, renaming made toast work

  8. Iwan Gabovitch reporter

    Replacement script that will detect driver in use and make a linked clone of the path containing libstdc++, removing the libstdc++ link and using that path.

    Only tested on arch linux 64bit with open source ATI drivers. Needs testing on proprietary ATI, both NVIDIA, Intel and software-mode-only for the heck of it (to provide a nice error message rather than freezing the thread).

    PS: 32bit version would be nice too of course.

  9. Bart van Strien

    A few comments on your changes, I hope you don't mind:

    • Technically you could flatten the lib dir, I've just copied everything with their full paths, and I'm actually generating the script, so I don't have to set LD_LIBRARY_PATH myself.
    • After exec, control never returns, so the rm's never run.
    • I wonder if always prioritizing the system's libstdc++ would work. Presumably every system that has a libstdc++ installed, and that would already be compatible would also have a new enough libstdc++.
    • Probing for the driver sounds hacky, so I'd prefer it if the above works. If not, well, it's always an option, so thanks anyway for figuring out how to make it work that way.

    As for the 32-bit version, I kind of want to focus on one architecture at the moment, and if that all works (I plan to package it as a snap, AppImage and flatpak), it shouldn't be too hard to grab the 32-bit dependencies in my build chroot and build with -m32. If that doesn't work I might build a 32-bit version of my chroot, but I'm hoping it doesn't come to that.

    Thanks for the continued interest, unfortunately I'm currently unable to spend much time on love, but I hope I can dedicate some more time to it within the next few weeks.

  10. Iwan Gabovitch reporter

    Good job! Supertoast appears, even if I uninstall the system-installed love package.

    If I >> a .love into usr/bin/love, running ./love will run the game, meaning I can make a portable game (assuming this works on other OS).

    I'm running 64bit Arch Linux with open source AMD (ati) drivers

  11. Bart van Strien

    I've also heard from @karai17 that it also works on Fedora 24, and I've replicated that on a clean live dvd. On irc MichaelRaskin said it runs on NixOS too (within a FHS-compatible chroot). So it's looking good so far.

  12. Bart van Strien

    As pgimeno said on the forums, ldconfig isn't always in PATH, since it's in /sbin.

       ./love: 4: ./love: ldconfig: not found
  13. francismoy

    Hi, thanks for all the information. I've learned a lot.

    I know this is an old post, but I have a problem. I have created a Löve build with a new module (Steam module). This module relies on an external library provided by Steam. The problem is that when I launch the love wrapper, it only works if the Steam library is inside a known path, such as /usr/lib. But I wouldn't like users having to install the Steam library by their own.

    It seems like the love wrapper is not exporting the LD_LIBRARY_PATH variable, since it's not finding the Steam library (which I placed inside /usr/lib relative to the love wrapper). I've read this in the Ubuntu Documentation:

    LD_LIBRARY_PATH: List of directories where the system searches for runtime libraries in addition to those hard-defined by ld and in /etc/ files. Note: You can only set this environment variable inside an interactive shell. Since Ubuntu 9.04 Jaunty Jackalope, LD_LIBRARY_PATH cannot be set in $HOME/.profile, /etc/profile, nor /etc/environment files. You must use /etc/ configuration files. See Launchpad bug #366728 for more information.

    Does this mean that the wrapper should be changed to update this new directory?

  14. Bart van Strien

    It does set and export LD_LIBRARY_PATH, and it does contain the (relative) /usr/lib dir. Unfortunately the error indicating that a library cannot be found is very similar to the error indicating that the library cannot find one of the libraries it's looking for. Could it be that you're missing one of the dependencies for the steam library? In case of the wrapper script, setting the environment LOVE_BIN_WRAPPER to ldd before running it should print a list of required libraries and the paths they resolve to, maybe that helps?

  15. francismoy

    Thanks for the quick answer!

    If I understand what you asked me to do, the love wrapper would be as follows:

    export LOVE_LAUNCHER_LOCATION="$(dirname "$(which "$0")")"
    ldconfig -p | grep -q libstdc++ || export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${LOVE_LAUNCHER_LOCATION}/libstdc++/"
    exec ldd "${LOVE_LAUNCHER_LOCATION}/usr/bin/love" "$@"

    The result of executing this is:

    not a dynamic executable

    (I didn't miss text: whatever it's not a dynamic executable is not showing up).

    However, the error shown when executing the normal love wrapper is:

    /home/francis/Downloads/love-0.10.2-amd64/usr/bin/.libs/lt-love: error while loading shared libraries: cannot open shared object file: No such file or directory

    , which is exactly the same error I get when I try to execute love (the binary) and the Steam library is not in /usr/lib. When the library is there, it executes normally (both the love binary and the wrapper).

  16. Bart van Strien

    Right, but that is also the error you get when it can find the library, but not one of its dependencies.

    I'm also not sure how you got these binaries, but if you get that message from ldd, something is wrong, because it really should be a "dynamic executable".

  17. francismoy

    Mmm, yes, it makes sense. I have inspected and (the Steam library) with ldd, and ldd has yielded lots of libraries (which I assume is a good signal), although there was no dependency from liblove to libsteam_api.

    However, and as mentioned before, ldd does not yield any result on the love executable. Right now I'm not sure if I'm generating a 32 or 64 bit binary of Löve. Could it be that I'm generating a 32-bit Löve binary on a 64-bit platform and ldd does not "understand" the ELF-32?

    Calling "file" on the love executable returns "love: Bourne-Again shell script, ASCII text executable, with very long lines", whereas calling "file" on or yields something similar to: "ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=77cdebee1704d413489a4e83c006b14fd7d5b1ae, not stripped".

    The thing is that I got to build everything correctly on Windows and Mac (tested both of them on Steam), but Linux is proving (as usual) more challenging.

    EDIT: I just built Löve again, this time without integrating the Steam module and following the instructions in the Wiki and ldd still yields that it's not a dynamic executable.

    EDIT 2: I compiled once again, this time downlading the sources from here, instead of cloning the repository. ldd love continues yielding "not a dynamic executable".

    EDIT 3: So I found the dependency. It is lt-love that depends on If a make ldd lt-love, I get a bunch of libraries (all of them are found), except for

    ... more libraries ... => not found ... more libraries ...

    EDIT 4 (partially solved): ok, so I managed to execute love from the wrapper. It was a stupid and painful slip on my part: I hadn't placed the inside usr/lib folder... :( What I'm trying now is to create the fuse so that executing the wrapper launches the game directly. What I'm doing

    cat usr/bin/love ~/MyGame/ >> user/bin/MyGame

    And then, changing the wrapper to call:

    exec ${LOVE_BIN_WRAPPER} "${LOVE_LAUNCHER_LOCATION}/usr/bin/MyGame" "$@"

    This isn't working. Only Super Toast appears, but not my game. I'd highly appreciate if you tell me what I'm doing wrong.

  18. Bart van Strien

    Ah, I guess you copied the libtool-generated wrapper, the actual binary (as installed by make install) lives in src/.libs.

    Can you check the concatenated file is actually a valid zip file by trying to open it with an archiver (or zipinfo on the command line)?

  19. francismoy

    Sorry for my late reply. Indeed that was the reason :) Thanks so much for your help. I actually tested it on Steam and the online functions work perfectly!

  20. 4aiman

    I'm I've tried the "love-0.10.2-amd64.tar.gz". Works like a charm! There's a problem with PATH on Debian 9, though (ldconfig not found).

    Also, how about x86?

  21. Bart van Strien

    I fixed the ldconfig issue a while back (see ). I'm planning on building a container to create these builds, both so I can more easily do them (perhaps nightly), and so others can reproduce my work easily. I'm hoping it will be trivial to reapply the same steps to create a 32-bit container once I do, but in any case I'll have proper notes on how to create such an environment.

  22. 4aiman

    Oh, thanks!

    How old should be a system to use your script? Like, will Debian Wheezy do? It's 4 y.o. and has less than a year to be supported.

  23. 4aiman

    Just finished building both x86 and x64 binaries under VBox. Works just fine. Although there are several things to remember if one is to do that on his/her own:

    • libsdl2 from backports is too old (2.0.0 whereas love2d requires 2.0.1). One need to build from source.
    • one will need to change this line to a path to libstdc++
    • x86 build on a x86_64 Debian-driven machine yields the following error:
    ERROR: object '' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
    • There's no libturbojpeg in the standard repo (main, contrib, non-free) and the backports one (main, contrib, non-free). Never bothered to fix either as those builds work for me.

    If anyone is willing to try (or want to use those binaries I built), here they are :) (love2d 0.10.2 + LuaJIT 2.1 (beta 2) + SDL2 2.0.5 )

  24. Seppi

    Small bump - using the love-0.10.2-amd64.tar.gz and it works like a charm. If you could, please include the license.txt like the other love releases!

  25. Bart van Strien

    I've now got two docker images — one for x86_64 and one for i686 — that I can rebuild, that can build love into a tarball, and turn that tarball into a snap and an appimage. Here's the proof. (Note that if you run a 64-bit system like me, you might need a 32-bit libfuse to run the appimage.)

    I've also fixed the ldconfig thing. Next steps are adding the license in a reasonable place and adding support for packaging games, I guess.

  26. Seppi

    @bartbes In the interest of moving my porting progress forward, can you build a love-11.0.0-amd64.tar.gz using the same method for me, and attaching it to this issue?

  27. Andrew Black

    Does this have implications for the instructions on Linux Game Distribution on the wiki ( I'll see if I can investigate this more later, but I just wasted several hours trying to get the instructions there working before giving up and stumbling upon this thread.

  28. Bart van Strien

    I guess I forgot to close this, but we've been releasing with a portable build and appimage for a while now.

  29. Log in to comment