使用cmake -E compare_files比较目录时返回错误结果的疑问
问题解答:CMake compare_files 不支持目录对比
首先明确:cmake -E compare_files 仅支持单个文件的内容对比,完全不支持目录递归对比。你遇到的问题根源就在这里——当你传入目录路径时,该工具不会遍历目录内容,只会判断传入的路径是否指向同一个文件系统实体,这就是为什么两个内容一致但路径不同的目录会返回1,只有路径完全相同时才返回0。
正确的目录对比方案
要实现输出目录与黄金目录的递归对比,可以通过以下两种方式解决:
方式1:编写CMake脚本递归对比文件
创建一个专门的CMake脚本(比如compare_directories.cmake),用来遍历两个目录下的所有文件,逐个调用compare_files对比:
# compare_directories.cmake set(output_dir "${ARGV0}") set(golden_dir "${ARGV1}") # 获取两个目录下的所有文件(保留相对路径结构) file(GLOB_RECURSE output_files RELATIVE "${output_dir}" "${output_dir}/*") file(GLOB_RECURSE golden_files RELATIVE "${golden_dir}" "${golden_dir}/*") # 先检查文件列表是否完全一致 if(NOT output_files STREQUAL golden_files) message(FATAL_ERROR "目录文件列表不一致:\n输出目录文件:${output_files}\n黄金目录文件:${golden_files}") endif() # 逐个对比文件内容 foreach(file_path ${output_files}) set(output_file "${output_dir}/${file_path}") set(golden_file "${golden_dir}/${file_path}") # 跳过嵌套目录 if(IS_DIRECTORY "${output_file}") continue() endif() execute_process( COMMAND "${CMAKE_COMMAND}" -E compare_files "${output_file}" "${golden_file}" RESULT_VARIABLE cmp_result ERROR_VARIABLE cmp_error ) if(cmp_result) message(FATAL_ERROR "文件内容不一致:${file_path}\n错误信息:${cmp_error}") endif() endforeach() message(STATUS "所有文件对比一致")
然后在你的测试中调用这个脚本:
add_test( NAME "cmp_to_golden_${test_name}" COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_SOURCE_DIR}/compare_directories.cmake" "${output_path}" "${golden_path}" )
方式2:使用平台原生工具(注意跨平台兼容性)
如果你的项目只针对特定平台,可以直接调用系统自带的目录对比工具:
- Linux/macOS:使用
diff -r命令 - Windows:使用
fc /s命令
示例:
if(UNIX) add_test( NAME "cmp_to_golden_${test_name}" COMMAND diff -r "${output_path}" "${golden_path}" ) elseif(WIN32) add_test( NAME "cmp_to_golden_${test_name}" COMMAND fc /s "${output_path}" "${golden_path}" ) endif()
这种方式的缺点是跨平台需要做条件判断,且不同工具的输出格式和返回码逻辑可能有差异。
补充说明
CMake官方文档中,compare_files的参数明确标注为<file1> <file2>,没有任何关于目录支持的描述。你看到的“支持目录”的信息应该是误解或错误传播。该工具的核心逻辑是对比两个文件的二进制内容是否完全一致,不具备目录递归对比的能力。
内容的提问来源于stack exchange,提问作者Daniel Barac
相关产品推荐
相关产品推荐

