有些时候我们编写的源代码并不需要将他们编译生成可执行程序,而是生成一些静态库或动态库
提供给第三方使用,下面来讲解在 cmake 中生成这两类库文件的方法。
1 制作静态库
在 cmake 中,如果要制作静态库
,需要使用的命令如下:
add_library(库名称 STATIC 源文件1 [源文件2] ...)
add_library
是生成库文件
的意思,而不是添加库文件
- 不管是在
Linux
还是在Windows
下,动态库
或者静态库
它们的名字主要分成3部分:lib
+库名字
+后缀
, 如果是动态库在Linux是.so
,在windows
下是.dll
;如果是静态库,如果是windows系统,静态库对应的后缀为.lib
,如果是Linux
系统它的后缀为.a
。 库名称
: 去掉lib和后缀的库名字, 如果是生成静态库指定为STATIC
,如果是动态库则为SHARED
, 后面接着所有要生成库文件的源文件。
下面有一个目录,需要将src
目录中的源文件编译成静态库
,然后再使用:
.
├── build
├── CMakeLists.txt
├── include # 头文件目录
│ └── head.h
├── main.cpp # 用于测试的源文件
└── src # 源文件目录
├── add.cpp
├── div.cpp
├── mult.cpp
└── sub.cpp
根据上面的目录结构,可以这样编写CMakeLists.txt
文件:
cmake_minimum_required(VERSION 3.0)
project(CALC)
include_directories(${
PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
add_library(calc STATIC ${
SRC_LIST})
这样最终就会生成对应的静态库文件 libcalc.a
。
2 制作动态库
在 cmake 中,如果要制作动态库
,需要使用的命令如下:
add_library(库名称 SHARED 源文件1 [源文件2] ...)
-
在
Linux
中,动态库名字分为三部分:lib+ 库名字 +.so
,此处只需要指定出库的名字
就可以了,另外两部分在生成该文件的时候会自动填充。 -
在 Windows 中虽然库名和 Linux 格式不同,但也只需指定出名字即可。
根据上面的目录结构,可以这样编写 CMakeLists.txt
文件:
cmake_minimum_required(VERSION 3.0)
project(CALC)
include_directories(${
PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
add_library(calc SHARED ${
SRC_LIST})
这样最终就会生成对应的动态库文件 libcalc.so。
3 库文件的使用
库文件发布给第三方时,需要发布两部分
数据:库文件 + 头文件
, 因为不论是动态库还是静态库,它们的本质都是源代码
, 只不过这些源代码是二进制
的(对应计算机来说,不论是二进制还是文本格式的源文件,都是以二进制来处理), 因此二进制的源文件也是需要头文件
的, 因为源文件的申明,都定义在头文件中。
4. 指定输出库文件的路径
方式 1 - 适用于动态库
对于生成的库文件来说和可执行程序一样都可以指定输出路径。由于在Linux下生成的动态库
默认是有执行权限
的,所以可以按照生成可执行程序
的方式去指定它生成的目录:
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(EXECUTABLE_OUTPUT_PATH ${
PROJECT_SOURCE_DIR}/lib)
add_library(calc SHARED ${
SRC_LIST})
- 对于这种方式来说,其实就是通过 set 命令给
EXECUTABLE_OUTPUT_PATH
宏设置了一个路径,这个路径就是可执行文件生成的路径。 EXECUTABLE_OUTPUT_PATH
指定可执行文件的输出路径,因为动态库和可执行文件都有可执行权限,所以EXECUTABLE_OUTPUT_PATH 也适用于动态库。但对于动态库的输出来说,并不是很直观,因此指定库文件的输出路径时,建议使用LIBRARY_OUTPUT_PATH
方式 2 - 都适用
由于在 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(calc SHARED ${
SRC_LIST})
# 生成静态库
add_library(calc STATIC ${
SRC_LIST})
参考
作者: 苏丙榅
链接: https://subingwen.cn/cmake/CMake-primer/