Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: distributing SFML projects on Linux (binaries)  (Read 11831 times)

0 Members and 1 Guest are viewing this topic.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: distributing SFML projects on Linux (binaries)
« Reply #15 on: February 15, 2015, 12:15:48 pm »
First of all: Linus rants about shipping applications on Linux desktop:


This is the divers app he is talking about (compare the download options for Mac, Windows and Linux users...): http://subsurface-divelog.org/download/



(In case you don't want to read through the rant, the quick help list is at the end).
(Also, this is a complex issue - I might be wrong at times).
(Also, I'm a bit biased talking about Lua and Red Hat based distros since I use Fedora and used CentOS for a short while and Lua is one of most interestingly problematic libs in terms of shipping stuff that I ran into so far).
Second: I rant about shipping applications on Linux desktop:

Basically: it's impossible to get 101% right.
You use dynamic libraries: bitness, ABI or missing libs get you.
You use static libraries and set the environment to use own .so: it's kind of OK actually... but it doesn't use the InfinitePowerOfDynamicLibraries(tm). And might be illegal without making your entire app LGPL along with it (OpenAL, libsndfile, etc.) :(


There is a bunch of fun problems with dlls (by that I mean dynamic libs, not the Windows .dll format itself, I know, the format is .so on Linux) on Linux:
1. ABI
2. Versions/'configurations'
3. Names
4. Missing stuff

Let me explain them all:
ABI is simple - ABIs change often between releases of less 'core' libs ie.: Lua 5.1 is not ABI compatible with 5.2, Fedora 20 ships 5.1 and links liblua.so to it, Fedora 21 does the same with 5.2 and 5.1 is now compatibility, RHEL and CentOS 6 and 7 ship 5.1 - have fun linking your app dynamically to liblua.so, it links to one of two incompatible libs depending on distro relase/version, and that is inside a single distro tree (RH), without even going into Debian, Arch, Suse or more exotic systems like Oralce Linux and so on. Of course this doesn't affect XCB, GL, libc, etc. (This - the change of what is behind the symbolic link - is more of an issue in compiling and runtime linking actually, compile time dynamic linking doesn't get affect by it, but it then gets affected by 3. possibly).

Versions/'configurations' - this is a bit more subtle (but even more dangerous). Libraries have build configs, SFML has almost none so yay. Worst is configs that violate ABI and that cut into feature set (SFML itself has 0 of that). Even if there is no ABI incompatibility you risk that your program will not work because some part of feature set is just missing/replaced with stubs.
Examples:
1. Fedora didn't enable Eliptic Curves in OpenSSL - patent issues. This broke (for example) BitCoin apps so you have to build yourself or add a special, unofficial repo to package manager that doesn't fear patent litgation and download your bitcoin app from there, it will pull in a completely separate OpenSSL lib binary built with EC in it, named differently. Problem solved - kind of - any app that comes to your system and thinks that normal OpenSSL has EC will break (I actually had this happen to me on certain experimental mail client app).
2. Lua again, it can be built with a lot of configuration options (none actually make sense for common usage IMO), LuaJit even more so (and here it makes sense, the 5.2 compat flag in particular).

Names - this is a bit connected to 2., like the issue of EC capable OpenSLL being named differently and no one knowing that. Basically - you have no guarantee what the dynamic lib will be named on the target system. Standard libs have obvious-as-hell names but the more rare ones might differ, and given that there is probably close to dozen or two 'popular' distros (and their versions, since versions can vary wildly) you might want to carter to, you are taking a big risk.

Missing stuff - simple, user might not have ability to install what you need easily: F20 has no Lua 5.2, F21 has no Lua 5.3, RHEL/CentOS 7 has no Lua 5.2 and OpenAL(!).
It probably IS possible after adding more repos to package managers (EPEL and nux for RHEL/CentOS, rpmfusion for Fedora, etc.) and by manual compilation but it's hard to require either of your user. Also, not everyone might want to install Mono (quite a big/convoluted lib..) or something just for your one app. We are going for the instant fun experience here... like there is on Windows (or with Unity...).


You mention Unity - it cheats around the problem with mix of static and dynamic and it's kind of good solution actually, what Unity built Linux binary is doing is:
1. Link everything statically  to the executable (you can find PhysicsSDK, Box2D and OpenSLL in it, possibly more).
2. Bring own libmono(!) and a bunch of managed libraries (these are 100% cross platform).
3. Link only bare minimum to your dynamic libs and your executable: libc, opengl, xcb, etc. that is sure to be ABI compatible.
4. Be 32 bit to not lock out 32 bit users (it forces 64 bit users to install 32 bit libraries of all the stuff from 3. I think... I have 32 bit system so I don't know) .

This is what I gathered from looking at binaries of just from 2 games on gamejolt so take it with a grain of salt...


So, given all these problems, incompatibilities, traps and possible missing stuff I made a set of rules I'd go by if I ever tried to ship a Linux binary.

0. Acknowledge that this is MY list, that it might be WRONG or INCOMPLETE since I'm not the Linux-Native-Apps-Guru-Of-All-Time.
1. Go 32 bit (or both) to not lock out 32 bit users, if you don't go both you will have to make 64 bit people install 32 bit version of few libs you rely on.
2. Link everything you legally and technically can statically.
3. Bring your own dlls for all else except sys libs and use a bash script to start your game with them.
4. Use just the most basic libs in the system - gl, xcb, libc, etc.
5. Bring all own scripts/managed libs (mono dlls, lua and python scripts, etc.) - don't trust that users will have them - they won't.

In terms of SFML: go 32 bit (or both), build it fully statically (except for the two dlls of audio), link it statically to your executable and bring your own dlls for OpenAL and libsndfile and launch via a bash/sh script that sets the environment variable for ld.
« Last Edit: February 15, 2015, 05:42:34 pm by FRex »
Back to C++ gamedev with SFML in May 2023