CMake:回显文件时的unescape空白

时间:2017-04-23 14:27:17

标签: cmake

作为构建过程的一部分,我们会在实际构建期间通过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,其工作方式如下:

  • 它回显命令行并将其保存到输出文件
  • 它通过valgrind运行测试,将所有输出保存到输出文件
  • 如果测试没有通过,它将捕获输出文件并且命令失败
  • 如果测试通过,它将触及传递的sentinel文件。

这是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

2 个答案:

答案 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需要外部双引号,不要将回声参数分开)。