Whoa, lots of replies. I'll try to reply to everyone, let me know if i missed something..
First off, one important thing that i forgot to mention before, and that is if you do decide to compile your own versions of libraries, be careful that you include support for everything you need! Specially if you're building SDL, make sure that your build environment supports
all the audio drivers and that SDL is configured to support them as an option, since eg not supporting pulseaudio may mean no sound on systems that use that. Fortunately SDL supports loading the low-level audio libraries dynamically at runtime (dlopen), which is ideal: Your SDL library supports all the audio drivers, but doesn't
require any of them. (For this reason it may be best to go with pre-built libraries of at least low-level stuff like SDL whenever you can, unless you really know what you're doing.)
Also, this is probably obvious, but don't include system-dependent driver libraries like alsa or opengl with your game. (This is why loading them at runtime is good, since they might not be there, and you don't want to require them but still want to support them if they're there.)
Do you have any similarly useful advice for packaging? E.g. making something like a .deb instead of a .tar.gz
I haven't done a lot of packaging myself, so i don't have a lot of experience with it, but it is something i've been meaning to look into. Packages make things easier to install for the end user (well, assuming they've got permissions to install stuff), so i think it's definitely a good thing to do if you've got the time. However, package dependencies are very distro-dependent, so i think the best way to treat them is as just another distribution method. You'd do everything i talked about before, include all dependencies in the package and all that, and then just make the package have no dependencies and install everything to a single subdirectory somewhere in the file system. Somewhere under /opt or /usr/local would be my first choice, but these directories are usually considered safe from meddling by package systems, so it'd probably have to be somewhere under /usr/share in stead. A symlink to the executable could be put in /usr/bin, and you could use
the xdg-utils to install/uninstall desktop menus and icons. (Note, i'm not saying this is the best way, just one possibility. Some more research about how packages usually do things would probably be a good idea.)
Including libraries is never a good idea. Windows' poor library model makes this an unfortunate necessity for that OS, but it's a terrible habit.
No, it's a necessity, and this has nothing to do with the library model. Fact is that your game may depend on libraries that are not installed everywhere, and even if they happen to be installed they might be different, incompatible versions, or buggy ones. Even taking something as ubiquitous on linux as SDL, 32-bit versions of SDL may not be installed on 64-bit distros, and now that 1.3 is coming out soon packages built from source are likely to change to that, since it's source compatible -- but it's not binary compatible. It's also not free from bugs; for example, SDL version 1.2.8 had a bug that prevented surfaces higher than 16383 pixels from working, breaking some games that depended on very high surfaces. There's also some libraries that are very picky about which versions of other libraries they can work with. It's a mess, really, and you
can't rely on distros to resolve these things for you, both because there's so many different distros out there that you'd never realistically be able to support them all, and also because even common distros like Ubuntu ship broken stuff from time to time. Not universally broken since they do tend to test that their stuff works, but your game may trigger rare or unknown bugs.
This isn't just theory btw, this actually happens. I've had mystifying bug reports for things i've worked on that was a direct cause of users who "knew better" removing the supplied libraries to use the distro provided ones in stead. Things like graphical artifacts, fonts not rendering correctly, distorted sound, or even data corruption and crashes, that magically went away when the supplied libraries were used in stead.
Linux users expect to have to resolve dependencies and obtain the required libraries.
You're generalizing, and besides, what people expect and what they'd actually prefer can be very different things. Sometimes they just want to play a game.
Linux releases are generally done as source, and users compile it themselves, or you find someone to make packages for various distros.
Linux is not only for open source stuff, and for closed source games the way i describe is usually the way it's done, because it works, you can support pretty much everything with only one build, and you don't have to rely on unpredictable distros not to break your game.
Even
if the source is open though, i think it's a nice thing to do to provide binaries so that people don't have to go through all the mess of compiling, resolving dependencies, dealing with compiler differences and all that, unless they really want to.
Linux distros are completely different operating systems. They share a common kernel and a lot of the same software, but they all expect software to come a specific way, and barring that, they expect source. If you make packages, you don't need to release source.
Distros are different, yes, but that's exactly the point. Package dependencies are also distro-dependent, so if you rely on a distro's package system to resolve dependencies for you, you have to make different packages for every distro you want to support, and leave all the rest unable to install your game, assuming the distros you want to support even have packages for everything your game depends on (which you can't really rely on). You could of course choose some popular distros to support directly with distro-specific packages and provide a generic solution for the rest, but this can quickly become a maintenance nightmare as you have to keep up with all the little things distros do that have an effect on your game. And if you
don't rely on the package system to resolve dependencies for you, the package becomes just another distribution method, like i talked about above.
Most Linux users I deal with (myself included) prefer to build from source, and on my distro (Slackware) that's often the preferred method for installation. We must be hanging around different Linux users.
I like having the option of building from source for some things, but this is
games we're talking about here. They're not essential system components, and they're usually built to work just one way, without lots of compilation options that change how they work (except for debug modes and publisher-specific versions and such, but as a player you wouldn't build those from source anyway). You don't have to be a system administrator to know how to download and play a game.
Besides, if the provided binary works fine anyway, what's the point of building from source? Bearing in mind you have to resolve all dependencies and other issues that come up and may run into compatibility issues, it doesn't really strike me as something i'd do "just because".
The whole point behind libraries is that multiple programs can use the same object code. Distributing them with your program defeats that entire purpose.
It's one point, but it's not the only one or even the most important one imo. Libraries are good for code reuse, cross-platform wrappers of system-specific interfaces and such, not having to write everything from scratch yourself, etc, all of which are good to have even without object reuse. That said, object reuse would be great if you could rely on distro provided libraries to actually work with your game. Which you can't.
mjau's post makes good points but glibc doesn't always break with never versions.
I have binaries that works since ubuntu 7.04 on ubuntu and fedora machines.
I think you misunderstood. The problem is that building stuff against very recent versions of glibc means that they might not work on
older versions of glibc, because they need more recent symbol versions. They'll work fine on newer versions. It's only really an issue if you want to support distros that use an older version of glibc than the one you're using to compile your game. Not everyone is good at keeping their distros up to date, and some distros are eager to use the latest bleeding-edge glibc, while others are more conservative and stay with old and thouroughly tested versions for long periods. For example, the latest version of glibc right now is 2.11.1, but the latest stable version of debian uses glibc 2.7. The one before that used 2.3.6. Ubuntu 9.10 uses 2.10.1.
also, if you use SDL and OpenGL it will even get easier since SDL is almost always backward compatible and every popular distro comes with it preinstalled.
Unfortunately even SDL isn't immune to bugs and incompatible versions (may be too old or too recent), or even from missing entirely (32-bit libs on 64-bit).
The right way isn't always the easy way.
As far as i'm concerned, the right way is to give the end user a game that actually works on his/her system, preferably with a minimum of fuss on their part. You as the developer might have to work a little harder to make this happen, and that's ok as long as it stays within reason. Having to keep up with the whims of every distro out there is not very reasonable though, things would keep breaking and even at best it'd be a constant annoyance distracting you from other things. The alternative: make it distro-independent and stand-alone. You're happy because you don't have to worry about how distros will break things next, and the player is happy because the game keeps working. Everybody wins.
http://icculus.org/mojosetup/it's a setup tool for linux used by ports of big titles. it's actively developed by Ryan "icculus" Gordon who is also one of the SDL developers. it's worth a try.
Yeah, mojosetup is excellent if you want to provide an installer that works everywhere. It's really easy to set up, too. (It's still in development and doesn't directly support some useful stuff like installing menu items and such, but you can do that manually with eg xdg-utils if you want.)
edit: i don't know if mojosetup supports it but, nowadays every popular distro comes with packagekit preinstalled which is a service daemon that interacts with the native package manager of the distro. basically, you can tell the distro to install libsdl (for example) if it's not installed with a few lines of code. i think it can be easily implemented to a setup tool. this way developers would have to worry about only one package and still use dependency checking of the distro's native package manager.
Haven't actually heard of this before, but it does sound interesting. The distro i'm on atm (arch) doesn't have it though (but arch has its own package system and isn't based on rpm or deb). How does it tackle the various distros' different naming conventions and custom versions and such?
Anyway, even if this worked and was truly ubiquitous i don't know if i'd use it, since this still doesn't guarantee that the particular version of a library that you want is available in a particular distro's package system, and even if it is distros like to patch libraries in their own little ways and may introduce bugs. (I know i sound paranoid here, but believe me, it's warranted.)
As long as a Makefile is provided, it is really easy. This is usually the way it's done:
Done. Still, though, I would obviously prefer something pre-compiled.
Sure, assuming that the source is available in the first place, and that the build system actually uses autoconf, which is almost universally despised these days, and assuming you've already got development versions of all the required libraries installed (and of course all
their dependencies and so on), and that they're all the right versions and compatible, and also assuming that the particular defines the code uses plays well with the headers it includes and that the code even compiles with your compiler (usually the case, but gcc likes to change things up now and then, and there's also alternatives like icc, llvm-gcc and clang to keep things interesting).
If the game isn't too picky and you're on a dev system you're probably ok, but not only developers like to play games. Point is, while compiling is usually simple enough, there's
a lot that can go wrong.