CMake教程11:find_package/find_libary/find_path

926 阅读3分钟

相关变量

PackageName_INCLUDE_DIRS

基本用法

find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS components...]
             [NO_POLICY_SCOPE])

查找并加载模块,如果找到模块,<PackageName>_FOUND会被设置,并指明模块的位置。

version参数需要和包版本一致(版本号格式为:major.minor.patch.tweak)

EXACT选项要求版本是否完全一致。

QUIET选项禁用信息,如果模块不是REQUIRED,也会找不到。

REQUIREDCOMPONENTSOPTIONAL_COMPONENTS选项的书写顺序不能乱。

查找模块有2个模式:Module模式Config模式,默认使用的是Module模式

如果Module模式没有找到模块,命令将使用Config模式,如果给定了MODULE选项,则不会使用Config模式

在Module模式,CMake查找Find<PackageName>.cmake文件,首先在CMAKE_MODULE_PATH中查找,然后再CMake安装所提供的模块中查找。

用户可以设置CMAKE_FIND_PACKAGE_PREFER_CONFIG变量为TRUE,让CMake优先使用Config模式。

详细的模块查找过程(翻译的官方文档)

find_packge完成的参数列表

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])

CMake有非常多的<prefix>变量,比如CMAKE_PREFIX_PATHCMAKE_INSTALL_PREFIX等等。

CMake在查找模块的时候,会将搜索目录自动补全<prefix>,不同操作系统的默认搜索目录如下:

NAMES参数和下边的<name>对应,相当于别名

如果使用了NAMES选项,就会使用NAMES选项后的列表中的名称作为包名搜索<PackageName>Config.cmake文件/<package-name>-config.cmake 文件

<prefix>/                                                       (Windows)
<prefix>/(cmake|CMake)/                                         (Windows)
<prefix>/<name>*/                                               (WindowsW)
<prefix>/<name>*/(cmake|CMake)/                                 (Windows)
<prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/                 (Unix)
<prefix>/(lib/<arch>|lib*|share)/<name>*/                       (Unix)
<prefix>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/         (Unix)
<prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/         (Windows/Unix)
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/               (Windows/Unix)
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/ (Windows/Unix)
<prefix>/<name>.framework/Resources/                            (Apple)
<prefix>/<name>.framework/Resources/CMake/                      (Apple)
<prefix>/<name>.framework/Versions/*/Resources/                 (Apple)
<prefix>/<name>.framework/Versions/*/Resources/CMake/           (Apple)
<prefix>/<name>.app/Contents/Resources/                         (Apple)
<prefix>/<name>.app/Contents/Resources/CMake/                   (Apple)
  • 在Window平台,<prefix>指向应用程序安装目录
  • 在Unix平台,<prefix>是共享的。
  • 在Apple平台CMAKE_FIND_FRAMEWORKCMAKE_FIND_APPBUNDLE变量决定了优先顺序。

<name>不区分大小写,来自是<PackageName>或者CMake变量NAMES的值。

如果设置了PATH_SUFFIXES,在window和Unix上,每个目录都会追加这个后缀。

当设置CAME_LIBRARY_ARCHITECTURE变量,lib/<arch>将会启用,lib*的可选值有lib64、lib32、libx32、lib(按照顺序搜索)

  • FIND_LIBRARY_USE_LIB64_PATHS属性设置为TRUE,在64位平台上,lib64将会查找
  • FIND_LIBRARY_USE_LIB32_PATHS属性设置为TRUE,在32位平台上,lib32将会查找
  • FIND_LIBRARY_USE_LIBX32_PATHS属性设置为TRUE,在x32架构的平台上,libx32将会查找
  • lib目录永远都会查找

安装前缀是通过以下步骤构建的,如果指定了NO_DEFAULT_PATH,所有的NO_*选项启用了

  1. 搜索CMake的<PackageName>_ROOT变量,以及环境变量<PackageName>_ROOT,包的root变量是堆栈变量,调用模块的父模块的root 路径也将会进行搜索,通过传递了NO_PACKAGE_ROOT_PATH,或者将CMAKE_FIND_USE_PACKAGE_ROOT_PATH设置位FALSE,都可以跳过这个行为。

  2. 搜索指定的CMake变量。这些变量可以通过命令行-D var=value设置,value;分割的列表。

    传递NO_CMAKE_PATH、设置CMAKE_FIND_USE_CMAKE_PATHFALSE可以跳过该步骤。

    CMAKE_PREFIX_PATH
    CMAKE_FRAMEWORK_PATH
    CMAKE_APPBUNDLE_PATH
    
  3. 搜索CMake指定的环境变量。 这些变量在用户的shell配置中设置,因此使用主机的本地路径分割(windows ; Unix :)。

    传递NO_CAMKE_EVVIRONMENT_PATH、设置CMAKE_FIND_USE_CMKAE_ENVIRONMENT_PATHFALSE跳过该步骤。

    <PackageName>_DIR
    CMAKE_PREFIX_PATH
    CMAKE_FRAMEWORK_PATH
    CMAKE_APPBUNDLE_PATH
    
  4. 搜索HINTS选项设置的路径。这些路径是系统自动计算出来的,比如由另一个本地已经找到的提供。硬编码的话,应该用PATHS选项指定。

  5. 搜索系统环境变量。如果路径的结尾是/bin/sbin会自动转换到父目录。

    传递了NO_SYSTEM_ENVIRONMENT_PATH、设置CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATHFALSE可以跳过该步骤,

  6. 搜索CMake User Package Registry

  7. 搜索当前系统平台文件中定义的CMake变量

    传递NO_CMAKE_SYSTEM_PATHCMAKE_FIND_USE_CMAKE_SYSTEM_PATHFALSE来跳过该步骤。

    CMAKE_SYSTEM_PREFIX_PATH
    CMAKE_SYSTEM_FRAMEWORK_PATH
    CMAKE_SYSTEM_APPBUNDLE_PATH
    
  8. 搜索CMake System Package Registry

  9. 搜索PATHS选项指定的路径,通常这些都是硬编码。

find_libary

会自动查找带lib开头的库,比如

find_library (libvar math ./dir)

./dir目录下,查找名字为math的库,如果找到了,会将路径赋值给libvar,实际上也会查找libmath的库,即会自动增加前缀lib

find_path

搜索指定头文件路径。