find_file

简短的签名是

find_file (<VAR> name1 [path1 path2 ...])

一般的签名是

find_file (
          <VAR>
          name | NAMES name1 [name2 ...]
          [HINTS [path | ENV var]... ]
          [PATHS [path | ENV var]... ]
          [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
          [PATH_SUFFIXES suffix1 [suffix2 ...]]
          [VALIDATOR function]
          [DOC "cache documentation string"]
          [NO_CACHE]
          [REQUIRED]
          [NO_DEFAULT_PATH]
          [NO_PACKAGE_ROOT_PATH]
          [NO_CMAKE_PATH]
          [NO_CMAKE_ENVIRONMENT_PATH]
          [NO_SYSTEM_ENVIRONMENT_PATH]
          [NO_CMAKE_SYSTEM_PATH]
          [NO_CMAKE_INSTALL_PREFIX]
          [CMAKE_FIND_ROOT_PATH_BOTH |
           ONLY_CMAKE_FIND_ROOT_PATH |
           NO_CMAKE_FIND_ROOT_PATH]
         )

此命令用于查找命名文件的完整路径。一个缓存条目,如果指定了NO_CACHE,则一个名为<VAR>的普通变量用于存储此命令的结果。如果找到了文件的完整路径,则将结果存储在变量中,并且搜索不会重复,除非清除变量。如果什么都没有找到,结果将为<VAR>-NOTFOUND

选项包括

NAMES

指定文件的完整路径的一个或多个可能名称。

在使用此项指定带和不带版本后缀的名称时,我们建议先指定未设置版本号的名称,以便可以在那些由发行版提供的包之前找到本地构建的包。

HINTS, PATHS

指定除了默认位置外要搜索的目录。ENV var子选项从系统环境变量中读取路径。

3.24版中已更改:Windows平台上,可以使用专用语法,将注册表查询作为目录的一部分包括在内。此类规范将在所有其他平台上被忽略。

REGISTRY_VIEW

在3.24版中添加。

指定必须查询哪个注册表视图。此选项仅在Windows平台上有意义,在其他平台上将被忽略。未指定时,会在CMP0134策略为NEW时使用TARGET视图。策略为OLD时的默认视图,请参见CMP0134

64

查询64位注册表。在32位Windows系统中,它总是返回字符串/REGISTRY-NOTFOUND

32

查询32位注册表。

64_32

查询两个视图(6432),并为每个视图生成一个路径。

32_64

查询两个视图(3264),并为每个视图生成一个路径。

HOST

查询与主机架构匹配的注册表:64位Windows系统上的64和32位Windows系统上的32

TARGET

查询注册表与 CMAKE_SIZEOF_VOID_P 变量指定的架构匹配。如果没有定义,则回退到 HOST 视图。

BOTH

查询这两个视图(3264)。顺序取决于以下规则:如果 CMAKE_SIZEOF_VOID_P 变量已定义,请根据该变量的内容使用以下视图

  • 8: 64_32

  • 4: 32_64

如果 CMAKE_SIZEOF_VOID_P 变量未定义,则依赖于主机的架构

  • 64 位:64_32

  • 32 位:32

PATH_SUFFIXES

指定必须在每处目录位置下方检查的额外子目录。

VALIDATOR

在 3.25 版中新增。

指定一个 function(),以便在找到的每个候选项目中调用(则不能提供 macro(),这样会导致发生错误)。将向验证器函数传递两个参数:结果变量的名称和候选项目的绝对路径。除非函数将结果变量中的值在调用范围内设置为 false,否则将接受该项目并且搜索将结束。输入验证器函数时,结果变量将保存一个 true 值。

function(my_check validator_result_var item)
  if(NOT item MATCHES ...)
    set(${validator_result_var} FALSE PARENT_SCOPE)
  endif()
endfunction()

find_file (result NAMES ... VALIDATOR my_check)

请注意,如果使用了缓存结果,则会跳过搜索并且会忽略任何 VALIDATOR。缓存的结果不必通过验证函数。

DOC

指定 <VAR> 缓存条目的文档字符串。

NO_CACHE

在 3.21 版中新增。

搜索结果将存储在标准变量中,而不是缓存条目中。

注意

如果在调用之前已经设置该变量(作为标准或缓存变量),则不会执行搜索。

警告

应谨慎使用此选项,因为它会极大增加重复配置步骤的成本。

REQUIRED

在 3.18 版中新增。

如果什么也没找到,则停止处理并显示一条错误消息,否则在使用相同变量再次调用 find_file 时再次尝试执行搜索。

如果指定了 NO_DEFAULT_PATH,则不向搜索中添加其他路径。如果没有指定 NO_DEFAULT_PATH,则搜索过程如下

  1. 如果从 find 模块内或由调用 find_package(<PackageName>) 加载的任何其他脚本中进行调用,搜索要查找的当前软件包独有的前缀。请参阅策略 CMP0074

    在版本 3.12 中添加。

    具体来说,按顺序搜索由以下变量指定搜索路径

    1. <PackageName>_ROOT CMake 变量,其中 <PackageName> 是区分大小写的软件包名称。

    2. <PACKAGENAME>_ROOT CMake 变量,其中 <PACKAGENAME> 是大写软件包名称。请参阅策略 CMP0144

      在版本 3.27 中添加。

    3. <PackageName>_ROOT 环境变量,其中 <PackageName> 是区分大小写的软件包名称。

    4. <PACKAGENAME>_ROOT 环境变量,其中 <PACKAGENAME> 是大写软件包名称。请参阅策略 CMP0144

      在版本 3.27 中添加。

    软件包根变量保留为堆栈,因此如果从嵌套的查找模块或配置软件包调用,则会在从当前模块或软件包的路径之后搜索父查找模块或配置软件包的根路径。换句话说,搜索顺序应为 <CurrentPackage>_ROOTENV{<CurrentPackage>_ROOT}<ParentPackage>_ROOTENV{<ParentPackage>_ROOT},依此类推。如果传递了 NO_PACKAGE_ROOT_PATH 或将 CMAKE_FIND_USE_PACKAGE_ROOT_PATH 设置为 FALSE,则可以跳过此步骤。

  2. 在cmake特定缓存变量中指定的搜索路径。建议与-DVAR=value一起在命令行中使用。这些值被解释为用分号分隔的列表。如果传递了NO_CMAKE_PATH或者设置了CMAKE_FIND_USE_CMAKE_PATHFALSE,则可以跳过此步骤。

  3. 在 cmake 特定环境变量中指定搜索路径。这些旨在在用户的 shell 配置中设置,因此使用宿主的本机路径分隔符(Windows 上为 ;,UNIX 上为 :)。如果传递 NO_CMAKE_ENVIRONMENT_PATH 或将 CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH 设置为 FALSE,则可以跳过。

  4. 搜索由 HINTS 选项指定的路径。这些应该是通过系统自省计算的路径,例如已找到的另一项的位置提供的提示。应使用 PATHS 选项指定硬编码的猜测。

  5. 搜索标准系统环境变量。如果传递 NO_SYSTEM_ENVIRONMENT_PATH 或将 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH 设置为 FALSE,则可以跳过。

    • INCLUDEPATH 中的目录。

    在 Windows 主机上,CMake 3.3 至 3.27 搜索的其他路径:如果 CMAKE_LIBRARY_ARCHITECTURE 已设置,则为 <prefix>/include/<arch>,对于 PATH 中的每个 <prefix>/[s]bin,则为 <prefix>/include,对于 PATH 中的其他条目,则为 <entry>/include。CMake 3.28 已删除此行为。

  6. 在当前系统的 Platform 文件中搜索定义的 CMake 变量。如果传递 NO_CMAKE_INSTALL_PREFIX 或将 CMAKE_FIND_USE_INSTALL_PREFIX 设置为 FALSE,则可跳过搜索 CMAKE_INSTALL_PREFIXCMAKE_STAGING_PREFIX。如果传递 NO_CMAKE_SYSTEM_PATH 或将 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH 设置为 FALSE,则可跳过所有这些位置。

    这些变量所包含的平台路径通常包含已安装软件的位置。基于 UNIX 的平台的一个示例是 /usr/local

  7. 搜索 PATHS 选项指定的路径或在命令的简写版本中。这些通常是硬编码猜测。

变量 CMAKE_IGNORE_PATHCMAKE_IGNORE_PREFIX_PATHCMAKE_SYSTEM_IGNORE_PATHCMAKE_SYSTEM_IGNORE_PREFIX_PATH 还可以导致忽略以上一些位置。

在 3.16 版中添加了: 添加了 CMAKE_FIND_USE_<CATEGORY>_PATH 变量以全局禁用各种搜索位置。

在 macOS 中,CMAKE_FIND_FRAMEWORKCMAKE_FIND_APPBUNDLE 变量决定了偏好在 Apple 风格和 Unix 风格的包组件之间的顺序。

CMake 变量 CMAKE_FIND_ROOT_PATH 指定一个或多个将预先添加到所有其他搜索目录中的目录。此操作实际上是在给定位置下“重新根植”了整个搜索。是 CMAKE_STAGING_PREFIX 子级的路径被排除在此次重新根植之外,因为该变量始终是主机系统上的路径。默认情况下,CMAKE_FIND_ROOT_PATH 为空。

CMAKE_SYSROOT 变量也可用于指定恰好一个目录以用作前缀。设置 CMAKE_SYSROOT 还有其他作用。请参阅该变量的文档了解更多信息。

当进行交叉编译以指向目标环境的根目录时,这些变量特别有用,而 CMake 也将在那里搜索。默认情况下,一开始会在 CMAKE_FIND_ROOT_PATH 中列出的目录中进行搜索,然后搜索 CMAKE_SYSROOT 目录,然后搜索非根目录。可以通过设置 CMAKE_FIND_ROOT_PATH_MODE_INCLUDE 来调整默认行为。可以使用选项手动按每次调用覆盖此行为

CMAKE_FIND_ROOT_PATH_BOTH

按照上面描述的顺序搜索。

NO_CMAKE_FIND_ROOT_PATH

不使用 CMAKE_FIND_ROOT_PATH 变量。

ONLY_CMAKE_FIND_ROOT_PATH

仅搜索重新根植的目录和 CMAKE_STAGING_PREFIX 以下的目录。

默认的搜索顺序设计为对常见用例从最具体的到最不具体的。项目可以简单地多次调用命令并使用 NO_* 选项来覆盖顺序

find_file (<VAR> NAMES name PATHS paths... NO_DEFAULT_PATH)
find_file (<VAR> NAMES name)

一旦其中一个调用成功,结果变量将被设置并在缓存中存储,这样就不会再有调用进行搜索了。