跨平台工程构建:CMake 的使用(三) 引入库

前一章介绍了 cmake 的基本语法 以及如何构建一个最简单的工程。这里接着聊一聊使用 cmake 构建工程的常用操作:添加库
一、由源代码添加库
这一节中我们将向工程中添加一个库项目。
假设我们需要开发一个 mathlib 库, 并在其他项目中调用,可以像下面这样操作:
-
在工程路径下建立子文件夹
mathlib -
在
./mathlib中添加项目源文件mymath.h,mymath.cxx,并添加CMakeLists.txt:
mymath.h :
1 |
|
mymath.cxx:
1 |
|
CMakeLists.txt:
1 | add_library(mathlib mymath.cxx mymath.h) |
- 在主工程中添加代码:
src.cxx:
1 |
|
CMakeLists.txt:
1 | cmake_minimum_required(VERSION 3.0) |
二、由二进制文件添加库
很多时候我们没有库的源码,或者不想源码引入工程中重复编译。此时我们将添加二进制的库。
添加二进制库的一般操作为:
-
使用
link_directories设置库的路径 -
add_executable生成文件 -
target_link_libraries链接库
如下:
CMakeLists.txt:
1 | cmake_minimum_required(VERSION 3.0) |
src.cpp:
1 |
|
其中库文件 mathlib.lib 放在 build/lib 路径下。另外要注意这几个命令的顺序。
三、使用 find_package 添加库(包)
在使用以上两种方法时,我们需要知道库的源文件(或头文件) / 库文件(a/lib/so/dylib) 的位置,然后通过 include_directories link_directories 等命令引入工程。如果事先不知道这些信息,也可以使用 find_package 命令来添加预定义在 CMAKE_MODULE_PATH 的或内置的 Find.cmake 模块。
1 | find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE] |
-
version兼容版本号。格式应该是major[.minor[.patch[.tweak]]] -
EXACT可选,要求精确版本号 -
QUIET可选 , 当没有发现库时不发生警告信息 -
REQUIRED可选, 指明该库是必须的,若没发现库则会终止 cmake -
COMPONENTS可选,指明该包需要的组件
cmake 内置了很多常用的包的 cmake 模块,可以直接调用,它们在 cmake 安装目录下的 share/cmake-3.13/Modules 下。例如当我们需要引入 boost 时的工程:
CMakeLists.txt:
1 | cmake_minimum_required(VERSION 3.0) |
src.cxx:
1 |
|
find_package 工作原理
find_package( ) 先在 ${CMAKE_MODULE_PATH} 路径下,然后在 <CMake_Install_dir>/share/cmake-3.13/Modules 下查找 Find<Nmae>.cmake 。如果没有找到,则会寻找 <Name>Config.cmake 或 <lower-case-name>-config.cmake。前一种称为 模块模式 ,后一种称为 配置模式 。cmake 默认优先使用模块模式,如果找不到模块,则使用配置模式,通常安装库时会拷贝一份 Config.cmake 到系统目录中,因此没有指定搜索路径时也有可能顺利找到包。 不管哪种模式,只要找到包就会定义下面这些变量:
1 | <NAME>_FOUND |
如果 <NAME>_FOUND 被定义,说明包已经找到了。那么可以使用 include_directories() 引入 <NAME>_INCLUDE_DIRS 头文件 ,使用 link_directories() 和 target_link_libraries() 来引入库文件。
自定义包
这里以前面的 mathlib 为例,看一下如何自定义一个 cmake 包。
mathlib的 CMakeLists.txt 定义如下:
1 | cmake_minimum_required(VERSION 3.0) |
完成编译后,以上工程会在源文件目录下生成:
-
install/include/mymath包含了头文件mymath.h -
install/lib包含生成的库文件mathlib.lib -
install/lib/cmake/mathlib包含了两个 cmake 文件 :mathlib-config.cmake,mathlib-config-debug.cmake
使用上面的包:
src.cpp:
1 |
|
CMakeLists.txt
1 | cmake_minimum_required(VERSION 3.0) |