[linux] What's the difference between .so, .la and .a library files?

I know an .so file is a kind of dynamic library (lots of threads can share such libraries so there is no need to have more than one copy of it in memory). But what is the difference between .a and .la? Are these all static libraries?

If dynamic libs have big advantages over static ones, why there are still lots of static libraries?

I also want to know the underlying mechanism to load libraries (both kinds) and how a piece of code in a lib is invoked when it is used somewhere. Which part of the kernel should I study? And what related Linux command/utility should I know in order to know how a process is running? (I only know the ld command by now)

When should I try to build code into .so or .a? Which one is better?

[mirror@home ins_openvpn]$ ls lib/openvpn/plugins/ -l
total 96
-rw-r--r-- 1 mirror mirror 22892 Sep  2 23:25 openvpn-plugin-auth-pam.a
-rwxr-xr-x 1 mirror mirror   931 Sep  2 23:25 openvpn-plugin-auth-pam.la
-rwxr-xr-x 1 mirror mirror 23621 Sep  2 23:25 openvpn-plugin-auth-pam.so
-rw-r--r-- 1 mirror mirror 17228 Sep  2 23:25 openvpn-plugin-down-root.a
-rwxr-xr-x 1 mirror mirror   932 Sep  2 23:25 openvpn-plugin-down-root.la
-rwxr-xr-x 1 mirror mirror 18805 Sep  2 23:25 openvpn-plugin-down-root.so

The answer is


.so files are dynamic libraries. The suffix stands for "shared object", because all the applications that are linked with the library use the same file, rather than making a copy in the resulting executable.

.a files are static libraries. The suffix stands for "archive", because they're actually just an archive (made with the ar command -- a predecessor of tar that's now just used for making libraries) of the original .o object files.

.la files are text files used by the GNU "libtools" package to describe the files that make up the corresponding library. You can find more information about them in this question: What are libtool's .la file for?

Static and dynamic libraries each have pros and cons.

Static pro: The user always uses the version of the library that you've tested with your application, so there shouldn't be any surprising compatibility problems.

Static con: If a problem is fixed in a library, you need to redistribute your application to take advantage of it. However, unless it's a library that users are likely to update on their own, you'd might need to do this anyway.

Dynamic pro: Your process's memory footprint is smaller, because the memory used for the library is amortized among all the processes using the library.

Dynamic pro: Libraries can be loaded on demand at run time; this is good for plugins, so you don't have to choose the plugins to be used when compiling and installing the software. New plugins can be added on the fly.

Dynamic con: The library might not exist on the system where someone is trying to install the application, or they might have a version that's not compatible with the application. To mitigate this, the application package might need to include a copy of the library, so it can install it if necessary. This is also often mitigated by package managers, which can download and install any necessary dependencies.

Dynamic con: Link-Time Optimization is generally not possible, so there could possibly be efficiency implications in high-performance applications. See the Wikipedia discussion of WPO and LTO.

Dynamic libraries are especially useful for system libraries, like libc. These libraries often need to include code that's dependent on the specific OS and version, because kernel interfaces have changed. If you link a program with a static system library, it will only run on the version of the OS that this library version was written for. But if you use a dynamic library, it will automatically pick up the library that's installed on the system you run on.


Examples related to linux

grep's at sign caught as whitespace How to prevent Google Colab from disconnecting? "E: Unable to locate package python-pip" on Ubuntu 18.04 How to upgrade Python version to 3.7? Install Qt on Ubuntu Get first line of a shell command's output Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running? Run bash command on jenkins pipeline How to uninstall an older PHP version from centOS7 How to update-alternatives to Python 3 without breaking apt?

Examples related to memory-management

When to create variables (memory management) How to check if pytorch is using the GPU? How to delete multiple pandas (python) dataframes from memory to save RAM? Is there a way to delete created variables, functions, etc from the memory of the interpreter? C++ error : terminate called after throwing an instance of 'std::bad_alloc' How to delete object? Android Studio - How to increase Allocated Heap Size Implementing IDisposable correctly Calculating Page Table Size Pointer-to-pointer dynamic two-dimensional array

Examples related to static-libraries

"relocation R_X86_64_32S against " linking Error How do I tell CMake to link in a static library in the source directory? File is universal (three slices), but it does not contain a(n) ARMv7-s slice error for static libraries on iOS, anyway to bypass? What's the difference between .so, .la and .a library files? Telling gcc directly to link a library statically static linking only some libraries How to compile a static library in Linux? Difference between static and shared libraries? Trying to include a library, but keep getting 'undefined reference to' messages DLL and LIB files - what and why?

Examples related to ld

What's the difference between .so, .la and .a library files? ld cannot find -l<library> How to print the ld(linker) search path How to remove unused C/C++ symbols with GCC and ld? I don't understand -Wl,-rpath -Wl, Compiling problems: cannot find crt1.o How to set the LDFLAGS in CMakeLists.txt? LD_LIBRARY_PATH vs LIBRARY_PATH Why do I have to define LD_LIBRARY_PATH with an export every time I run my application?

Examples related to shared-libraries

How to install the Six module in Python2.7 "relocation R_X86_64_32S against " linking Error Compilation fails with "relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object" How to create a shared library with cmake? error while loading shared libraries: libncurses.so.5: Build .so file from .c file using gcc command line What's the difference between .so, .la and .a library files? ld cannot find -l<library> How do you find what version of libstdc++ library is installed on your linux machine? What are .a and .so files?