CMake4-指令4-2:find_package【用于查找并配置复杂的第三方软件包】【通过查找第三方库的.cmake的文件,并不是直接去找具体的动态库文件和头文件】【指定第三方库所在路径】

本文深入解析CMake中的find_package命令,涵盖基本与完整命令格式、搜索模式及应用场景,通过实例演示如何查找配置第三方库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

find_package() 主要用于查找并配置复杂的第三方软件包,这些软件包通常包含多个库和头文件,并且可能需要执行额外的配置步骤。例如,对于 Boost 库,你需要使用 find_package () 来查找和配置 Boost,CMake 会查找 Boost 库的位置,并设置正确的库路径、头文件路径和编译选项等。 

find_library ()则主要用于查找单个库文件。如果你只需要使用某个库文件而不需要配置整个第三方软件包,那么可以使用 find_library ()来查找该库文件并设置库路径、链接选项等。 


在CMake中,find_packagefind_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_packagefind_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.11.0、等。同样也可以指定版本范围(CMake 3.19及之后才支持),格式为:versionMin...[<]versionMaxversionMinversionMax均是major[.minor[.patch[.tweak]]]形式的版本号,默认情况下会包含这个指定区间两端的版本号,但如果指定了<,那么会排除掉versionMax,例如1.1.1.1...1.1.2.01.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} 查询是否找到。
  • find_package(OpenCV QUIET)
    • 查找名为 OpenCV 的包,找不到不报错,也不打印任何信息。
  • find_package(OpenCV REQUIRED) # 最常见用法
    • 查找名为 OpenCV 的包,找不到就报错(并终止 cmake 进程,不再继续往下执行)。
  • find_package(OpenCV REQUIRED COMPONENTS core videoio)
    • 查找名为 OpenCV 的包,找不到就报错,且必须具有 OpenCV::core 和 OpenCV::videoio 这两个组件,如果没有这两个组件也会报错。
  • find_package(OpenCV REQUIRED OPTIONAL_COMPONENTS core videoio)
    • 查找名为 OpenCV 的包,找不到就报错,可具有 OpenCV::core 和 OpenCV::videoio 这两个组件,没有这两组件不会报错,通过 ${OpenCV_core_FOUND} 查询是否找到 core 组件。

简单的例子

# 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.solibQt5Widgets.solibQt5Network.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。有三种设置方法

  1. 单次有效。在 configure 阶段,可以从命令行设置(注意要加引号): cmake -B build -DQt5_DIR=”D:/Qt5.12.1/msvc2017/lib/cmake/Qt5”
  2. 全局启用。右键“我的电脑”->“管理”->“高级”添加一个环境变量 Qt5_DIR 值为 D:/Qt5.12.1/msvc2017/lib/cmake/Qt5,然后重启 Visual Studio。这样以后你每次构建任何项目,find_package 都能自动找到这个路径的 Qt5 包了。
  3. 单项目有效。直接在你自己项目的 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。有三种设置方法:

  1. 单次有效。在 configure 阶段,可以从命令行设置: cmake -B build -DQt5_DIR=”/opt/Qt5.12.1/lib/cmake/Qt5”
  2. 全局启用。修改你的 ~/.bashrc 文件添加环境变量: export Qt5_DIR=”/opt/Qt5.12.1/lib/cmake/Qt5”,然后重启终端。这样以后你每次构建任何项目,find_package 都能自动找到这个路径的 Qt5 包了。
  3. 单项目有效。直接在你自己项目的 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 了,导致版本冲突。
  • 单项目有效(写死在 CMakeLists.txt)虽然方便了你,但是你的 CMakeLists.txt 拿到别人电脑上就冲突了
    • (例如你通过 GitHub 开源的),可能你 set(Qt5_DIR D:/Qt5),而人家却需要 set(Qt5_DIR E:/Qt5) 。

所以“单次有效”虽然劳驾您的高抬贵手每次命令行打一下 -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>.cmakeCmake会读取并处理该文件,简而言之,它负责检查一些条件(如版本号是否满足等)是否满足,并在找到包后,返回给调用者一些变量,用以获取包的详细信息。

一般来说,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_MODULECONFIG来表示只使用配置模式搜索。
  • 完整命令:只支持配置模式搜索。

四、使用示例

我们将以两个例子分别展示两种搜索模式。本例中会利用我自己系统(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介绍 - 简书

Cmake中find_package命令的搜索模式之模块模式(Module mode) - 简书

 Cmake中find_package命令的搜索模式之配置模式(Config mode) - 简书

https://juejin.cn/post/7213575951114977341

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值