在软件开发中,我们经常听到动态链接库(Dynamic Link Library,DLL)和静态链接库(Static Link Library,LIB)的术语。它们是一种组织和共享代码的方式,有助于提高代码的可维护性和可重用性。本教程将使用CMake来创建动态链接库和静态链接库,为你提供一份简单易懂的指南,让你轻松理解这两种库的概念和制作过程。
动态链接库是一种包含可执行代码和数据的文件,它可以在运行时被加载和执行。这种库的主要优势在于代码的共享,多个程序可以同时使用同一个动态链接库,从而减少内存占用。在不同的操作系统中,DLL的文件后缀不同:
在Windows上,动态链接库的后缀通常是.dll(比如mylibrary.dll)。
在Linux上,通常是.so,表示共享对象(Shared Object,比如libmylibrary.so)。
在macOS上,也是.dylib,表示动态库(Dynamic Library,比如libmylibrary.dylib)。
相比之下,静态链接库在编译时被嵌入到程序中,程序在运行时不再依赖外部库。这意味着每个程序都包含其所需的所有代码,但也可能导致更大的可执行文件。静态链接库的文件后缀也因操作系统而异:
在Windows上,静态链接库的后缀通常是.lib(比如mylibrary.lib)。
在Linux上,通常是.a,表示归档文件(Archive,比如libmylibrary.a)。
在macOS上,同样是.a,表示静态库(Static Library,比如libmylibrary.a)。
在cmake中,如果要制作静态库,需要使用的命令如下:
add_library(库名称 STATIC 源文件1 [源文件2] ...)
STATIC后面的为你要生成静态库的源文件
在Linux中,静态库名字分为三部分:lib+库名字+.a,此处只需要指定出库的名字就可以了,另外两部分在生成该文件的时候会自动填充。
在Windows中虽然库名和Linux格式不同,但也只需指定出名字即可。
首先,我们创建一个a.cpp作为示例:
.
├── a.cpp
├── bin
├── build
├── CMakeLists.txt
├── include
└── src
接下来我们在cmake里面添加上这句:
add_library(testlib a.cpp)
然后我们使用cmake和make命令
Consolidate compiler generated dependencies of target app
[ 60%] Built target app
[ 80%] Building CXX object CMakeFiles/testlib.dir/a.cpp.o
[100%] Linking CXX static library libtestlib.a
[100%] Built target testlib
ubuntu@ubuntu-2204:~/C/csdn-cmake/build$ tree -L 1
.
├── app
├── CMakeCache.txt
├── CMakeFiles
├── cmake_install.cmake
├── libtestlib.a
└── Makefile
1 directory, 5 files
接下来我们看一下文件:
.
├── a.cpp
├── bin
│ └── app
├── build
│ ├── app
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ ├── libtestlib.a
│ └── Makefile
├── CMakeLists.txt
├── include
│ └── func.h
└── src
├── func.cpp
└── main.cpp
5 directories, 11 files
可以看到libtestlib.a
这边就有Linux的静态文件夹了
制作动态库
在cmake中,如果要制作动态库,需要使用的命令如下:
add_library(库名称 SHARED 源文件1 [源文件2] ...)
我们只需要把STATIC 换成 SHARED 即可
add_library(testlib SHARED a.cpp)
可以看到,这样就成功生成了我们的so动态库文件
对于生成的库文件来说和可执行程序一样都可以指定输出路径。由于在Linux下生成的动态库默认是有执行权限的,所以可以按照生成可执行程序的方式去指定它生成的目录:
cmake_minimum_required(VERSION 3.0)
project(test)
include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
# 设置动态库生成路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
add_library(test SHARED ${SRC_LIST})
由于在Linux下生成的静态库默认不具有可执行权限,所以在指定静态库生成的路径的时候就不能使用EXECUTABLE_OUTPUT_PATH宏了,而应该使用LIBRARY_OUTPUT_PATH,这个宏对应静态库文件和动态库文件都适用。
cmake_minimum_required(VERSION 3.0)
project(CALC)
include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
# 设置动态库/静态库生成路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
# 生成动态库
#add_library(test SHARED ${SRC_LIST})
# 生成静态库
add_library(test STATIC ${SRC_LIST})
通过CMake,我们可以轻松地创建和管理动态链接库和静态链接库,使得代码的组织和共享变得更加简单。动态链接库允许多个程序共享相同的代码,而静态链接库将代码嵌入到程序中,减少了对外部依赖的需求。选择使用哪种库取决于你的项目需求和偏好,但理解它们的差异将有助于你更好地设计和组织你的代码。希望这个保姆级教程能够让你对动态链接库和静态链接库有一个清晰的认识。