如何指定find_package命令使用的Find[Package].cmake文件路径?
find_package 使用的Find[Package].cmake文件位置 这个问题在CMake开发里挺常见的——当你有多个同名的Find模块时,CMake总是优先选了不是你想要的那一个。下面给你几个靠谱的解决办法,按场景选就行:
方法1:调整CMAKE_MODULE_PATH的顺序(全局生效)
CMake查找Find模块时,会按CMAKE_MODULE_PATH里的目录顺序依次查找,同时也会检查系统默认的模块路径。如果你的/A目录在CMAKE_MODULE_PATH里的位置比/B靠前,或者/A是系统默认路径的一部分,那肯定会优先用/A/FindX.cmake。
解决办法就是把/B目录插入到CMAKE_MODULE_PATH的最前面,确保CMake先找这里的模块:
# 一定要在调用find_package(X)之前执行这段代码 list(INSERT CMAKE_MODULE_PATH 0 "/B") # 现在调用find_package就会优先找/B下的FindX.cmake了 find_package(X REQUIRED)
list(INSERT 0 ...)是把目标目录放到列表的第一个位置,比用list(APPEND)更可靠,因为APPEND是加到末尾,还是会被前面的目录抢先。
方法2:给find_package直接指定模块路径(仅本次调用生效)
如果你不想修改全局的CMAKE_MODULE_PATH,只针对X包的查找指定路径,CMake 3.21及以上版本支持MODULE_PATH参数,直接在find_package里指定:
find_package(X REQUIRED MODULE_PATH "/B")
这个方法更精准,不会影响其他包的查找逻辑,推荐在只需要单独调整某个包的查找路径时使用。
方法3:临时修改并恢复CMAKE_MODULE_PATH(安全全局临时生效)
如果你的项目里还有其他包需要用原来的CMAKE_MODULE_PATH顺序,你可以先保存原路径,用完再恢复,避免影响后续查找:
# 保存当前的CMAKE_MODULE_PATH状态 list(APPEND CMAKE_MODULE_PATH_BACKUP "${CMAKE_MODULE_PATH}") # 把/B放到最前面 list(INSERT CMAKE_MODULE_PATH 0 "/B") # 查找X包 find_package(X REQUIRED) # 恢复原来的CMAKE_MODULE_PATH set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH_BACKUP}") unset(CMAKE_MODULE_PATH_BACKUP)
这个方法很适合在复杂项目里用,既能临时指定路径,又不会破坏其他模块的查找逻辑。
额外提醒
不管用哪种方法,都要确保/B/FindX.cmake是符合CMake Find模块规范的——比如要正确设置X_FOUND、X_INCLUDE_DIRS、X_LIBRARIES这些标准变量,否则find_package可能会报错或者找不到正确的包信息。
内容的提问来源于stack exchange,提问作者Benjamin Horowitz

