Search code examples
pythonlinuxshared-librariessdl-2pysdl2

Portable .so library for Linux


I am writing a Python app that works with graphics and depends on PySDL2 library. PySDL2 depends on compiled SDL2 binary library that can be downloaded from SDL site. I wrote a bootstrap script to automate the process, but it works only for Windows, because there is no binary download for Linux.

The question is how to make that binary SDL2 download for Linux?

It is not clear if it is possible to create .so file that will work on every Linux at all, if it is because it is impossible to create .so file that will work on every CPU, and that's mostly because it is not clear if any work was already done in this direction (I am sure people tried to research this problem) and if it is, then why the format of portable .so file (cross-platform against different distributions and CPUs) was not adopted.

UPDATE: I don't mind installing dependencies (packages) with updates and security fixes provided by Linux community, but this should be done in user space, and I need the ability to automate it with portable scripts.


Solution

  • Regarding CPU architectures, Linux does not have support for Fat Binaries (more than architecture per binary, something which is available in OS X for example). There was a proposal called Fat ELF by Ryan Gordon which sadly didn't go anywhere.

    In the particular case of SDL2, the library links by default to very few libraries:

    ldd /usr/local/lib/libSDL2.so

        linux-vdso.so.1 =>  (0x00007fffd1f0b000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f414c44e000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f414c24a000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f414c02c000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f414be24000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f414ba5c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f414cac4000)
    

    The rest of the binaries SDL depends on are loaded dynamically (using dlopen), and SDL is quite adaptable to different versions of certain binaries. So, in short, if you compile in a system with certain versions of libc, libpthread, etc and manage to find a different system with compatible binaries, you have a good chance that the SDL binary will at least run. In practice, you are better off depending on the system provided binary, or accept that you'll be supporting a limited set of distros with your custom made SDL2.

    Note that this limitation also applies if you link SDL statically! And if you think you can keep on adding statically linked binaries until you've made a static ball of several hundred megs that runs anywhere (like I did!), there's other limitations that prevent you from doing that, ranging from licensing issues to segfaults due to linking libpthread statically.