Table of Contents

Dynamic Linking

This page contains notes about creating and using shared objects on Unix-like systems.

Basic Concepts

The discussion on this page assumes that the reader is familiar with the four stages of compilation and use of shared objects:

Overview: Creating a Simple Shared Object

To create a shared object from a single object file, it must first be compiled as position-independent code1) with the -fpic option:

gcc -c -Wall -Werror -fpic code.c

When linking multiple object files into a single shared object, all of them must have been compiled with -fpic or the operation will fail.

Then the -shared option can be used to link that into a shared object:

gcc -shared -o libcode.so code.o

When compiling an application to use the shared library, its location must be specified with -L prior to using the -l option to link it (unless it's in a system default shared object directory):

gcc -L/home/user/src/code -Wall -o codeapp main.c -lcode

Similarly, when executing the application the library won't be found unless its location is specified (again, unless it's in a system default location). This can be done with LD_LIBRARY_PATH:

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/user/src/code ./codeapp

While sometimes useful for development, this isn't a robust solution for production environments and it has serious security implications. It's also possible to specify the path at link time, however:

gcc -L/home/user/src/code -Wl,rpath=/home/user/src/code -Wall -o codeapp main.c -lcode

This approach requires libraries to be installed in a fixed location, which isn't always convenient, but doesn't require any special configuration at runtime. Note that the -Wl option is used to pass the subsequent option directly through to the linker.

The standard approach is to copy the library to a system default location (e.g. /usr/lib) and run the ldconfig utility to create appropriate symlinks to it and update the shared object cache.

1) This prevents the compiler locating data at fixed addresses, because clearly different executables will load the shared object into different parts of their address space.