Assuming you have a directory of source files you want to turn into a dynamic linked library, first convert them into object files using the following command:
gcc -fPIC -c *.c
The -fpic
command stands for "position independent code".
Next, the library is created using the following command:
gcc -shared -Wl,-soname, libtools.so -o libtools.so *.o
On MacOS, it might need to be: (see next section for $LD_LIBRARY_PATH)
gcc -shared -Wl,-install_name,$LD_LIBRARY_PATH/libtest.so -o libtest.so *.o
-
The command
-shared
tells the compiler to produce a shared object. This can then be linked with other objects to form an executable. -
The command
-Wl
passes options to the linker using fomrat:-Wl,options,
. In this example, the name of the shared library is set, and then passed on to the linker. -
In this example, the name is set to
libtest
andlibtools
, but you can pretty much choose any name for the library
The compiler (GCC at least) will supposedly look for libraries at the environment variable:
export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH
What this effectively does is pin the current directory to the head of the DLL lookup path in the environment variables. On MacOS, this environment variable is empty. In order to make the library available to a program, the linker must be informed in the following manner:
gcc <src>.c -L<path> -l<libname> -o <app_name>
Here, the angled brackets indicate placeholders.
src
is the name of the program source file to which you want to link the library with.path
says where the dynamic linked library is located. It is also the name that the dynamic library will be packaged with. In my case.libname
is the name of the dynamic linked library. However, while the dynamic linked library has the namelibfoo
(always starts withlib
), you don’t include that when compiling because it is already assumed to be there. You also don’t include the suffix.so
app_name
refers to the name of the executable you want created from the linked program and library.
An example of how I compiled the following program is shown below:
gcc moduletest.c -I$LD_LIBRARY_PATH -L$LD_LIBRARY_PATH -ltest -o moduletest
Where the directory structure is:
├── dynamic
│ ├── libtest.so
│ ├── testmodule.c
│ ├── testmodule.h
│ └── testmodule.o
├── dynamic_2
│ ├── moduletest
│ └── moduletest.c
├── zebro.sublime-project
└── zebro.sublime-workspace
The following command lists all functions made available from the dynamic linked library
nm <libname>.so
The following command lists all dependencies of the dynamic linked library. However, this doesn’t appear to work on macOS
ldd <libname>.so