CMake Find_Package和Install

Find_Package

find_package( [version] [EXACT] [QUIET]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS components...]
             [MODULE|CONFIG|NO_MODULE]
             [GLOBAL]
             [NO_POLICY_SCOPE]
             [BYPASS_PROVIDER]
             [NAMES name1 [name2 ...]]
             [CONFIGS config1 [config2 ...]]
             [HINTS path1 [path2 ... ]]
             [PATHS path1 [path2 ... ]]
             [REGISTRY_VIEW  (64|32|64_32|32_64|HOST|TARGET|BOTH)])

参考:https://cmake.org/cmake/help/latest/command/find_package.html

Find_Package分为两种模式,一种是Module模式一种是Config模式,只要找到对应的配置文件find_package就会设置_FOUND=1。

对于Module模式下,查找到相应的库后一般会设置以下变量:

  1. _FOUND

  1. _INCLUDE_DIR 或 _INCLUDES

  1. _LIBRARY 或 _LIBRARIES

对于Config模式通常找到的是一个Target,具体Target的名字库中的CMake决定。

对于一些库配置比较麻烦,可以支持通过参数传递-D_LIBRARY="..."和-D_INCLUDE_DIR="...",可以让find_package返回正确的值。

Module模式

MODULE模式中cmake通过查找名为Find.cmake的文件来查找包。查找顺序如下:

  1. 首先在CMAKE_MODULE_PATH变量中查找,可以设置多个目录用分号分隔。

  1. 在cmake安装目录下的“share\cmake-[version]\Modules”查找

  1. 以上都没有找到则转入Config模式。

module主要用于库没有提供共Cmake配置(*.cmake)文件。

Config模式

在CONFIG模式中查找-config.cmake或者Config.cmake的配置问题,查找顺序如下:

  1. 查找_ROOT或者_ROOT环境变量

  1. 查找CMAKE_PREFIX_PATH变量,如果设置多个目录用分号分隔。

  1. 查找环境变量_DIR 或者 CMAKE_PREFIX_PATH

  1. 查找HINTS 选项指定的目录。

  1. 在环境变量Path中查找,如果Path中的路径以bin或sbin,搜索时会去掉bin或sbin。

  1. 查找 CMake 用户包注册表中路径,windows下注册表HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\

  1. 查找cmake的系统变量CMAKE_SYSTEM_PREFIX_PATH中的路径

  1. 查找cmake系统注册表,windows下注册表HKEY_LOCAL_MACHINE\Software\Kitware\CMake\Packages\

  1. 查找PATHS参数指定的目录

对于以上每一个目录,会查找以下子目录,W为Windows支持,U为Linux/Unix支持,

CMake Find_Package和Install_第1张图片

其中prefix是查找目录,name是包名或者参数NAMES中指定的名字

通常用法

  1. 程序编译时指定CMAKE_INSTALL_PREFIX="C:/cmake-pkg/"

  1. 如果程序没有提供配置(*.cmake),编写一个Config.cmake配置文件

  1. 编译时使用-DCMAKE_PREFIX_PATH="C:/cmake-pkg/"参数

对应一些cmake内置的模块(Modules目录),需要特别注意,例如ZLIB,当查找ZLIB时需要提供ZLIB_ROOT="C:/cmake-pkg/ZLIB"参数指定ZLIB的安装目录。

Install命令

使用

  1. 生成cmake项目时需要加上参数CMAKE_INSTALL_PREFIX="C:/cmake-pkg/"设置好安装目录

  1. cmake --build [build_dir] --config="debug|release"

  1. Cmake --install [build_dir]

创建

官方参考: https://cmake.org/cmake/help/latest/guide/tutorial/Installing%20and%20Testing.html

  1. 设置Public头文件,也就是要导出的头文件,以及头文件安装目录。

set(target_name libAdd)
project(${target_name} VERSION 1.0)

set_target_properties(${target_name} PROPERTIES PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/head.hpp)

target_include_directories(${target_name} PUBLIC $)
  1. 使用install命令

install(TARGETS ${target_name}
        EXPORT ${target_name}Targets
        LIBRARY DESTINATION lib  # 动态库安装路径
        ARCHIVE DESTINATION lib  # 静态库安装路径
        RUNTIME DESTINATION bin  # 可执行文件安装路径
        PUBLIC_HEADER DESTINATION include/${target_name})  # 头文件安装路径  
  1. 导出位置

install(EXPORT ${target_name}Targets
        DESTINATION lib/cmake/libAdd
        NAMESPACE Add::
        FILE libAddConfig.cmake
        COMPONENT headers)
  1. 生成版本信息,并使用install 导出

set(VERSION_MAJOR "1")
set(VERSION_MINOR "0")
set(VERSION_PATCH "0")

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
        ${PROJECT_BINARY_DIR}/libAddConfigVersion.cmake
        VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
        COMPATIBILITY SameMajorVersion)
install(
        FILES ${PROJECT_BINARY_DIR}/libAddConfigVersion.cmake
        DESTINATION lib/cmake/libAdd
        COMPONENT headers)

引用

这种自动生成的是Config模式,find_package可以找到,只会设置_FOUND变量,以及一个命名空间+库名的Target,这个Target可以直接用target_link_libraries引用。

find_package不会设置_INCLUDE_DIR和_LIBRARY,但是会设置_DIR指向Config.cmake文件目录。

使用步骤如下:

  1. 使用_FOUND确定是否找到库

  1. target_link_libraries 直接使用 命名空间+库名直接引用。

  1. 无需设置include目录,因为返回的库并不是文件名,而是一个Target,这个Target已经设置过了头文件目录。

代码:

find_package(libAdd 1.0 REQUIRED)
if (libAdd_FOUND)
    target_link_libraries(${target_name} Add::libAdd)
else()
    message(FATAL_ERROR "libAdd NOT found")
endif ()

你可能感兴趣的:(编程语言杂记,cmake,Find_Package,Install)