Should you distribute your C++ API as a static or dynamic library ? The answer to that question is not straightforward and will depend on a number of factors like:
- Does the client application using your library have size limitations on disk ?
- Does your client application need to reduce linking overhead ?
- Does you client application need to control when the functionality is loaded in process space ?
- Is it convenient for your client application to package and distribute multiple DLLs ? Some asset management system for certain game engines can make this problematic.
- Does your client plan on patching the system frequently like Windows does ?
and many more...
Even if the answer to the above question is not obvious, it is useful to note down the differences between static and dynamic libraries such that next time you can use this checklist to determine is a static or dynamic library is better suited for your API.
Differences between Static and Dynamic C++ libraries
Compiling : Yes
(The linking happens when the client executable using the static library is built)
Nature of Binary
The executable without the startup routines.
Contains resolved references.
Archive of object file(s).
All the sections exist, but the majority of references are unresolved (except local references)
Needed after the executable is built ?
The dynamic library needs to be packaged with the executable and must be available when the executable starts running (more specifically, calls a function provided by the dynamic library)
A static library is only needed during building the executable (during link stage). It is not needed to run the executable because the library code is embedded inside the application.
Disk Space Efficiency: Code sharing among applications on disk
The same dynamic library can be shared among multiple executables on disk.
Each executable will need to link it's seperate copy of the static library. This can cause a lot of binary bloat on disk and especially resource constrained mobile devices. However, if each application only uses a small fraction of the total static library, the disk space efficiency can still be competitive with a single large DLL
Many modern operating systems will attempt to load the dynamic library code into memory once and share it across all applications that need it. For example, an http networking stack might be shared between your calendar and notebook applications
If the http networking stack is in a static library, every application needing this functionality will load it's own copy of the networking stack and affect runtime memory in general.
You might run into issues when a version of the dynamic library used by your application conflicts with an older/newer version of the library present on the operating system.
Since all the library functionality is linked into the application, it does not amtter if other applications on the system is using a different version of the static library.
Delivering Updates / Patching
If your clients wish to hot patch the application with a new ( ABI compatible) version of the dynamic library, they can just obtain a new dll from you and patch that DLL only without rebuilding their entire application.
The whole application will need to be re-built and patched. This becomes a huge problem for large applications because now you'll need to deliver a much larger update via network.
Control over Loading
In some systems, the application has explicit control via system calls like (LoadLibrary on windows) of when the library functionality gets loaded and unloaded. This can help manage the memory of applications in an efficient way on resource constrained systems
The entire library is loaded into process space when the applications boots up and stays there till the application tears down.
In most systems, a separate step is required to create an asset / dependency manifest for the application and package it up.
Distributed by default with the application/ executable itself - no separate packaging necessary.
Suitability during development
Only the functionality in the Dynamic library needs to be recompiled.
The entire application will need to be recompiled. For a large application like a AAA game or something as large as Office, it can take hours if all functionality is statically linked in instead of being in separate DLLs.
As a rule of thumb, prefer to distribute your library as a dynamic library unless it is very small and is prone to version conflicts with rest of the system. However, it's always recommended to do your own analysis using the dimensions above together with your client.
As some readers on Reddit has pointed out, the statically linked libraries have a little better performance profile than dynamic libraries. Something to keep in mind as well.
Additional Information/ References
4. Book Reference: Advanced C/C++ compiling - a lot of the information in this article has been adapted from this book. Highly recommended for every C/C++ developer
5. Book Reference: C++ API Design by Martin Reddy offers a great section explaining the difference between static and dynamic libraries from an API design perspective.