Upcoming Events
Workshop on Network and Systems Support for Games (NetGames 2009)
11/23 - 11/25 @ Paris, France

LOOP 2009
11/26 - 11/29  

EVA 2009
12/4 - 12/5 @ Buenos Aires, Argentina

ICIDS 2009 Interactive Storytelling
12/9 - 12/11 @ Guimarães, Portugal

More events...


Quick Stats
6787 people currently visiting GDNet.
2341 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!



Link to us

Link to us

  Intel sponsors gamedev.net search:   

Linux Game Development Part 2
Distributable Binaries


The Solution: Steps 1-2

Most of this information came directly from Gerry Jo Jellestad, so I would like to take this opportunity to publicly thank him for it. Without his assistance, I could never have finished the Linux version of Dirk Dashing.

There’s a lot of information to cover here, so let’s get started.

Step 1: Statically Link Everything Possible

If you statically link a library with your application, then you don’t have to worry about any dependency issues with it. Dirk Dashing, for example, uses Ogg/Vorbis for its music, and the license for the Ogg/Vorbis libraries allows for static linking in commercial applications. Unfortunately, the licensing for other libraries like SDL and OpenAL require you to open your source code if you statically link them into your program. If you’re not willing to do that, then you must link these libraries dynamically. So proceed to step 2.

Step 2: Identify Your Remaining Dependencies

Before we can go any further, the first thing you need to do is to find out all the dynamic libraries that your application is dependent on. I’m sure you’re thinking to yourself, “That’s easy - just look at the link line.” But hold on a second, the game libraries themselves might be dependent on other libraries that you don’t necessarily know about (because you’re not linking against them directly). You will need to resolve all of these dependencies yourself, if you’re going to build an executable that will run on any distribution.

Here is a handy-dandy little tool that is invaluable for this task: objdump. It’s probably already installed on your Linux system. If you type in

  objdump –x your-exe
it will show you a lot of useful information about your program. For example,
  objdump –x dirkdashing | grep NEEDED
will show the libraries *directly* required by my Dirk Dashing executable. Here was the output when I ran it on v1.02 of the executable:
  NEEDED      libSDL-1.2.so.0
  NEEDED      libGLU.so.1
  NEEDED      libGL.so.1
  NEEDED      libalut.so.0
  NEEDED      libopenal.so.0
  NEEDED      libboost_filesystem-gcc.so
  NEEDED      libpthread.so.0
  NEEDED      libstdc++.so.6
  NEEDED      libgcc_s.so.1
  NEEDED      libc.so.6
  NEEDED      libm.so.6
Some of the libraries listed here are low-level or system-specific, and including these libraries with your application will often lead to problems. So let me point them out to you.
libc and libm are part of glibc, the C library. They are not on my link line, and probably won’t be on yours either; the linker automatically pulls these in. libc consists of general C library functions, and libm contains math-specific C functions. Both of these are pretty much guaranteed to be present on any Linux system, and their version has been fixed for a very long time, so you can count on them being compatible.

libpthread is also part of glibc and provides threading support. Technically, it is an optional library, but every distribution includes it because if they didn’t there would be problems. This library, too, has been fixed at its current version for a very long time, so you can rely on compatibility with it as well.

libgcc is part of the GNU Compiler Collection (GCC), and it contains a number of internal subroutines that GCC uses to overcome any shortcomings on particular machines. This library isn’t on my link line either. libgcc generally provides for backward compatibility, so you can rely on it too.

libGL and libGLU are the OpenGL libraries. They are highly system-specific, so you definitely should not include them with your application.

libstdc++ is not system-specific, but it is up to you whether or not you want to include it with your application. It will probably be installed on your end user’s system, but it might be an older version (although, it has been awhile since it was last updated, so you could choose to ignore it). To be on the safe side, I chose to include it with Dirk Dashing, and I’ve noticed that other commercial games (like DROD from Caravel Games) do too.

libdl is another common library that isn’t on the dependency list for my particular executable, but since we see it later in this article I want to cover it here. libdl is used for dynamic linking of libraries at runtime, and it is another low-level library that is always available and compatible. It shouldn’t be included with your application either.

To summarize, don't worry about these low-level libraries. They're pretty much always available and compatible, as long as you make sure to not use any newer symbol versions than the oldest glibc you want to support. One other thing I should point out: don't statically link these libraries into your program.

The rest of the libraries listed by objdump are probably ones you recognize as standard development libraries. The list will probably be different for your game, depending on which libraries you use. Regardless, these are the libraries you need to look at in more detail. These libraries may or may not exist on a given Linux system, and even if they do exist, they may not be the version your game needs.

You can use the same objdump command above to look at the dependencies for each of the dynamic libraries. For example, when I run it on the OpenAL library provided in SUSE 10 (which is the distribution I originally used to develop Dirk Dashing), I get this output:

  NEEDED      libdl.so.2
  NEEDED      libm.so.6
  NEEDED      libpthread.so.0
  NEEDED      libasound.so.2
  NEEDED      libartsc.so.0
  NEEDED      libgmodule-2.0.so.0
  NEEDED      libgthread-2.0.so.0
  NEEDED      libglib-2.0.so.0
  NEEDED      libesd.so.0
  NEEDED      libaudiofile.so.0
  NEEDED      libSDL-1.2.so.0
  NEEDED      libvorbis.so.0
  NEEDED      libvorbisfile.so.3
  NEEDED      libc.so.6
This library has a lot of problems. First, look at the long list of dependent libraries. If I ran objdump on every one of these libraries to find all of their dependencies, and then ran it on those libraries, and so on and so forth, I would end up with a huge list of dynamic libraries that I would have to bundle with my application. The size of the download file for my game would be pretty big. Second, the library depends on a lot of glib stuff - not glibc, but glib, which is the low-level library that forms the basis of GTK+ and GNOME. Not all distributions use GNOME, but for those that do, I could cause problems by including the SUSE 10 version of this low-level library with my game. Third, the library depends on ALSA, arts, and ESD, which are low-level audio libraries and could also be problematic to bundle with my game.

Now, I can almost see the look of despair on your face as you’re starting to understand the seemingly daunting task before us. But don’t worry, because the solution is very simple. Here’s the bottom line: you should never bundle a pre-built library with your application, because you don’t know how it was built or why it was built the way it was. Instead, you should build your own custom version of the dynamic libraries that you use. The goal is to strip off all the dependencies that you don’t need, and to deliver a small, streamlined version of each library with your game.



The Solution: Steps 3-4

Contents
  Introduction
  The Problem
  The Solution: Steps 1-2
  The Solution: Steps 3-4

  Printable version
  Discuss this article

The Series
  Part 1: Introduction
  Part 2: Distributable Binaries
  Part 3: Installers
  Part 4: Testing
  Part 5: Marketing and Distribution