前言
- find_package是cmake用来管理第三方库的一个命令。
- 那这个命令有什么用呢?在实际项目开发中,我们肯定会使用到第三方库。那就需要在程序中,去指定库的位置和头文件位置,但库的安装位置,每个人都是不一样的,基本上所有项目都是很多人一起协同开发,我们不可能直接在项目中把路径写死。
- find_package就可以解决这个问题,他会自动去查找第三方库的位置。这样不管你的第三方库安装在哪个位置,都可以使用同一套项目代码。
语法
- 语法简介
-  find_package(<PackageName> [<version>] [REQUIRED] [COMPONENTS <components>...])
- PackageName: 包名
- version: 版本
- REQUIRED: 指定后如果找不到对应包,cmake就会停止执行。
- COMPONENTS: 指定要查找的组件
- 执行find_package命令后,会自动设置以下三个变量 : 
  - PackageName_FOUND:找到了就是True
- PackageName_INCLUDE_DIR或者- PackageName_INCLUDES:头文件目录
- PackageName_LIBRARY或者- PackageName_LIBRARIES: 库文件位置
 
模式
- cmake有两种查找库的模式,分别为 Module mode 和 Config mode。默认情况下, cmake采用Module模式查找, 如果没有找到, 再采用Config模式查找.
Module mode
- 在Module模式中,cmake需要找到一个叫做Find<PackageName>.cmake的文件。这个文件负责找到库所在的路径,为我们的项目引入头文件路径和库文件路径。
- cmake搜索这个文件的路径有两个,一个是cmake安装目录下的share/cmake-<version>/Modules(Linux平台为/usr/share/cmake-<version>/modules)目录,另一个是我们指定的CMAKE_MODULE_PATH的所在目录。
- 这里简单演示下,我的电脑上安装了Qt4,通过find_package去查找下
- cmake文件内容 
  -  # 指定CMake最低版本 cmake_minimum_required(VERSION 3.16) # 构建项目的名称 project(findpackage) # 查找库 find_package(Qt4) if(Qt4_FOUND) Message("find Qt4 success") else() Message("find Qt4 failed") endif()
 
-  
- 构建工程后,可以看到查找成功 
  
- 那么cmake是如何找到Qt4库的,cmake首先会去安装目录下的 share/cmake-<version>/Modules目录下查找一个Find<PackageName>.cmake的文件,可以去这个目录下看看都有哪些文件。
- 可以看到有非常多的*.cmake文件,这是cmake安装时就会将一些常用的开源库的*.cmake文件放到这个目录下。
- 接下来把 FindQt4.cmake拷贝到D盘根目录下,再去构建工程。可以看到提示查找失败。 
  
Config mode
- 在Config模式中,可以查找两种类型的文件。 
  - config:<lowercasePackageName>-config.cmake或者<PackageName>Config.cmake
- version: <lowercasePackageName>-config-version.cmake或者<PackageName>ConfigVersion.cmake
 
- config:
- 查找路径为 CMAKE_PREFIX_PATH
示例
-  生成*.cmake并调用 
-  需要准备两个工程 
-  工程一:生成动态库并导出*.cmake文件 - 目录结构
-  ├── CMakeLists.txt ├── include │ └── dlib.h └── src └── dlib.cpp
- cmake文件内容
-  # 指定CMake最低版本 cmake_minimum_required(VERSION 3.16) # 构建项目的名称 project(create_package) # 包含头文件 include_directories(${PROJECT_SOURCE_DIR}/include) # 生成动态库 add_library(dlib SHARED ${PROJECT_SOURCE_DIR}/src/dlib.cpp) # 指定头文件 set_target_properties(dlib PROPERTIES PUBLIC_HEADER include/dlib.h) # 设置头文件路径 target_include_directories(dlib PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> # install时为空, 只有编译时有值 $<INSTALL_INTERFACE:include> # 只有install时有值 ) # 安装目标项 install(TARGETS dlib EXPORT dlib # 标志导出Config.cmake文件 RUNTIME DESTINATION bin ARCHIVE DESTINATION bin PUBLIC_HEADER DESTINATION include # 导出头文件 ) install(EXPORT dlib FILE dlibConfig.cmake DESTINATION config # 指定生成的 Config.cmake 文件名和路径 )
- 命令
-  # 构建工程,并指定生成文件路径 cmake -DCMAKE_INSTALL_PREFIX=../out .. # 编译 cmake --build . --config Release # 安装 cmake --install . --config Release
- 安装完成后,可以看到指定目录下生成了对应的文件
 
- 下面通过工程二来调用生成的相关文件
 
-  工程二:通过*.cmake文件调用动态库 - 目录结构
-  ├── CMakeLists.txt └── src └── main.cpp
- cmake文件内容
-  # 指定CMake最低版本 cmake_minimum_required(VERSION 3.16) # 构建项目的名称 project(findpackage) # 查找库 find_package(dlib) if(dlib_FOUND) Message("find dlib success") else() Message("find dlib failed") endif() # 包含头文件 include_directories(${PROJECT_SOURCE_DIR}/include) # 生成可执行程序 add_executable(findpackage ${PROJECT_SOURCE_DIR}/src/main.cpp) target_link_libraries(findpackage dlib)
- 命令
-  # 构建项目 # 工程一中生成的是Config类型的*.cmake文件,因此通过 CMAKE_PREFIX_PATH 来指定生成的*cmake文件路径。 cmake -DCMAKE_PREFIX_PATH=E:/setcmake_package/out/config .. # 编译 cmake --build . --config Release
- 可以看到,调用并执行成功
 
 
参考
- “轻松搞定CMake”系列之find_package用法详解















![[SQLSERVER][SQL]数据库备份任务异常](https://i-blog.csdnimg.cn/direct/cef0f767c33d40bf918a51e6b08ea25c.png)






