如何让CMake的find_package指令输出所有已找到包的信息?
解决CMake全局输出find_package找到包的简洁信息问题
CMake本身没有专门的内置开关让所有find_package()调用都输出类似CUDAToolkit、Python的简洁找到信息,但可以通过以下两种方式实现需求:
1. 利用CMAKE_FIND_PACKAGE_MESSAGE_LEVEL变量
对于遵循规范、使用find_package_handle_standard_args()函数的官方或第三方find模块,设置该变量可强制输出找到包的状态信息:
- 命令行配置时添加:
cmake .. -DCMAKE_FIND_PACKAGE_MESSAGE_LEVEL=STATUS - 原理:该变量控制
find_package_handle_standard_args()的输出级别,设为STATUS后,符合规范的模块会自动打印类似-- Found <PackageName>: ...的信息。 - 局限性:如果某个find模块调用
find_package_handle_standard_args()时显式指定了NO_MESSAGE选项,此方法无效,但绝大多数官方模块不会这么做。
2. 全局包装find_package宏
如果上述方法覆盖不全,可以在项目顶层CMakeLists.txt的最开头添加以下代码,全局替换默认的find_package行为,自动打印找到的包信息:
macro(find_package) # 调用原生的find_package实现 _find_package(${ARGV}) # 检查包是否找到 if(${CMAKE_FIND_PACKAGE_NAME}_FOUND) set(_output_msg "Found ${CMAKE_FIND_PACKAGE_NAME}: ") # 尝试获取包的路径信息(适配不同包的变量命名) if(DEFINED ${CMAKE_FIND_PACKAGE_NAME}_DIR) string(APPEND _output_msg "${${CMAKE_FIND_PACKAGE_NAME}_DIR}") elseif(DEFINED ${CMAKE_FIND_PACKAGE_NAME}_ROOT) string(APPEND _output_msg "${${CMAKE_FIND_PACKAGE_NAME}_ROOT}") elseif(DEFINED ${CMAKE_FIND_PACKAGE_NAME}_INCLUDE_DIR) string(APPEND _output_msg "${${CMAKE_FIND_PACKAGE_NAME}_INCLUDE_DIR}") elseif(DEFINED ${CMAKE_FIND_PACKAGE_NAME}_INCLUDE_DIRS) string(APPEND _output_msg "${${CMAKE_FIND_PACKAGE_NAME}_INCLUDE_DIRS}") endif() # 添加版本信息(如果存在) if(DEFINED ${CMAKE_FIND_PACKAGE_NAME}_VERSION) string(APPEND _output_msg " (found version \"${${CMAKE_FIND_PACKAGE_NAME}_VERSION}\")") endif() # 输出标准格式的信息 message(STATUS "${_output_msg}") endif() endmacro()
- 这个宏会先执行原生的
find_package逻辑,再自动检查包的查找结果,拼接路径和版本信息后输出,格式和官方模块的输出保持一致。 - 可根据项目中使用的包的变量命名习惯,调整宏中的路径变量判断逻辑,适配更多特殊包。
注:
CMAKE_FIND_DEBUG_MODE=ON会输出大量底层调试细节(如查找路径、尝试的文件等),不符合简洁输出的需求,因此不推荐使用。
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

