【问题标题】:Expand FindModule.cmake logic with a wrapper file使用包装文件展开 FindModule.cmake 逻辑
【发布时间】:2021-12-26 00:55:30
【问题描述】:

有很多库的包不提供 CMake 配置文件,为了在 cmake 中找到和使用它们,必须使用FindPackage.cmake 脚本。一些脚本(即 SDL)在 cmake 本身中可用,因此查找包相对容易。
尽管在我的例子中,SDL 搜索脚本(SDL、SDL_image、SDL_mixer)几乎从现代 cmake(至少 3.1)诞生之日起就可用,但它们没有提供现代方法的方法——它们没有定义导入的 cmake 目标。 SDL 作为目标仅从 3.19 开始可用,它没有定义 IMPORTED_LOCATION 属性。
因此,合乎逻辑的事情是定义这些目标和属性。
一种天真的方法可能是从较新的 cmake 包中复制 FindSDL.cmake 的内容并粘贴修改。
但我想保留来自 cmake 包(或来自外部源的另一个足够好的脚本)中的这些文件完整并包装它们。
所以,主要的CMakeLists.txt 会是:

list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")
find_package(SDL REQUIRED)
find_package(SDL_mixer REQUIRED)
find_package(SDL_image REQUIRED)

cmake/modules/FindSDL.cmake:

find_package(SDL REQUIRED)

if (NOT TARGET SDL::SDL)
# add target and properties here
endif()

但是,我写它的方式是行不通的,因为无限递归。

在编写使用原始FindPackage.cmake 文件的包装器FindPackage.cmake 时,如何解决find_package 的无限递归?


这看起来很有希望:
How to execute CMake's default find module from my own find module with the same name?

【问题讨论】:

  • 那么,referenced question 中的解决方案是否适合您?据我了解,它应该解决您的第一个问题(避免递归)。至于将参数重定向到内部FindSDL.cmake,您可以尝试通过include 包含它而不是find_packageinclude(FindSDL)
  • @Tsyvarev 它确实适用于第一个问题。对于第二个:用户的主要 CMakeLists 代码应该不知道 FindSDL 是否扩展。 find_package 是搜索包的预期方式
  • 关于你的第二个问题——你看过FindPackageHandleStandardArgs模块吗?
  • @u-235 是的,我有。在find_package(SDL) 之后使用与FindSDL.cmake 相同的参数调用它似乎适用于find_package(SDL REQUIRED)。但我并没有试图弄清楚它的内部结构来重定向find_package(SDL ${ARGS})之类的参数

标签: c++ cmake


【解决方案1】:

首先想到的是在调用find_package()之前从CMAKE_MODULE_PATH中删除当前路径,然后再恢复。

list(REMOVE_ITEM CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
find_package(SDL)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})

if (NOT TARGET SDL::SDL)
# add target and properties here
endif()

【讨论】:

  • Tsyvarev 的回答已经在链接中引用了这一点
  • 存在显着差异 - 在我的情况下,CMAKE_MODULE_PATH 没有完全被覆盖。如果此变量还包含其他路径,这可能很重要。
  • 是的,这确实有意义
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多