We’re going to build a dynamic library libgreeting and an application to link to it (and also do some bug fixes).
Start by reading the library source which consists of just a single .c file in libgreeting and a header file in libgreeting/include/greeting. (We’ll fix the typo later.)
$ clang -Wall -std=c11 -fPIC -Iinclude -c -o hello.o hello.c
$ clang -fPIC -shared -Wl,-soname=libgreeting.so.1 -o libgreeting.so.1.0.0 hello.o
$ file libgreeting.so.1.0.0
$ nm libgreeting.so.1.0.0 | grep hello
Next, we’re going to “install” the library and its header files for our program to use.
Copy libgreeting/libgreeting.so.1.0.0 into the lib directory.
Copy libgreeting/include/greeting into the include directory.
Inside lib, we need to make two symlinks.
$ ln -s libgreeting.so.1.0.0 libgreeting.so
$ ln -s libgreeting.so.1.0.0 libgreeting.so.1
Our library is installed, so it’s time to build our application which is in the src directory.
The first step is to compile the source files to object files (this could be omitted, especially since it’s just a single file for the program, but we’re going to do it here).
We need to tell clang where to find the header files.
$ clang -Wall -std=c11 -I../include -c -o main.o main.c
$ clang -L../lib -o prog main.o -lgreeting
$ LD_LIBRARY_PATH=../lib ./prog
$ clang -L../lib -Wl,-rpath='$ORIGIN/../lib' -o prog main.o -lgreeting
Build a new version of the library. Make sure you rebuild the object file!
Since this version is compatible with the existing version, use the same soname of libgreeting.so.1 but change the output file to libgreeting.so.1.0.1.
Run the program which should still be in bin: $ bin/prog.
If all has gone well, then without needing any changes to the binary, it should be using the new version of the dynamic library.
$ strace -o syscalls -f -e openat clang -L../lib -Wl,-rpath='$ORIGIN/../lib' -o prog main.o -lgreeting
This will write the trace to the syscalls file, trace the children of clang (because clang will be invoking the linker), and only trace the openat system call.
Open syscalls up in an editor and search for greeting. Which file did it open?
$ strace -e openat ./prog
Which of the libgreeting.so files did it open? How did it know to open that one when the one opened by the linker in the previous step was different?