This is actually a really tedious topic that has tons of little items
and details… something I have spent an unfortunate chunk of my
professional career dealing with. With cross-platform, languages and
libraries are easily portable, but build systems and distribution
rules/conventions (and now codesigning) are a real pain.
I don’t have time to go into everything, but a brief overview:
For dynamic libraries:
Windows: Put your .dll’s in the same directory as your .exe. Be
aware that if you linked to a C or C++ runtime, you are also
responsible for getting those to your end users, either by also
copying those .dlls into the same directory as the .exe or in the case
of Microsoft’s VS, hook into and ship the redistributable installer
for the C++ components. SDL does not by default link to the C standard
library on Windows, but if any of your own code or dependencies call
things like malloc or new, then you will need it.
ELF/Linux: There is a mechanism called RPATH $ORIGIN which lets you
specify relative paths from your executable to where the .so’s are
located. You need to be very careful about shipping binaries on Linux
because even the foundational stuff like glibc and the C++ standard
libraries don’t really focus on keeping the ABI stable. If you are
serious about shipping Linux binaries, you should build inside
Steam-Runtime (provided by Valve on Github), which gives you your best
shot of working on most distros.
Mac: There are two variants of dynamic libraries on Mac, .dylib and
.framework. Frameworks are basically a standardized packaged bundle
that include a .dylib (without suffix) and also any related assets
that go with the library (e.g. header files, image files, localization
strings, nib files). Apple tooling tends to favor .frameworks so there
are advantages to using them even if you don’t have any assets you
need to go with your library. So you will notice that the official SDL
binary for Mac is a .framework bundle.
For shipping apps, your application also has an asset bundle like a
framework. Again, there is a standardized layout, and it includes
different sections for executables, frameworks, dylibs, PlugIns,
assets, etc.). Following standard convention, you want to to put all
your .frameworks in .app/Contents/Frameworks. Finally, Apple has a
mechanism similar to the RPATH $ORIGIN, except it is divided into two
halves. You build the libraries with an anchor and relative path (e.g.
@rpath), and then when you build your app, you specify the paths that
the app will search (e.g. -rpath @executable_path/…/Frameworks). I
believe the SDL .frameworks are already built with the first half
using @rpath. So your app just needs to do the second part.
iOS: Similar to Mac, but .dylibs don’t seem to be supported by Xcode
for iOS at all. So you pretty much have to use .frameworks. However,
the Xcode iOS tooling is still utter crap for 3rd-party libraries.
Because iOS needs both device and simulator binaries, your build
breaks when you switch targets. Xcode doesn’t really offer good
mechanisms for 3rd party libraries, so the easiest thing has been to
build a fat binary with all architectures. But the problem is when you
ship a binary, Xcode won’t strip out the simulator binaries in dynamic
libraries. Because of this problem, and the historical fact that iOS
disallowed dynamic libraries until a few years ago, static libraries
are easier, and how the SDL Xcode project is setup.
Android: You must NOT use SONAME versioning. All .so files must be
bundled with your .apk. The standard build process will put them in a
special place and on first launch, will extract them out to a special
area on disk so they can be used. (This path is considered private
API.) You then must load each library (dependency order matters) in
Java using System.loadLibrary.
There are also a ton of rules for bundling assets (images, sounds,
etc) for each platform.
Anyway, I hope this is helpful and at least gets you on the right path.
Also, I want to mention Blurrr SDK, the SDL based SDK I’m currently
developing. One major thing Blurrr provides is it implements all these
rules into its build system so you don’t have to get bogged down with
all these details and you can just focus on your app. You just list
your files in a pre-laidout CMake-based file provided by the SDK, and
you can build a binary that is completely self-contained and