====================================================================== ====================================================================== There are some points which you should be careful when you create shared library files unlike when you create archive files (static library files) ====================================================================== 1. Functions in shared library files should be "reentrant" "Reentrant" means that you shouldn't use "global variables" in shared library files Imagine 2 executable files are pointing to one shared library file at the same time, and if shared library file has global variable x, global variable x can be changed by exe1 file, then exe2 file can reference unexpectedly changed value from the global variable x ====================================================================== 2. Codes in shared library files should be "position-independent". When shared library file is loaded onto memory, you can't predict the specific address in the memory place where shared library file is loaded. So, you shouldn't write any codes in executable files, object fiels, shared library files, etc, with supposing a specific address where shared library files are loaded onto the memory. You shouldn't suppose you can jump or call to the fixed address when writing codes. You shouldn't suppose you can access data at the fixed locations when writing codes. ====================================================================== Shared library naming rule # 1.0: version infomation libmyfuncs.so.1.0: shared library file which has most version information is actual shared library file which you create -------------------------------------------------- libmyfuncs.so: when you compile, you use this name which doesn't have version information But this is not an actual file but it's symbolic link to the actual shared library file like libmyfuncs.so.1.0 sudo ln -s /path1/libmyfuncs.so.1.0 /path2/libmyfuncs.so -------------------------------------------------- You can make libmyfuncs.so.1 file symbolic-link to actual shared library file which you want to use like libmyfuncs.so.1.0, libmyfuncs.so.1.1, libmyfuncs.so.1.2, etc And this file libmyfuncs.so.1 is used by the executable file at runtime sudo ln -s /path1/libmyfuncs.so.1.0 /path2/libmyfuncs1.so sudo ln -s /path1/libmyfuncs.so.1.1 /path2/libmyfuncs1.so sudo ln -s /path1/libmyfuncs.so.1.2 /path2/libmyfuncs1.so At excutable time, you need version information but you don' need even minor version ====================================================================== How to create shared library files 1. Create object files with using -fPIC (position-independent code) option of GCC gcc -fPIC -c func1.c gcc -fPIC -c func2.c -------------------------------------------------- 2. Create shared library file by gathering object files For this step, you can use gcc and ld (Linker) # -shared: you're going to create shared library file # (default so it's omitable, # but recommended to use this for explicit expression) # -Wl, <options>: <options> are passed to the ld (Linker) # compile and asembly steps are performed in GCC # Linking is performed by Linker (ld) # -soname=libmyfuncs.so.1: specify the name of representitive so file (shared library file) # *.o: you will include all object files # which are located in the current directory into so file # -o libmyfuncs.so.1.0: specify the name of actual shared library file # which you're going to create # -lc: link libc gcc -fPIC -shared -Wl, -soname=libmyfuncs.so.1 *.o -o libmyfuncs.so.1.0 -lc -------------------------------------------------- # Other way but same effect ld -shared -soname=libmyfuncs.so.1 *.o -o libmyfuncs.so.1.0 -lc ====================================================================== After you create shared library file like libmyfuncs.so.1.0, you need to perform symbolic link # libmyfuncs.so.1.0: actual shared library file # libmyfuncs.so: representitive name of libmyfuncs shared library file # which is used when you link files at compile time in gcc ln -s libmyfuncs.so.1.0 libmyfuncs.so # libmyfuncs.so.1: is used at runtime when dynamic linking is performed ln -s libmyfuncs.so.1.0 libmyfuncs.so.1 ====================================================================== To link an application (foo) with shared library file # When you want to use shared library libmyfuncs on foo.c file # you need to add path (-L/mypath/lib) # which contains shared library file libmyfuncs gcc -o foo foo.c -L/mypath/lib -lmyfuncs ====================================================================== Command-line options -L: is used to tell the places to the linker where the linker should search to find your libxxx.so file -l: is used to tell about which shared object files to be linked with first to the linker - Wl: is used to tell about to pass specified options onto the linker to gcc/g++ compilers ====================================================================== How to find shared library files at runtime How to link shared library files to executable and other files at runtime Excutable files have pointers. At runtime, library files which are pointed by pointers are linked with executable files But you can't search all directories to find specific shared library files. So, system library paths (like /lib, /usr/lib, etc) which you should search to find shared library files are written in /etc/ld.so.conf ====================================================================== You also can have your own custom libraries than system library Paths for your own custom libraries should be written in LD_LIBRARY_PATH environment variable like export LD_LIBRARY_PATH=$HOME/foo/lib Then, Linux loader which executes programs searches all libraries which are located in the written paths at runtime