如何从我自己的同名查找模块中执行CMake的默认查找模块?

Posted

技术标签:

【中文标题】如何从我自己的同名查找模块中执行CMake的默认查找模块?【英文标题】:How to execute CMake's default find module from my own find module with the same name? 【发布时间】:2019-07-24 14:03:16 【问题描述】:

出于某种原因,如果 CMake 的 FindThreads 失败,我想扩展一个查找模块(在我的情况下为 FindThreads)来做一些特定的事情。对于我们软件系统其他部分的普通开发人员来说,这应该是透明的,这样他/她可以像往常一样调用find_package(Threads),所以我不想给自己的查找模块一个专有名称。

我的想法是将我自己的FindThreads.cmake 添加到包含在CMAKE_MODULE_PATH 的文件夹中。因为CMAKE_MODULE_PATH有优先级find_package(Threads)会执行我自己的FindThreads.cmake

但是,在我自己的FindThreads.cmake 中,我需要执行find_package(Threads ...) 以便它执行CMake 的原始FindThreads.cmake怎么做?

如果我自己的FindThreads.cmake 失败了,应该尝试添加一个特定的线程库。

不幸的是,find_package 没有选项 NO_CMAKE_MODULE_PATH 可以退回到 CMake 自己的查找模块,并且似乎无法将搜索路径(例如 $CMAKE_ROOT/Modules)传递给 find_package 以覆盖 @ 987654337@.

版本

Linux 上的 CMake 3.5 (Ubuntu 16.04) Windows 上的 CMake 3.14

【问题讨论】:

【参考方案1】:

您可以在find_package调用之前设置CMAKE_MODULE_PATH,并在调用之后恢复变量:

# Save old value of CMAKE_MODULE_PATH.
set(CMAKE_MODULE_PATH_OLD $CMAKE_MODULE_PATH)
# Temporary replace CMAKE_MODULE_PATH
set(CMAKE_MODULE_PATH "$CMAKE_ROOT/Modules")
# Call find_package() with specific CMAKE_MODULE_PATH set.
find_package(Threads ...)
# Restore CMAKE_MODULE_PATH
set(CMAKE_MODULE_PATH $CMAKE_MODULE_PATH_OLD)

请注意,FindXXX.cmake 与调用者代码在同一作用域 中执行,因此即使您的脚本不再调用find_package 而只是返回,也需要恢复CMAKE_MODULE_PATH 变量。

另外,最好使用一些unique 变量的name 而不是CMAKE_MODULE_PATH_OLD:调用者可能已经出于自己的目的使用了该变量。例如。您可以在变量名称中添加一些与您的组织相关或不太可能被其他人使用的后缀。

【讨论】:

谢谢,虽然我希望没有这种临时上下文更改的解决方案,但这应该可以工作。我对此感到有点不舒服,因为未来的开发人员可能不会注意到它。为了避免CMAKE_MODULE_PATH_OLD 的范围问题,我将尝试将整个代码放在一个函数中以确保安全。

以上是关于如何从我自己的同名查找模块中执行CMake的默认查找模块?的主要内容,如果未能解决你的问题,请参考以下文章

CMake:覆盖查找模块

jquery 节点查找(查同名 class 的下一个)

Oracle ebs 中如何查找银行流水

find_package()的查找*.cmake的顺序

如何使用Git子模块和CMake处理传递依赖冲突?

CMake基础教程(26)find_package搜索包完成库链接和头文件添加(module模式)