Search code examples
c++linuxsdlsdl-2sdl-mixer

Cutting dependencies


I'm writing a small game in C++ using SDL2/Box2D/OpenGL (plus SDL2 extensions SDL2_mixer and SDL2_ttf). Since I'm approaching version 1.0, I've been thinking about distributing the game, and I just found out that my game has some unexpected dependencies.

Apparently SDL2 is pulling in dependencies like libjson (Why would SDL need json?) while SDL2_mixer pulls libglib in. Those are the strangest in my opinion, but there's a whole lot more. SDL2, and not SDL2_mixer, is pulling in libFLAC for example. There are also dependencies like libpng, libmad, libvorbis, etc. the functionality of which I'm sure I'm not using.

Do I need to include all those dependencies in order to have a faily self-contained game? What's the best way to cut the number of dependencies to the absolutely barest minimum?

This is the complete output of ldd:

linux-vdso.so.1 =>  (0x00007fff19ee0000)
libSDL2-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (0x00007f562ede5000)
libSDL2_ttf-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libSDL2_ttf-2.0.so.0 (0x00007f562ebdd000)
libSDL2_mixer-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libSDL2_mixer-2.0.so.0 (0x00007f562e98d000)
libGL.so.1 => /usr/lib/nvidia-304/libGL.so.1 (0x00007f562e670000)
libGLEW.so.1.10 => /usr/lib/x86_64-linux-gnu/libGLEW.so.1.10 (0x00007f562e3e4000)
libSOIL.so.1 => /usr/lib/libSOIL.so.1 (0x00007f562e1cc000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f562dec8000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f562dbc2000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f562d9ab000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f562d5e5000)
libasound.so.2 => /usr/lib/x86_64-linux-gnu/libasound.so.2 (0x00007f562d2f5000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f562d0f0000)
libpulse-simple.so.0 => /usr/lib/x86_64-linux-gnu/libpulse-simple.so.0 (0x00007f562ceec000)
libpulse.so.0 => /usr/lib/x86_64-linux-gnu/libpulse.so.0 (0x00007f562cca3000)
libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f562c96d000)
libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f562c75b000)
libXcursor.so.1 => /usr/lib/x86_64-linux-gnu/libXcursor.so.1 (0x00007f562c551000)
libXinerama.so.1 => /usr/lib/x86_64-linux-gnu/libXinerama.so.1 (0x00007f562c34d000)
libXi.so.6 => /usr/lib/x86_64-linux-gnu/libXi.so.6 (0x00007f562c13d000)
libXrandr.so.2 => /usr/lib/x86_64-linux-gnu/libXrandr.so.2 (0x00007f562bf33000)
libXss.so.1 => /usr/lib/x86_64-linux-gnu/libXss.so.1 (0x00007f562bd2e000)
libXxf86vm.so.1 => /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007f562bb28000)
libwayland-egl.so.1 => /usr/lib/x86_64-linux-gnu/libwayland-egl.so.1 (0x00007f562b926000)
libwayland-client.so.0 => /usr/lib/x86_64-linux-gnu/libwayland-client.so.0 (0x00007f562b718000)
libwayland-cursor.so.0 => /usr/lib/x86_64-linux-gnu/libwayland-cursor.so.0 (0x00007f562b510000)
libxkbcommon.so.0 => /usr/lib/x86_64-linux-gnu/libxkbcommon.so.0 (0x00007f562b2d6000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f562b0b7000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f562aeaf000)
libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f562ac0b000)
libmodplug.so.1 => /usr/lib/libmodplug.so.1 (0x00007f562a93c000)
libfluidsynth.so.1 => /usr/lib/x86_64-linux-gnu/libfluidsynth.so.1 (0x00007f562a666000)
libvorbisfile.so.3 => /usr/lib/x86_64-linux-gnu/libvorbisfile.so.3 (0x00007f562a45e000)
libFLAC.so.8 => /usr/lib/x86_64-linux-gnu/libFLAC.so.8 (0x00007f562a22c000)
libmad.so.0 => /usr/lib/x86_64-linux-gnu/libmad.so.0 (0x00007f562a00d000)
libnvidia-tls.so.304.117 => /usr/lib/nvidia-304/tls/libnvidia-tls.so.304.117 (0x00007f5629e0a000)
libnvidia-glcore.so.304.117 => /usr/lib/nvidia-304/libnvidia-glcore.so.304.117 (0x00007f5627a1f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f562f116000)
libpulsecommon-4.0.so => /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-4.0.so (0x00007f56277b8000)
libjson-c.so.2 => /lib/x86_64-linux-gnu/libjson-c.so.2 (0x00007f56275ac000)
libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007f5627367000)
libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f5627148000)
libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007f5626f3d000)
libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f5626d37000)
libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007f5626b2e000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f5626915000)
libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f56266ef000)
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f56263e6000)
libjack.so.0 => /usr/lib/x86_64-linux-gnu/libjack.so.0 (0x00007f562618d000)
libsndfile.so.1 => /usr/lib/x86_64-linux-gnu/libsndfile.so.1 (0x00007f5625f25000)
libreadline.so.6 => /lib/x86_64-linux-gnu/libreadline.so.6 (0x00007f5625cde000)
libvorbis.so.0 => /usr/lib/x86_64-linux-gnu/libvorbis.so.0 (0x00007f5625ab1000)
libogg.so.0 => /usr/lib/x86_64-linux-gnu/libogg.so.0 (0x00007f56258a8000)
libwrap.so.0 => /lib/x86_64-linux-gnu/libwrap.so.0 (0x00007f562569d000)
libasyncns.so.0 => /usr/lib/x86_64-linux-gnu/libasyncns.so.0 (0x00007f5625497000)
libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f5625292000)
libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f562508c000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f5624e4e000)
libvorbisenc.so.2 => /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x00007f562497e000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f5624755000)
libnsl.so.1 => /lib/x86_64-linux-gnu/libnsl.so.1 (0x00007f562453a000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f562431f000) 

Solution

    1. If you are going to distribute the game as a binary image (rather than source), then use static linking instead of dynamic linking. Only a few libraries should be dynamically linked after you make this switch, including linux-vdso and libc. Note that statically linking also makes distribution simpler, as you can avoid the linux version of DLL hell.

    2. Switching to static is probably going to explode the size of your binary, which may be a problem. If it is, I recommend compiling each package from source on your own because you will then be able to disable optional features you don't need, thus reducing further the number of dependencies you have and therefore reducing the size of the resulting statically linked binary.

    3. If you don't get the reduction you need from the previous step, you can also modify the source of the libraries you're depending on to remove the unnecessary code. This step is more time consuming than 2 so only do this if necessary.