Unless your program is compiled into one big binary lump it will typically need to load other assets on program start.

This is usually libraries, though other assets may also be required.

Your programming environment will define some standard locations (see hier(7) for some examples), but will normally have a way to specify more.

  • C programs will look for libraries in directories listed as : separated strings in the LD_LIBRARY_PATH environment variable.
  • Python programs will look in PYTHONPATH.
  • Lua programs will look in LUA_PATH, LUA_CPATH and other environment variables based on the version of the Lua interpreter.
  • Java will look in its class path, which can be set with the -classpath option.
  • Executables will be sought in the PATH environment variable.

If you only need assets in the standard locations then you wouldn't normally need to change anything.

However you're not always able to stick to only distribution provided software.

In this case you need to use software which has "bundled" its dependencies alongside its own software.

Linux ELF binaries can make use of its "RPATH" to add extra paths, but most executable formats don't have a direct equivalent.

In which case we can instead specify the new locations with a wrapper script. The standard trick is to use $0 for the name of the script, dirname(1) to get the directory the script is located in, and readlink(1) -f on the to turn it into an absolute path.

#!/bin/sh
D="$(dirname "$(readlink -f "$0")")"
cp="$(set -- "$D/support/jars/"*.jar; IFS=:; printf %s "$*")"
exec java -classpath "$cp" com.myapplication.Main "$@"

This works for running the script in the directory the assets are stored in, but it can be convenient to add the program to a directory in PATH.

If written as a bash script you can use $BASH_SOURCE which is guaranteed to be the path of the script, and in circumstances I can now no longer reproduce I needed to use it instead of $0.

#!/bin/bash
D="$(dirname "$(readlink -f "${BASH_SOURCE}")")"
cp="$(set -- "$D/support/jars/"*.jar; IFS=:; printf %s "$*")"
exec java -classpath "$cp" com.myapplication.Main "$@"