Cmake override find_package for a given target

问题

我们有一个 CMakeLists.txt,它将(例如)opencv 链接到我们的各种二进制文件。 这是按如下方式完成的:

find_package(OpenCV REQUIRED core imgproc highgui contrib) 
target_link_library(XXX opencv_core)

我们还希望允许构建库的人提供自己的 opencv 库。 似乎这可以通过将 -DCMAKE_PREFIX_PATH 设置为正确的路径来完成。

cmake -DCMAKE_PREFIX_PATH=".../mybuild/include;.../mybuild/lib" .  

但是我想确保使用的库正是客户端指定的库(即,如果 /mybuild/lib 中没有任何内容,则配置失败)。

如何允许构建库的人覆盖使用的库? (如果没有指定它应该回退到 find_package-s)

回答1

简而言之

  1. 如果包提供<package>Config.cmake脚本,用户可以指定<package>_DIR CMake 变量来定位这个脚本。

    在这种情况下,可以使用find_package()NO_DEFAULT_PATH选项禁用搜索其他地方。

  2. 如果使用Find<package>.cmake脚本搜索包,如果用户提供了提示变量但它是错误的,则没有(通用)方法可以禁用搜索其他地方。

解释

首先, CMAKE_PREFIX_PATH为所有包提供了额外的安装树。 由于此变量适用于所有find_package()调用,因此要求在其下找到所有包是不明智的。

在谈到为特定包指定安装目录的方法时,我们需要区分两种“查找”脚本:

  1. <package>Config.cmake (或一些替代名称,请参阅 find_package 文档)。

    这些脚本随软件包本身一起提供。 并且有一种通用的方法供用户指定此类包的位置:CMake 变量<package>_DIR ,它应该指向带有*Config.cmake脚本的目录。

    虽然find_package()的默认行为将<package>_DIR变量视为附加提示,但传递NO_DEFAULT_PATH选项会禁用所有隐式路径:

     if(<package>_DIR) # Variable is set by the user or by previous `cmake` run. # Search only under given directory. find_package(<package> NO_DEFAULT_PATH) else() # Search everywhere (as documented for 'find_package'). find_package(<package>) endif()
  2. Find<package>.cmake

    该脚本要么随 CMake 提供,要么应随项目提供。

    大多数此类脚本允许使用变量(CMake 或环境之一)提示包位置,例如<package>_DIR<package>_ROOT

    但是,几乎所有此类脚本都将提示变量仅视为附加搜索位置,因此如果将变量设置为错误值,它们会简单地忽略它。 如果不修改脚本,您将无法更改该行为。

标签

更多相关内容:请点击查看