cmake之find_package命令详解

前言

  • 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
  • 查找路径为 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
      
    • 可以看到,调用并执行成功
    • 在这里插入图片描述

参考

  • 10
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大草原的小灰灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值