Building Distributable Linux Binaries?
Grubby Games asks: "I make games for a living, and I want to ensure that my games will run on as many Linux distros as possible. However, since I distribute binary game executables, the programs often fail to run on certain distros because of missing dependencies, and so forth. So, how do the Slashdot Linux gurus handle this situation? I've heard a number of theories on the subject, but have yet to find one that results in 100% cross-distro compatibility. Is it even possible, short of distributing source code?"
Java and Python are obvious. You can always use things like JNI and the Python-C bridge if you feel you need better speed in some parts. As long as those parts don't link to any external code, you won't have any problem. They are both very fast these days, and by using things like PyOpenGL and Java3D you can get accelerated rendering and everything. Plus you would only need one codebase for both windows, linux, and OS X.
As for a static build, you may or may not want to do that. The size of the executable will be much larger, and it will take more memory to run, but you won't have the problem of everyone has a different version. It would solve your problem.
As an odd suggestion: why not build all your code into objects and distribute those with a little script to link them on the client machine into an executable. That would fix the problem right? The problem is you couldn't strip the binary (if you do that) because the linker needs the symbols (right?). But it would solve you problem. This is my understanding of how nVidia's kernel drivers work (they have a little glue source too, which you could include). This way they don't have to put out a version for every combination under the sun.
I hope this helps. This is one area where Linux is (rather far) behind Windows and OS X. It's not much of a problem if you've got the source, but if the application is closed source (like yours) then it can be a headache. This is something that the LSB was trying to solve, but I don't know how far they got (or how many distros follow their guidelines).
Comment forecast: Bits of genius surrounded by a sea of mediocrity.
If you absolutely can't have the source to your app open, you could do like the developers of binary kernel modules: ship your software in object format, with all the parts that interface with the rest of the system open source. That way, people can't read your actual application source, but they can compile and link the glue layer to make your code work on their system.
If you take this approach, be _very_ careful to have _everything_ that interfaces with the outside system in the open source part; I've worked with kernel modules where some OS calls were still made from inside the binary part, and they were hell.
Please correct me if I got my facts wrong.
I'd suggest doing a bootable CD. You can have total control, then. In my limited experience, gamers are typically not too disturbed by having to do a reboot to get to their game.
http://tinyurl.com/4ny52
``100% cross-distro compatibility. Is it even possible''
In a word, no. Binary compatibility just isn't. It happens to work in very select situations, usually on proprietary operating systems that are themselves binary-only, which means the developers of the OS would be dealing with the same headaches you would if they broke binary compatibility.
On Linux, where binary compatibility has very low priority because _everything_ on the system works fine without it, binary compatibility happens only by accident. It starts with the fact that Linux runs on many architectures, and people actually use it on most, if not all, of these architectures.
Then there are distributions that are still using libc5. Think they don't matter? What happens when libc7 comes out? And if you think that isn't going to happen for a long time, how about when X.org replaces the monolithic structure they inherited from XFree86 by their new, modular one? Or how about when Qt 4 replaces Qt 3, or GNOME 3 is released? These projects are not going to let themselves held back because of your app. Because this is what binary compatibility means: slowing progress, because some changes become impossible.
Please correct me if I got my facts wrong.
Gamers shouldn't condescend so much to the casual gaming market, and certainly not their developers. These guys are living the dream, after all (and realizing the dream means coding down in the trenches). Power to you, Linux-supporting casual gamer guy.
Help poke pirates in the eyepatch, arr.
For regular binaries, a static build is pretty much guaranteed to work. Alternatively, all Linux distributions I know of do honor the LD_LIBRARY_PATH environment variable. Create a library directory on the target computer, then test the libraries already installed. If the ones you want are either not there or the wrong version, copy the ones you have on the CD into the library directory and have that directory searched BEFORE the default system library directories.
If using custom versions of standard libraries, use a chroot jail to guarantee that the program cannot see the regular library directories.
If you don't actually need standard functions at all, but use your own routines and maybe some system calls, then there's absolutely no problem - just remember that when you compile, you want to PREVENT GCC from linking in the C library. Rescue tools, installers and other components that have to run PRIOR to being able to check versions, etc, should either be statically linked OR not linked at all.
If you want to avoid including stuff that might not be necessary, then you can use yet another technique. Write a "loader" program and include that as source. All the loader does is dlopen() the application (which is now written as a shared library, not an executable) and start it up.
This technique works by linking to the installed libraries in the wrapper, and then when you dlopen() the application, the application can then access the linked libraries. The linking is entirely done in the wrapper, which would always be compiled for the local system.
This technique would only work if all the required libraries are present, and the parts of the API that are used are present and the same. If you write to the libraries which are damn-near universal, then this will work. If you are writing to libraries which are not universal, then you would still have to do the whole process of checking and installing your own libraries, then setting the LD_LIBRARY_PATH. In which case, don't bother with the wrapper and just do that for all libraries.
A final option is to provide TWO programs. The first program assumes nothing about the native system and doesn't do any checks at all. It just installs everything it needs in local directories, sets all the paths as needed, and runs in its own corner.
The second program would be a clean-up program. It has a list of applications it knows about, what versions of what libraries are needed, etc. It would pull libraries that are not system-wide into a standard set of directories, then use symlinks or LD_LIBRARY_PATH to repoint applications to where the libraries are. It would also need two additional capabilities - deinstalling libraries when NO application still installed uses it, and updating records (and shuffling links as needed) when an application is updated.
The reason for the second program is that many developers (especially commercial vendors) have the same problem. If a standardized mechanism existed for library tracking, with a well-known API, I believe it would become very popular very quickly. If such a program were developed, and was sufficiently widely adopted, you could abandon system-wide libraries altogether. Which would be no bad thing, as the existing system has problems with multiple versions and will also fail when libraries have the same filename. It's also slow when you've a lot of libraries installed.
By creating virtual directories, in which the ONLY libraries present are ALL that the application needs, you eliminate not only the application/library issue, but al
It's a small world and it smells funny; I'd buy another if it wasn't for the money; Take back what I paid (SoM)
If you're making games, it's usually a good solution to make the game engine open source, and charge for the data.
(ppffftttt) Milk just shot out of my nose (and I'm not drinking milk).
The real value of a game tends to be in the data files
Wipe the drool from your chin before posting, please. Do you know how brutally retarded you sound? Take any commercial game company. For example:
"John Carmack - your Doom 3 engine is merely a 'playback library', the real value here is in the 'data files' (snicker)".
"Rockstar - your Grand Theft Auto engine may not be entirely YOURS since you licenced the RenderWare 3D engine to build your game, but give me the source to it anyway."
"Blizzard - your World Of Warcraft engine is merely a 'playback engine', there's absolutely no danger of people having an easier time trying to cheat if they have the source code."
Of course, not all games work like this
Err.. how about none worth playing work like this?
Brutally. Retarded. Is. You. So quit whining about not having games on Linux when you expect source code.