🔍 什么是静态库和动态库?
静态库(Static Library)
- 链接时将代码嵌入到最终可执行文件中
- 文件扩展名:
.lib(Windows) 或.a(Linux/Mac) - 可执行文件独立,不依赖外部库文件
动态库(Dynamic Library)
- 运行时才加载库代码
- 文件扩展名:
.dll(Windows) 或.so(Linux) /.dylib(Mac) - 可执行文件依赖外部库文件
📦 静态库的生成与使用
1. 编写库源码
math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
int multiply(int a, int b);
#endif
math_utils.cpp
#include "math_utils.h"
int add(int a, int b) {
return a + b;
}
int multiply(int a, int b) {
return a * b;
}
2. 编译成目标文件
# Linux/Mac
g++ -c math_utils.cpp -o math_utils.o
# Windows (MinGW)
g++ -c math_utils.cpp -o math_utils.o
3. 创建静态库
cpp
# Linux/Mac
ar rcs libmath_utils.a math_utils.o
# Windows
ar rcs libmath_utils.a math_utils.o
# 或者使用 MSVC 的 lib 工具
lib /OUT:math_utils.lib math_utils.obj
4. 使用静态库
- main.cpp
cpp
#include <iostream>
#include "math_utils.h"
int main() {
std::cout << "5 + 3 = " << add(5, 3) << std::endl;
std::cout << "5 * 3 = " << multiply(5, 3) << std::endl;
return 0;
}
编译链接:
*
cpp
# Linux/Mac
g++ main.cpp -L. -lmath_utils -o main_static
# Windows
g++ main.cpp -L. -lmath_utils -o main_static.exe
📦 动态库的生成与使用
1. 编译成共享对象
cpp
# Linux
g++ -fPIC -c math_utils.cpp -o math_utils.o
g++ -shared -o libmath_utils.so math_utils.o
# Mac
g++ -dynamiclib -o libmath_utils.dylib math_utils.o
# Windows (创建 DLL)
g++ -shared -fPIC math_utils.cpp -o math_utils.dll
2. 使用动态库
编译时链接
*
cpp
# Linux/Mac
g++ main.cpp -L. -lmath_utils -o main_dynamic
# Windows
g++ main.cpp -L. -lmath_utils -o main_dynamic.exe
运行时注意事项
- Linux/Mac:确保库路径在
LD_LIBRARY_PATH环境变量中 - Windows:确保 DLL 文件在可执行文件同目录或系统 PATH 中
🛠️ 生成库的常用工具
Linux/Mac
cpp
# 编译器
gcc/g++ # GNU 编译器套件
clang/clang++ # LLVM 编译器
# 库管理工具
ar # 创建静态库
ld # 链接器
objdump # 查看库信息
nm # 列出符号表
strip # 移除符号信息
Windows
cpp
# Microsoft Visual Studio
cl.exe # C/C++ 编译器
link.exe # 链接器
lib.exe # 静态库工具
dumpbin.exe # 查看库信息
# MinGW/MSYS2
gcc/g++ # GNU 工具链
ar # 库管理
🧩 Makefile 示例
Makefile
*
cpp
# 编译器设置
CC = g++
CFLAGS = -Wall -O2
# 目标文件
OBJECTS = math_utils.o
STATIC_LIB = libmath_utils.a
SHARED_LIB = libmath_utils.so
EXECUTABLE_STATIC = main_static
EXECUTABLE_DYNAMIC = main_dynamic
# 默认目标
all: static shared
# 编译目标文件
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $@
# 创建静态库
static: $(OBJECTS)
ar rcs $(STATIC_LIB) $(OBJECTS)
$(CC) main.cpp -L. -lmath_utils -o $(EXECUTABLE_STATIC)
# 创建动态库
shared: $(OBJECTS)
$(CC) -fPIC -c math_utils.cpp -o math_utils.o
$(CC) -shared -o $(SHARED_LIB) math_utils.o
$(CC) main.cpp -L. -lmath_utils -o $(EXECUTABLE_DYNAMIC)
# 清理
clean:
rm -f *.o $(STATIC_LIB) $(SHARED_LIB) $(EXECUTABLE_STATIC) $(EXECUTABLE_DYNAMIC)
.PHONY: all clean static shared
🧩 CMake 示例
CMakeLists.txt
*
cpp
cmake_minimum_required(VERSION 3.10)
project(MathLibrary)
set(CMAKE_CXX_STANDARD 17)
# 源文件
set(SOURCES math_utils.cpp)
# 静态库
add_library(math_utils_static STATIC ${SOURCES})
set_target_properties(math_utils_static PROPERTIES OUTPUT_NAME "math_utils")
# 动态库
add_library(math_utils_shared SHARED ${SOURCES})
set_target_properties(math_utils_shared PROPERTIES OUTPUT_NAME "math_utils")
set_target_properties(math_utils_shared PROPERTIES PREFIX "")
# 可执行文件(静态链接)
add_executable(main_static main.cpp)
target_link_libraries(main_static math_utils_static)
# 可执行文件(动态链接)
add_executable(main_dynamic main.cpp)
target_link_libraries(main_dynamic math_utils_shared)
构建命令
*
cpp
mkdir build && cd build
cmake ..
make
⚡ 静态库 vs 动态库对比
| 特性 | 静态库 (.a/.lib) | 动态库 (.so/.dll) |
|---|---|---|
| 文件大小 | 可执行文件大 | 可执行文件小 |
| 依赖性 | 独立运行 | 依赖库文件 |
| 内存使用 | 每进程独立 | 多进程共享 |
| 更新 | 需重新编译 | 只需替换库文件 |
| 启动速度 | 较快 | 略慢(加载库) |
| 部署 | 简单(单文件) | 需分发库文件 |
📋 实际操作步骤总结
创建库的完整流程:
- 编写头文件(.h/.hpp)
- 编写实现文件(.cpp/.cc)
- 编译为目标文件(.o/.obj)
- 打包成库文件
- 静态库:使用
ar或lib - 动态库:使用
-shared选项
- 静态库:使用
- 在其他项目中链接使用