find_package() 主要用于查找并配置复杂的第三方软件包,这些软件包通常包含多个库和头文件,并且可能需要执行额外的配置步骤。例如,对于 Boost 库,你需要使用 find_package () 来查找和配置 Boost,CMake 会查找 Boost 库的位置,并设置正确的库路径、头文件路径和编译选项等。
find_library ()则主要用于查找单个库文件。如果你只需要使用某个库文件而不需要配置整个第三方软件包,那么可以使用 find_library ()来查找该库文件并设置库路径、链接选项等。
在CMake中,find_package
和find_library
都是用来找到和链接库的方法,但它们的用法和适用场景略有不同。
find_package
主要用于寻找具有CMake配置文件的库,这些库通常遵循CMake的规范,提供了用于导入目标、库路径、头文件路径等的配置文件。这使得使用find_package
更加简洁,只需指定需要的组件即可自动处理头文件路径、库路径等。find_package
更适合于较大、更复杂的库,如Boost。在找到库后,find_package
会生成相关的导入目标(如Boost::filesystem
)供你在target_link_libraries
中使用。
find_library
则是一个更基本的方法,用于在系统中搜索特定的库文件。它不依赖于库提供的CMake配置文件,而是直接查找库文件。使用find_library
时,需要手动指定库文件路径、头文件路径等。find_library
更适合于较小或没有CMake配置文件的库,如Crypto++。比如实际应用中,我们使用find_library
来找到Crypto++库,因为Crypto++库没有提供CMake配置文件。而对于Boost,我们使用find_package
,因为Boost库提供了CMake配置文件,使得库的查找和链接更简便。
总之,find_package
和find_library
都可以用于在CMake中查找和链接库,但find_package
更适用于具有CMake配置文件的库,而find_library
则适用于没有CMake配置文件的库。
一、命令格式
find_package
命令有两种格式,基本命令格式和完整命令格式。
1、基本命令
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[NO_POLICY_SCOPE])
几个重要的参数介绍:
PackageName
:待查找包的名称。此外它还决定两种搜索模下的.cmake
文件名称:例如模块模式下的名称为Find<PackageName>.cmake
,而配置模式下为<lowercasePackageName>-config.cmake
/<lowercasePackageName>-config-version.cmake
。MODULE
:该选项指定find_package
命令只使用模块模式
搜索方式查找。未指定该选项时,find_package
会优先使用模块模式
搜索,仍未找到包时,会切换成配置模式
搜索。version
:待查找包的版本号要求,版本号为点分格式,由四个部分组成,每个部分都是一个数字,均为可选:major[.minor[.patch[.tweak]]]
,例如1.1.1.1
、1.0
、等。同样也可以指定版本范围(CMake 3.19
及之后才支持),格式为:versionMin...[<]versionMax
,versionMin
和versionMax
均是major[.minor[.patch[.tweak]]]
形式的版本号,默认情况下会包含这个指定区间两端的版本号,但如果指定了<
,那么会排除掉versionMax
,例如1.1.1.1...1.1.2.0
、1.1.1.1...<1.1.2.0
等。EXACT
:该选项要求待查找包的版本必须与指定的版本精确匹配,因此如果指定的是一个版本范围,不能使用该参数。QUIET
:禁止输出信息,正常情况当找到包时,CMake
会打印一些信息,指定该选项时会禁止掉这些打印。例外是当同时指定QUIET
时,如果找不到包,仍然会输出错误信息并终止执行过程。REQUIRED
:当未找到满足条件的包(例如版本号不匹配,或指定组件未找到等),会终止CMake
的执行过程,并输出一条错误信息。如果未指定该选项,即使未找到满足条件的包,CMake
的执行过程也会继续。COMPONENTS
:指定要查找的组件。通常一个包可能包含多个组件(可以理解为多个库,例如把C++的std看成一个包的概念,那么vector就是std下的其中一个组件),我们的工程可能会依赖包下的具体某个组件,因此可以通过这个选项来检测这些组件是否存在。通常的约定是,该选项后的组件应该都找到时才认为包找到,否则认为未找到满足条件的包。这个约束会依赖包的.cmake
来实现,通过find_package
命令传入的COMPONENTS
可以通过<PackName>_FIND_COMPONENTS
这个变量来获得。
find_package 命令用法举例
find_package(OpenCV)
- 查找名为 OpenCV 的包,找不到不报错,事后可以通过
${OpenCV_FOUND}
查询是否找到。
- 查找名为 OpenCV 的包,找不到不报错,事后可以通过
find_package(OpenCV QUIET)
- 查找名为 OpenCV 的包,找不到不报错,也不打印任何信息。
find_package(OpenCV REQUIRED)
# 最常见用法- 查找名为 OpenCV 的包,找不到就报错(并终止 cmake 进程,不再继续往下执行)。
find_package(OpenCV REQUIRED COMPONENTS core videoio)
- 查找名为 OpenCV 的包,找不到就报错,且必须具有
OpenCV::core
和OpenCV::videoio
这两个组件,如果没有这两个组件也会报错。
- 查找名为 OpenCV 的包,找不到就报错,且必须具有
find_package(OpenCV REQUIRED OPTIONAL_COMPONENTS core videoio)
- 查找名为 OpenCV 的包,找不到就报错,可具有
OpenCV::core
和OpenCV::videoio
这两个组件,没有这两组件不会报错,通过${OpenCV_core_FOUND}
查询是否找到 core 组件。
- 查找名为 OpenCV 的包,找不到就报错,可具有
简单的例子
# mymathConfig.cmake,假定它位于./mymath/mymath目录下
# 作用就是校验COMPONENTS是否是test,只有当COMPONENTS为空或者为test时,包mymath才会被找到
message(${mymath_FIND_COMPONENTS}) # `find_package`命令的`COMPONENTS`传入的
if(${mymath_FIND_COMPONENTS} STREQUAL "")
message("Empty comps.")
set(mymath_INCLUDE_DIR "/XXX/mymath")
set(mymath_LIBRARY "/XXX/mymath/libmymath.a")
else()
foreach(comp ${mymath_FIND_COMPONENTS})
if (comp MATCHES "test")
message("Find comp test")
set(mymath_INCLUDE_DIR "/XXX/mymath")
set(mymath_LIBRARY "/XXX/mymath/libmymath.a")
endif()
endforeach()
endif()
# 顶层目录的CMakeLists.txt
cmake_minimum_required(VERSION 3.10.2)
project(find_package_test)
find_package(mymath
CONFIG
REQUIRED
COMPONENTS test
PATHS ./mymath/mymath
)
if(mymath_FOUND)
message("Find mymath: ${mymath_INCLUDE_DIR}; ${mymath_LIBRARY};")
endif()
# 执行cmake .
cmake .
# 输出为
test
Find comp test
Find mymath: /XXX/mymath; /XXX/mymath/libmymath.a;
OPTIONAL_COMPONENTS
:与COMPONENTS
的区别是,不强制要求这些组件必须存在。不影响CMake
的执行。
2、完整命令
find_package(<PackageName> [version] [EXACT] [QUIET]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[CONFIG|NO_MODULE]
[NO_POLICY_SCOPE]
[NAMES name1 [name2 ...]]
[CONFIGS config1 [config2 ...]]
[HINTS path1 [path2 ... ]]
[PATHS path1 [path2 ... ]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[NO_DEFAULT_PATH]
[NO_PACKAGE_ROOT_PATH]
[NO_CMAKE_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_PACKAGE_REGISTRY]
[NO_CMAKE_BUILDS_PATH] # Deprecated; does nothing.
[NO_CMAKE_SYSTEM_PATH]
[NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH])
这里介绍一下与基本命令有差异的地方:
CONFIG|NO_MODULE
:这两个选项二选一即可,表示强制find_package
命令使用配置模式
搜索,忽略模块模式
搜索。NAMES
:默认情况下find_package
命令会查找名为<PackageName>
的包。如果NAMES
选项后指定了名称,则会使用这些名字来查找包而忽略<PackageName>
参数。PATHS
/HINTS
:配置模式下指定.cmake
文件的搜索路径。NO_XXX_PATH
:配置模式下忽略指定的路径,具体的含义可以参考4.1.2
节。
2.3 命令返回的结果
<PackageName>_FOUND
变量用来表示包是否找到,True
表示包找到了,False
表示未找到满足条件的包。如果包被找到,那么还会提供其他与这个包相关的变量供调用者使用,例如包的头文件、库文件等。这些变量都是以<PackageName>_
开头的,具体的命名格式请参考Cmake中find_package命令的搜索模式之模块模式(Module mode)的四、对标准变量名称的更多说明
章节。
二、find_package 说是找“包(package)”,到底是在找什么?
1、寻找包配置文件
find_package(OpenCV)
实际上是在找一个名为 OpenCVConfig.cmake
的文件。
注:出于历史兼容性考虑,除了OpenCVConfig.cmake
以外OpenCV-config.cmake
这个文件名也会被 CMake 识别到。
同理,find_package(Qt5)
则是会去找名为 Qt5Config.cmake
的文件。
这些形如 包名 + Config.cmake
的文件,我称之为包配置文件。
Qt5Config.cmake
是在安装 Qt5 时,随 libQt5Core.so
等实际的库文件,一起装到系统中去的。
以 Arch Linux 系统为例:
- 包配置文件位于
/usr/lib/cmake/Qt5/Qt5Config.cmake
。 - 实际的动态库文件位于
/usr/lib/libQt5Core.so
。
以 Ubuntu 22.04 系统为例:
- 包配置文件位于
/usr/lib/x86_64-linux-gnu/cmake/Qt5/Qt5Config.cmake
- 实际的动态库文件位于
/usr/lib/x86_64-linux-gnu/libQt5Core.so
2、包配置文件包含什么?
因此 find_package
并不是直接去找具体的动态库文件和头文件(例如 libQt5Core.so
)。而是去找包配置文件(例如Qt5Config.cmake
),这个配置文件里包含了包的具体信息,包括动态库文件的位置,头文件的目录,链接时需要开启的编译选项等等。
而且某些库都具有多个子动态库,例如 Qt
就有 libQt5Core.so
、libQt5Widgets.so
、libQt5Network.so
。因此 CMake 要求所有第三方库作者统一包装成一个 Qt5Config.cmake
文件包含所有相关信息(类似于 nodejs 的 package.json),比你单独的一个个去找动态库文件要灵活的多。
在XXXConfig.cmake
文件中,库的路径都是 相对路径,比如说../../libXXX.so
,而 不是绝对路径/usr/lib/libXXX.so
...
这样做可以让CMake更容易找到对应的动态库,因为不一定每个人的系统库都是安装在/usr/lib/...
下!比如Arch Linux和Ubuntu的库安装路径就不一样!因此相对路径会更加方便。
3、包配置文件怎么来的?
包配置文件由第三方库的作者(Qt的开发团队)提供,在这个库安装时(Qt的安装程序或apt install
等)会自动放到 /usr/lib/cmake/XXX/XXXConfig.cmake
这个路径(其中XXX是包名),供 CMake 用户找到并了解该包的具体信息。
/usr/lib/cmake
这个位置是 CMake 和第三方库作者约定俗成的,由第三方库的安装程序负责把包配置文件放到这里。如果第三方库的作者比较懒,没提供 CMake 支持(由安装程序提供XXXConfig.cmake
),那么得用另外的一套方法(FindXXX.cmake
),稍后细谈。
4、搜索路径
4.1 Windows 系统下的搜索路径
<prefix>/
<prefix>/cmake/
- <
prefix>/<name>*/
<prefix>/<name>*/cmake/
<prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/cmake/
其中:
<prefix>
是变量${CMAKE_PREFIX_PATH}
,Windows 平台默认为C:/Program Files
。<name>
是你在find_package(<name> REQUIRED)
命令中指定的包名。<arch>
是系统的架构名。
4.2 Unix 类系统下的搜索路径
<prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/
<prefix>/(lib/<arch>|lib*|share)/<name>*/
<prefix>/(lib/<arch>|lib*|share)/<name>*/cmake/
<prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/cmake/
其中:
<prefix>
是变量${CMAKE_PREFIX_PATH}
,Unix 平台默认为/usr
。<name>
是你在find_package(<name> REQUIRED)
命令中指定的包名。<arch>
是系统的架构,例如x86_64-linux-gnu
或i386-linux-gnu
。- (用于伺候 Ubuntu 喜欢把库文件套娃在 /usr/lib/x86_64-linux-gnu 目录下)
5、举例说明 find_package 搜索路径
例如你是 64 位的 Linux 系统,find_package(Qt5 REQUIRED)
会依次搜索:
/usr/lib/cmake/Qt5/Qt5Config.cmake
/usr/lib/x86_64-linux-gnu/cmake/Qt5/Qt5Config.cmake
/usr/share/cmake/Qt5/Qt5Config.cmake
/usr/lib/Qt5/Qt5Config.cmake
/usr/lib/x86_64-linux-gnu/Qt5/Qt5Config.cmake
/usr/share/Qt5/Qt5Config.cmake
/usr/Qt5/lib/cmake/Qt5/Qt5Config.cmake
/usr/Qt5/lib/x86_64-linux-gnu/cmake/Qt5/Qt5Config.cmake
/usr/Qt5/share/cmake/Qt5/Qt5Config.cmake
/usr/Qt5/lib/Qt5/Qt5Config.cmake
/usr/Qt5/lib/x86_64-linux-gnu/Qt5/Qt5Config.cmake
/usr/Qt5/share/Qt5/Qt5Config.cmake
例如你是 64 位的 Windows 系统,find_package(Qt5 REQUIRED) 会依次搜索:
C:/Program Files/Qt5Config.cmake
C:/Program Files/cmake/Qt5Config.cmake
C:/Program Files/Qt5/Qt5Config.cmake
C:/Program Files/Qt5/cmake/Qt5Config.cmake
C:/Program Files/Qt5/lib/cmake/Qt5/Qt5Config.cmake
C:/Program Files/Qt5/lib/x86_64-windows-gnu/cmake/Qt5/Qt5Config.cmake
C:/Program Files/Qt5/share/cmake/Qt5/Qt5Config.cmake
C:/Program Files/Qt5/lib/Qt5/Qt5Config.cmake
C:/Program Files/Qt5/lib/x86_64-windows-gnu/Qt5/Qt5Config.cmake
C:/Program Files/Qt5/share/Qt5/Qt5Config.cmake
还有一点,<name>
可以有额外后缀,且不分大小写(无论 Linux 还是 Windows),例如在Windows系统中:
C:/Program Files/Qt5/cmake/Qt5Config.cmake
C:/Program Files/Qt5.12.1/cmake/Qt5Config.cmake
C:/Program Files/qt5dnmd/cmake/Qt5Config.cmake
都是可以被 find_package(Qt5 REQUIRED)
搜索到的。
在 Linux 系统中:
/usr/lib/cmake/OpenCV/OpenCVConfig.cmake
/usr/lib/cmake/opencv4/OpenCVConfig.cmake
都是可以被 find_package(OpenCV REQUIRED) 搜索到的。
6、安装在非标准路径的库如何处理?
以 Qt5 为例,如果你安装在下列标准路径,find_package 能够自动找到。
- Windows:
C:/Program Files/Qt5.12.1/lib/cmake/Qt5/Qt5Config.cmake
。 - Linux:
/usr/lib/cmake/Qt5/Qt5Config.cmake。
但是假如我的库不是装在这些标准路径,而是我自定义的路径,怎么办? 而且即使你不自定义安装路径,Windows 版的 Qt 默认安装就会安装到:
C:/Qt5.12.1/msvc2017_64/lib/cmake/Qt5/Qt5Config.cmake
。
何况我们同学有的还喜欢装到 D 盘去,Windows 是非标准路径的重灾区,他就没有一个统一的 /usr/lib
目录。然而你一旦把库安装到非标准路径,find_package 是找不到的。
这时你需要手动指定一个变量告诉他在哪儿,可以是普通变量 ${Qt5_DIR}
,也可以是环境变量 $ENV{Qt5_DIR}
,两个中只要设置了任何一个 find_package 都可以识别到。 变量一般通过命令行 -DQt5_DIR=”C:/Program Files/Qt5.12.1/lib/cmake/Qt5”
设置。
6.1 举例,Windows 系统,Qt5
例如我把 Qt5 安装到了 D:/Qt5.12.1
。 首先找到他里面的 Qt5Config.cmake
文件所在位置(可以用文件管理器的“搜索”功能或者everything)。
假如你找到该文件的位置是 D:/Qt5.12.1/msvc2017/lib/cmake/Qt5/Qt5Config.cmake
,那么请你设置变量 Qt5_DIR
为 D:/Qt5.12.1/msvc2017/lib/cmake/Qt5
。有三种设置方法:
- 单次有效。在 configure 阶段,可以从命令行设置(注意要加引号):
cmake -B build -DQt5_DIR=”D:/Qt5.12.1/msvc2017/lib/cmake/Qt5”
- 全局启用。右键“我的电脑”->“管理”->“高级”添加一个环境变量
Qt5_DIR
值为D:/Qt5.12.1/msvc2017/lib/cmake/Qt5
,然后重启 Visual Studio。这样以后你每次构建任何项目,find_package 都能自动找到这个路径的 Qt5 包了。 - 单项目有效。直接在你自己项目的
CMakeLists.txt
最开头写一行(注意要加引号):set(Qt5_DIR ”D:/Qt5.12.1/msvc2017/lib/cmake/Qt5”) # 一定要加在最前面!
6.2 举例,Linux 系统,Qt5
例如我把 Qt5 安装到了 /opt/Qt5.12.1
。 首先找到他里面的 Qt5Config.cmake
文件所在位置(可以用文件管理器的“搜索”功能)。 假如你找到该文件的位置是 /opt/Qt5.12.1/lib/cmake/Qt5/Qt5Config.cmake
,那么请你设置变量 Qt5_DIR
为 /opt/Qt5.12.1/lib/cmake/Qt5
。有三种设置方法:
- 单次有效。在 configure 阶段,可以从命令行设置:
cmake -B build -DQt5_DIR=”/opt/Qt5.12.1/lib/cmake/Qt5”
- 全局启用。修改你的
~/.bashrc
文件添加环境变量:export Qt5_DIR=”/opt/Qt5.12.1/lib/cmake/Qt5”
,然后重启终端。这样以后你每次构建任何项目,find_package 都能自动找到这个路径的 Qt5 包了。 - 单项目有效。直接在你自己项目的 CMakeLists.txt 最开头写一行:
set(Qt5_DIR ”/opt/Qt5.12.1/lib/cmake/Qt5”) # 一定要加在最前面!
三种方案利弊分析
- 单次有效(通过命令行)最安全,高度推荐。
- 全局有效(添加环境变量)可能影响以后其他项目。
- 比如你的 A 项目依赖 Qt5.12.1,你设置了环境变量
Qt5_DIR=/opt/Qt5.12.1
,后来又搞了个 B 项目依赖Qt5.10.3
,但是你忘了你设置过全局的环境变量指向 5.12.1 了,导致版本冲突。
- 比如你的 A 项目依赖 Qt5.12.1,你设置了环境变量
- 单项目有效(写死在 CMakeLists.txt)虽然方便了你,但是你的 CMakeLists.txt 拿到别人电脑上就冲突了
- (例如你通过 GitHub 开源的),可能你
set(Qt5_DIR D:/Qt5)
,而人家却需要set(Qt5_DIR E:/Qt5)
。
- (例如你通过 GitHub 开源的),可能你
所以“单次有效”虽然劳驾您的高抬贵手每次命令行打一下 -DQt5_DIR=”D:/Qt5”
,但人家也打一下 -DQt5_DIR=”E:/Qt5”
,就没有冲突,各美其美,美美与共,赋能多元化社会,下沉团队合作发力面。
实际上只要你不删 build,不需要每次都 -DQt5_DIR 一下
,CMake 具有“记忆”功能。
cmake -B build -DQt5_DIR=D:/Qt5
# 只需要第一次指定好cmake -B build
# 以后第二次运行可以省略!rm -rf build
# 只有清理了 build 以后,cmake -B build -DQt5_DIR=D:/Qt5
# 才需要重新指定。
三、搜索模式
find_package
用于查找包(通常是使用三方库),并返回关于包的细节(使用包所依赖的头文件、库文件、编译选项、链接选项等)
与find_libaray直接在指定搜索目录下搜索库不同,find_package
命令可以获取更多的信息,那么它的搜索方式也是与find_libaray
不一样,它有两种不同的搜索方式,因此在介绍这个命令的细节之前,先简单介绍一下find_package
命令的两种搜索模式:模块模式(Module mode
)和配置模式(Config mode
)。
1、模块模式(Module mode
)
在该模式下,Cmake
会搜索一个名为Find<PackageName>.cmake
的文件,其中<PackageName>
为待搜索包的名称。
搜索路径的顺序依次是:
- 从变量
CMAKE_MODULE_PATH
指定的路径中进行查找 - 从
Cmake
安装路径中查找。Cmake
会在其安装路径下提供很多.cmake
文件,例如/XXX/cmake/Modules/
目录下(不同的系统安装目录可能不一致)
如果找到文件Find<PackageName>.cmake
,Cmake
会读取并处理该文件,简而言之,它负责检查一些条件(如版本号是否满足等)是否满足,并在找到包后,返回给调用者一些变量,用以获取包的详细信息。
一般来说,Find<PackageName>.cmake
文件不是随包本身一起提供的,更多的是外部针对已有包的重新包装,例如操作系统、Cmake
程序、甚至是调用find_package
命令的工程针对已有的包提供针对该包的.cmake
文件。
2、配置模式(Config mode
)
该模式下,CMake
会搜索<lowercasePackageName>-config.cmake
文件或<PackageName>Config.cmake
文件。如果find_package
命令中指定了具体的版本,也会搜索<lowercasePackageName>-config-version.cmake
或<PackageName>ConfigVersion.cmake
文件,因此配置模式下通常会提供配置文件和版本文件(注意形式上要保持一致),并且作为包的一部分一起提供给使用者。
该模式下对.cmake
文件的搜索路径的顺序比较复杂,具体见本文的4.1
节。
.cmake
后缀文件的作用是什么?
find_package
的两种搜索模式都会按照一定规则从路径下搜索.cmake
后缀的文件,两种模式下的.cmake
文件作用都是为了给find_package
命令的调用方返回有关包的信息(头文件路径、库文件路径、编译连接选项、版本信息等等)
三、搜索模式和命令之间的关系
搜索模式有两种:模块模式和配置模式。命令有两种形式:基本命令和完整命令。他们之间的关系是:
基本命令
: 首先使用模块模式,如果没找到包,则会切换到配置模式。可以通过将CMAKE_FIND_PACKAGE_PREFER_CONFIG
变量设置为true
来改变顺序,这样会优先使用配置模式,如果没找到再切换到模块模式。此外,基本命令可以通过MODULE
选项来强制指定只使用模块模式,也可以指定NO_MODULE
或CONFIG
来表示只使用配置模式搜索。完整命令
:只支持配置模式搜索。
四、使用示例
我们将以两个例子分别展示两种搜索模式。本例中会利用我自己系统(macOS
)已经安装的库LibLZMA
(如何编写自己的库并让find_package
两种模式能搜索到,请参考另外两篇文章看Cmake中find_package命令的搜索模式之模块模式(Module mode)和Cmake中find_package命令的搜索模式之配置模式(Config mode),尝试搜索这个库,并利用这个库提供的接口lzma_version_string
(在头文件lzma.h
中提供)来获取它的版本号,并打印出来,测试程序如下:
// test.cpp
// 打印lzma库的版本号
#include "lzma.h"
#include <iostream>
int main(int argc, char** argv)
{
const char* version = lzma_version_string();
std::cout << "lzma version is: " << version << std::endl;
return 0;
}
1、模块模式查找LibLZMA
库
模块模式的CMakeLists.txt
内容如下:
# CMakeLists.txt
find_package(LibLZMA MODULE) # MODULE指定使用模块模式查找
if (LibLZMA_FOUND)
message("Find lzma library: ${LIBLZMA_INCLUDE_DIR}, ${LIBLZMA_LIBRARY}")
include_directories(${LIBLZMA_INCLUDE_DIR})
add_executable(test test.cpp)
target_link_libraries(test ${LIBLZMA_LIBRARY})
endif()
# 命令行执行
cmake .
make
./test
# 命令行输出(只展示跟例子相关的输出)
Find lzma library: /usr/local/include, /usr/local/lib/liblzma.dylib
lzma version is: 5.2.5
2、配置模式查找LibLZMA
库
由于lzma
库本身未提供lzmaConfig.cmake
,我们简单的编写一个,内容就是为find_package
提供lzma
库所在的头文件和库文件,并在find_package
中指定查找该.cmake
所在的路径:
# lzmaConfig.cmake
set(lzma_INCLUDE_DIR "/usr/local/include")
set(lzma_LIBRARY "/usr/local/lib/liblzma.dylib")
配置模式的CMakeLists.txt
内容如下:
find_package(lzma CONFIG
NAMES lzma
PATHS ./)
if (lzma_FOUND)
message("Find lzma library: ${lzma_INCLUDE_DIR}, ${lzma_LIBRARY}")
include_directories(${lzma_INCLUDE_DIR})
add_executable(test test.cpp)
target_link_libraries(test ${lzma_LIBRARY})
endif()
# 命令行执行
cmake .
make
./test
# 命令行输出(只展示跟例子相关的输出)
Find lzma library: /usr/local/include, /usr/local/lib/liblzma.dylib
lzma version is: 5.2.5
find_package — CMake 3.22.6 Documentation
https://zhuanlan.zhihu.com/p/631259689
find_package() & find_library()区别_findpackge和findlibrary-CSDN博客
Cmake中find_package命令的搜索模式之模块模式(Module mode) - 简书