一、理解动态库与静态库
静态、动态是指链接
所谓静态、动态是指链接。回顾一下,将一个程序编译成可执行程序的步骤:
链接: 把外部函数的代码(通常是后缀名为.lib和.a的文件),添加到可执行文件中。这就叫做连接(linking)。这种通过拷贝,将外部函数库添加到可执行文件的方式,叫做静态连接(static linking),还有动态连接(dynamic linking)
命名方式
linux下:
静态库:lib库名.a
动态库:lib库名.so(shared object)
window:下
静态库:lib库名.lib
动态库:lib库名.dll(dynamic link library)
区分一个概念:库是包含前缀lib以及后缀.a或者.so的一个整体
库名是去掉前缀和后缀剩下的部分
动态库和静态库的特点
静态库的特点:
1、使用静态库的时候,会将静态库的信息直接编译到可执行文件中
2、优点:当静态库被删除,对可执行文件没有影响
3、缺点:浪费内存空间。如果静态库被修改,可执行程序要重新编译
动态库的特点:
加载器在加载动态库时,操作系统会先检查动态库是否因为其它程序已经将这个动态库信息加载到了内存中。如果没有加载到内存中,操作系统会将动态库载入内存,并将它的引用计数设置为1;如果已经加载到内存,仅将动态库的引用计数加1。
二、构建动态库和静态库
工程目录
haha.cpp随便写点,比如命名一个函数,打印"haha"
CMakeList.txt
aux_source_directory(./ SOURCES)
add_executable(example ${SOURCES})
# 添加动态库 得到libhaha.so动态库文件
add_library(haha SHARED haha.cpp)
# 给动态库添加版本号 得到libhaha.so.1.2 同时得到两个软链接 具体看结果说明
set_target_properties(haha PROPERTIES VERSION 1.2 SOVERSION 1)
# 添加静态库 得到libhaha.a静态库文件
add_library(haha_static STATIC haha.cpp)
# 更改输出库的名字 libhah.a 修改为 libhello.a
set_target_properties(haha_static PROPERTIES OUTPUT_NAME "hello")
# 设置可执行文件的输出路径 这是是工程目录下的lib目录
SET(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/lib")
# 设置库文件的输出路径 这是是工程目录下的lib目录
SET(LIBRARY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/lib")
结果说明
运行后会得到一个lib目录,里面有可执行文件和我们构建的动态库、静态库文件。
打开lib目录:
libhello.a文件是静态库文件,以下命令得到:
# 添加静态库 得到libhaha.a静态库文件
add_library(haha_static STATIC haha.cpp)
# 更改输出库的名字 libhah.a 修改为 libhello.a
set_target_properties(haha_static PROPERTIES OUTPUT_NAME "hello")
libhaha.so.1.2文件是静态库文件,同时 libhaha.so.1软链接 libhaha.so软链接,由该命令得到:
# 添加动态库 得到libhaha.so动态库文件
add_library(haha SHARED haha.cpp)
# 给动态库添加版本号 得到libhaha.so.1.2 同时有两个链接
# VERSION指代动态库版本, SOVERSION 指代API版本
set_target_properties(haha PROPERTIES VERSION 1.2 SOVERSION 1)
三、使用动态库
使用动态库的条件
必须有动态库的头文件,这里即 haha.h 头文件
必须要知道动态库所在路径:
CMakeLists.txt
# 动态库所在目录
set(lib_dir "/home/jason/work/my-deploy/example/lib")
# 添加 动态库头文件 搜索路径
include_directories(./)
# 生成可执行文件
add_executable(example main.cpp)
# 链接库文件到可执行文件 库文件名称要写全
target_link_libraries(example ${lib_dir}/libhaha.so)
mai.cpp中需要应用动态库的头文件,方可使用动态库的函数
这里头文件是 haha.h,动态库函数为 haha(),会在控制台打印 haha!
#include <iostream>
#include "haha.h"
using namespace std;
int main()
{
cout << "Hello World!" << endl;
haha();
return 0;
}
四、使用静态库
使用静态库基本与使用动态库一致,也需要准备静态库所在路径,静态库头文件
CMakeLists.txt
链接库文件时,改成静态库名称即可
# 静态库所在目录
set(lib_dir "/home/jason/work/my-deploy/example/lib")
# 添加 静态库头文件 搜索路径
include_directories(./)
# 生成可执行文件
add_executable(example main.cpp)
# 链接库文件到可执行文件 库文件名称要写全
target_link_libraries(example ${lib_dir}/libhello.a)
参考:
【Cmake实战:番外】库、动态库和静态库(.dll,.so,.lib,.a)_cmake dll和lib_郑同学的笔记的博客-CSDN博客
【cmake实战六】如何使用编译的库(动态库dll)——windows系统_cmake编译动态库_郑同学的笔记的博客-CSDN博客
【cmake实战五】如何使用编译的库(静态库)——windows系统_windows编译静态库_郑同学的笔记的博客-CSDN博客
创建静态库/动态库一定要有头文件吗?为什么?_使用静态库需要头文件吗_吃西瓜蘸辣酱的博客-CSDN博客
c++使用静态库和直接使用源码有什么区别?_生成静态库链接和直接编译的区别_千么漾漾的博客-CSDN博客
C++编译之(3)-camke/CMakeLists.txt的编译使用教程_丰色木夕的博客-CSDN博客