作为构建过程的一部分,我们会在实际构建期间通过valgrind自动运行单元测试(即:它不是单独的目标,例如make test
)
我们在测试通过时创建一个sentinel文件,以便后续构建在没有必要的情况下不会重新运行测试。
我们还将命令行和测试输出保存到文件中。
这里我构建了valgrind命令行:
set(VALGRIND_BIN "valgrind")
set(VALGRIND_OPTS "--leak-check=full --track-origins=yes")
set(VALGRIND_CMD "${VALGRIND_BIN} ${VALGRIND_OPTS}")
separate_arguments(VALGRIND_CMD)
这些是"通过" sentinal文件和测试输出文件。
set(OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/${ARG_NAME}.output)
set(PASSED_FILE ${CMAKE_CURRENT_BINARY_DIR}/${ARG_NAME}.passed)
我在这里添加custom_command
,其工作方式如下:
这是cmake来源:
add_custom_command(
OUTPUT
${PASSED_FILE}
COMMAND
echo "\"${VALGRIND_BIN} ${VALGRIND_OPTS} $<TARGET_FILE:${TEST_NAME}>\"" > ${OUTPUT_FILE}
COMMAND
${VALGRIND_CMD} $<TARGET_FILE:${TEST_NAME}> >> ${OUTPUT_FILE} 2>&1 || (cat ${OUTPUT_FILE} && false)
COMMAND
${CMAKE_COMMAND} -E touch ${PASSED_FILE}
COMMENT
"Running ${ARG_NAME} tests"
DEPENDS
${TEST_NAME}
USES_TERMINAL
)
不幸的是,cmake正在逃避测试命令行的echo
中的所有空格,因此输出文件中的第一行看起来像这样:
valgrind\ --leak-check=full\ --track-origins=yes\ /home/steve/src/test\
我已经向自己证明了变量中的转义,就好像我输出了message
它们不在那里。
message(STATUS "\"${VALGRIND_BIN} ${VALGRIND_OPTS} $<TARGET_FILE:${TEST_NAME}>\"")
结果输出:
-- "valgrind --leak-check=full --track-origins=yes $<TARGET_FILE:test>"
问题:
如何在回显文件时 unescape 空格?
也就是说,我怎么能让这条线不是这样的:
valgrind\ --leak-check=full\ --track-origins=yes\ /home/steve/src/test\
但改为:
valgrind --leak-check=full --track-origins=yes /home/steve/src/test
答案 0 :(得分:2)
您可以将所有内容放入列表中,该列表将被展开,并且不会转义空格。
因为如果CMake认为字符串是单个参数,那么它将转义空格。将其作为列表将每个元素作为单独的参数:
WHERE v.First_Aid = 'yes'
<强>参考强>
答案 1 :(得分:0)
正如@MuertoExcobito指出的,选项 VERBATIM 关心正确转义参数,不需要手动转义其他双引号:
COMMAND
echo "${VALGRIND_BIN} ${VALGRIND_OPTS} $<TARGET_FILE:${TEST_NAME}>" > ${OUTPUT_FILE}
VERBATIM
(CMake需要外部双引号,不要将回声参数分开)。