CMake 3中如何实现Catch2的可选find_package并规避警告?
在CMake 3中检查Catch2并自动获取的正确方法
针对CMake 3不支持OPTIONAL关键字的问题,有两种可靠方案可以实现静默检查系统是否安装Catch2,未安装则通过FetchContent拉取,同时避免查找失败时的警告:
方案一:用QUIET关键字抑制警告(简洁首选)
find_package的QUIET关键字在CMake 3全版本中都支持,它会直接抑制查找失败时的警告信息,仅通过Catch2_FOUND变量判断结果:
# 获取Catch2 if(TARGET Catch2::Catch2) message(STATUS "${PROJECT_NAME} > 从父项目获取到Catch2") else() # 静默查找Catch2 3.x版本,不输出警告 find_package(Catch2 3 QUIET) message(STATUS "${PROJECT_NAME} > 尝试find_package(Catch2 3) 结果:${Catch2_FOUND}") if(TARGET Catch2::Catch2) message(STATUS "${PROJECT_NAME} > 顶层项目 - 通过find_package获取到Catch2") else() message(STATUS "${PROJECT_NAME} > 顶层项目 - 通过FetchContent拉取Catch2") include(FetchContent) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG v3.8.1 # 可替换为更新的稳定版本 ) FetchContent_MakeAvailable(Catch2) endif() endif()
方案二:先检查Find模块是否存在(更严谨)
如果需要先确认系统中是否有FindCatch2.cmake模块文件,再决定是否执行查找逻辑,可以遍历CMake的模块路径进行检查:
# 获取Catch2 if(TARGET Catch2::Catch2) message(STATUS "${PROJECT_NAME} > 从父项目获取到Catch2") else() # 检查系统是否存在FindCatch2.cmake模块 set(CATCH2_HAS_FIND_MODULE OFF) foreach(module_path ${CMAKE_MODULE_PATH} ${CMAKE_ROOT}/Modules) if(EXISTS "${module_path}/FindCatch2.cmake") set(CATCH2_HAS_FIND_MODULE ON) break() endif() endforeach() if(CATCH2_HAS_FIND_MODULE) # 存在模块时才执行查找,同时用QUIET抑制警告 find_package(Catch2 3 QUIET) message(STATUS "${PROJECT_NAME} > 尝试find_package(Catch2 3) 结果:${Catch2_FOUND}") endif() if(TARGET Catch2::Catch2) message(STATUS "${PROJECT_NAME} > 顶层项目 - 通过find_package获取到Catch2") else() message(STATUS "${PROJECT_NAME} > 顶层项目 - 通过FetchContent拉取Catch2") include(FetchContent) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG v3.8.1 # 可替换为更新的稳定版本 ) FetchContent_MakeAvailable(Catch2) endif() endif()
关键说明:
QUIET是CMake 3.x的原生参数,能直接解决查找失败时的警告问题,是最常用的简洁方案。- 方案二更适合对依赖来源有严格要求的场景,避免在没有对应Find模块时执行无效的查找操作。
内容的提问来源于stack exchange,提问作者xealits
相关产品推荐
相关产品推荐

