Static And Shared Library
Code distribution among different programs and machines.
1. Introduction
A static library
is a collection of object files that are linked into the program during the linking phase of compilation, becoming part of the final executable. A shared library
is a collection of object files that are loaded into the program at runtime. Multiple programs can share the same library code in memory.
2. Example
2.1 Implementation
Source code can be found at: https://github.com/chuzcjoe/static_shared_lib
Project structure
1 | . |
We have a simple math library that does simple math operations.
1 | // mathlib.h |
We will compile it into both static and shared libraries.
1 | cmake_minimum_required(VERSION 3.5.0) |
For the most outside CMakeLists.txt, we will generate different executables that link to static/shared libraries.
1 | cmake_minimum_required(VERSION 3.5.0) |
2.2 Build
Let’s build it.
1 | mkdir build |
In the build folder, we can get two executables and inside the math folder, we have generated static/shared libraries. They should have the same output.
1 | ├── main_shared |
1 | > ./main_static |
2.3 Inspect
We could use otool
on MacOS to check the dependencies of each executable. Or on Linux we could use ldd
.
1 | > otool -L main_static |
1 | > otool -L main_shared |
Because static libraries will become part of the executable, so libmath_static.a
is not a dependency. On the other hand, shared libraries are loaded during runtime, so main_shared
replies on libmath_shared.dylib
.
2.4 File size
Linking a static library involves incorporating the entire library into the final executable. Compared with linking shared library, executables that link to static library usually will have larger file size.
1 | > ls -lh main_static |
2.5 Delete dependencies
If we delete both libmath_static.a
and libmath_shared.dylib
, main_static
can still run without any issues.
1 | > ./main_static |
However, main_shared
needs to load libmath_shared.dylib
at runtime, and it looks for the library at current project as well as system paths. If this library is not found, then we will get a link error.
1 | > ./main_shared |
2.5 More
If a static/shared library depends on another library. The relationship can be:
dependencies | valid? |
---|---|
shared_lib links to static_lib | ✗ |
shared_lib links to shared_lib | ✓ |
static_lib links to static_lib | ✓ |
static_lib links to shared_lib | ✓ |
Shared libraries can only be linked to shared libraries. Static libraries can be linked to both shared and static library.
3. Conclusion
static library
Advantages:
- Simplicity: No external dependencies are required at runtime.
- Performance: Sometimes faster to start and run due to the absence of the need to resolve symbols or load additional libraries at runtime.
Disadvantages:
- File Size: Can lead to larger executable sizes because each program has its own copy of the library.
- Updates: If the library is updated, all applications using it must be recompiled and redeployed to benefit from the updates.
shared library
Advantages:
- Reduced Memory Usage: Since the library is shared in memory among multiple programs, it can reduce memory usage overall.
- Ease of Updating: Updating a shared library can provide immediate benefits to all programs that use it, without needing recompilation.
Disadvantages:
- Complexity: Requires careful management of versions and dependencies to ensure compatibility.
- Startup Time: Can have slower startup times as the operating system needs to link the external libraries dynamically when the program is launched.
void GLRender::nextImage() {
LOG_INFO(“switch to next image.”);
int next_index = (image_idx + 1) % IMAGE_NUM;
sdrImage.setFilepath(files[next_index]);
glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_2D, _texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
sdrImage.loadJPEG();
auto data = sdrImage.data();
int width = sdrImage.getWidth();
int height = sdrImage.getHeight();
if (data) {
// generate texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
LOG_INFO("load texture success, width: %d, height: %d\n", width, height);
} else {
LOG_ERROR("load texture error");
}
glUseProgram(tProgram);
glUniform1i(glGetUniformLocation(tProgram, "texture_load"), 0);
}
Static And Shared Library
http://chuzcjoe.github.io/2024/06/29/cpp-static-shared-library/