1

What binary files I have to ship with my SDL2-based program so it can works on another computer without SDL installed?

Libraries required for my program:

iostream
SDL2/SDL.h
SDL2/SDL_image.h
ctime
cstdlib

Binary files which I already tried to use:

libSDL2.so
libSDL2-2.0.so.0.8.0
libSDL2_image.so
libSDL2_image-2.0.so.0.2.1

PS: I'm testing whether my program package works or not with a bootable Xubuntu pen drive

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
isocppforbids
  • 389
  • 1
  • 12

1 Answers1

2

The short answer is "use ldd". The long answer follows.

ldd ./your_program will show recursive list of all runtime dependencies (yours and dependencies of every library you use, and their dependencies, ...).

readelf -d ./your_program | grep NEEDED will show your direct dependencies (only ones your program actually links against - doesn't necesserily mean you can copy only those).

LD_DEBUG envvar could be utilised to trace what libraries are loaded at runtime (e.g. with dlopen).

If you target one specific distribution it may be siplier to build package with dependencies specified so e.g. apt would install SDL for you.

Next big question is where did you get your SDL. Many distributions disables SDL dynamic loaders so it wouldn't run without e.g. libX11, wayland, libXi, pulseaudio, ... It is very much ok for that distribution to do so, as it was never intended you'll just copy some libraries to another machine. If you build it yourself you can have much less direct dependencies and SDL will try to dlopen whateven it needs. SDL2_image is probably easier example - it could depend on libjpeg, libpng, libz, ..., it is possible you don't need some formats but if you have linked with that libraries you can't run without them.

Consider what libraries you could consider 'always there'. E.g. it makes no sense to carry libX11 or libc and many others. This part is shared for all OS - you can't get half of OS with your program, for multiple reasons.

To sum it up, use SDL build with dynamic loading enabled (I think it is default for quite a time now), copy SDL/SDL_image, use LD_LIBRARIES_PATH to set your libs location, verify list with ldd, and you should be fine. Do not copy libc, libstdc++, libpthread, libm.

keltar
  • 17,711
  • 2
  • 37
  • 42
  • Firstly, thank you so much for the answer. When I used ldd ./my_program it showed me a lot of libraries. If I put those libraries and my program in the same folder, will my program run? – isocppforbids Jan 18 '20 at 13:31
  • `readelf -d ./your_program | grep NEEDED` showed me this: `0x0000000000000001 (NEEDED) Shared library: [libSDL2-2.0.so.0] 0x0000000000000001 (NEEDED) Shared library: [libSDL2_image-2.0.so.0] 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]` – isocppforbids Jan 18 '20 at 13:47
  • First you don't make anything run by just putting libraries beside it as this is not the place where dynamic libraries are searched for. You'll need e.g. a script with `LD_LIBRARY_PATH="$PWD" ./your_program` to inform dynamic linker where to look for libraries (there is other way, but I'm not going to mention it) which will be used to launch your program. Second is you *really* don't want to get too many libraries; you don't need libc, libstdc++, libdbus, libpthread, libdl, because if your target system runs graphics is have to be there anyway. – keltar Jan 18 '20 at 14:02
  • I'd also recommend building SDL/SDL_image yourself as whatever your distribution have is targeted specifically to that distribution and never intended to be used anywhere else. This is one of reasons why you have very long `ldd` output - check `ldd /usr/lib/libSDL2.so` and if you see more than 5 libraries it most likely could be reduced by custom build even with default parameters. But you still need to check if it is running on reference system (e.g. just recently installed system without any extra libs). – keltar Jan 18 '20 at 14:04
  • Do you know a tutorial explaining how make that script? I was trying to run my program in the terminal ('./myprogram'). I never used a script to launch a program. In 'LD_LIBRARY_PATH="$PWD" ./your_program', does the 'PWD' mean the directory? – isocppforbids Jan 18 '20 at 17:45
  • something something [rpath $origin](https://stackoverflow.com/questions/42344932/how-to-include-correctly-wl-rpath-origin-linker-argument-in-a-makefile) – genpfault Jan 18 '20 at 17:46
  • @d.olinger sorry I don't. `$` in shell is "get value of variable". `PWD` is builtin variable containing current working directory, same as `pwd` command output. Note that "directory where script is placed" and "current working directory" are very different things. You can look at launch script in many big programs for linux (e.g. maya) or most of steam/gog linux games. – keltar Jan 19 '20 at 05:58
  • 2
    @genpfault and now the thing I specifically didn't want to mention is here :-D. That's possible solution, but it complicates things, makes it harder to debug or reason about. The problem with bringing up rpath is people who never used it often think "this solves my every problem, best thing ever", and now they have different problems that are probably harder to solve. But yes, it's good to know it exists, so thank you. – keltar Jan 19 '20 at 06:05
  • When I build SDL2 from source in my Ubuntu 20.04 machine I get a very small ldd output which is what I want. But if I do the same build on Debian Jessie for lower glibc compatibility, ldd output is HUGE. Is there a way to force it to only use dlopen dependencies if possible? – eri0o Dec 20 '20 at 12:31
  • @eri0o build SDL yourself, it defaults to dlopen. Debian/ubuntu love pinned dependencies so they disable dynamic loading for their packages. – keltar Dec 20 '20 at 12:43