本文介绍了如何在cmake add_test中使用重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为foo的控制台应用程序,它使用一个参考文本文件作为输入(in.txt),并在标准输出中生成文本(我想保持这种行为)。



在make(不是cmake)中,我使用一个测试目标,它调用foo并将输出重定向到一个文件(out.txt),如下所示。然后,我使用diff来比较文件out.txt与预期的参照(ref.txt)

  test:
./foo -a test / in.txt> test / out.txt
diff test / out.txt test / ref.txt

使用make工作良好。现在我的问题是; 如何使用cmake创建一个类似的Makefile?



我在一个名为build的子目录中尝试了

  project(foo)
...
add_test(NAME test1 COMMAND ./foo ../test/in.txt>。 ./test/out.txt)
enable_testing()

使用cmake 3.5版本得到一个没有错误的Makefile,但是当我调用 make test 时,测试本身失败。看起来cmake命令 add_test 支持命令行参数,但不支持重定向。我试着报价,逃避失败的成功。因为我不能通过这部分,我没有尝试使用diff。我只是想象,我可以打包foo和diff在一行使用&你可以用bash做。

解决方案

将我的评论转换为答案 b
$ b

正如@Tsyvarev所说,CTest命令不在shell的上下文中运行。但你可以只添加需要自己的shell和使用例如。 sh 作为要使用 add_test()调用的命令。



我使用您的示例代码运行了一些测试,并且以下操作成功:

  add_test(NAME test1 COMMAND sh -c$< TARGET_FILE:foo> ../test/in.txt> ../test/out.txt)

此解决方案不是平台无关的(它取决于在搜索路径中可用的 sh )。






因此,如果你想要更灵活,你可以这样做:

  include(FindUnixCommands)

档案(TO_NATIVE_PATH$ {CMAKE_CURRENT_SOURCE_DIR} /test/in.txt_in)
档案(TO_NATIVE_PATH) $ {CMAKE_CURRENT_SOURCE_DIR} /test/out.txt_out)
if(BASH)
add_test(
NAME test1
COMMAND $ {BASH} -c$< TARGET_FILE :foo> $ {_ in}> $ {_ out}

else()
if(WIN32)
add_test(
NAME test1
COMMAND $ {CMAKE_COMMAND} -E chdir $< TARGET_FILE_DIR:foo> $ ENV {ComSpec} / c$< TARGET_FILE_NAME:foo> $ {_ in}> $ {_ out}

else()
message(FATAL_ERROR$ {CMAKE_HOST_SYSTEM_NAME}的未知shell命令)
endif()
endif()






此外,还可以执行更多平台独立 diff $ {CMAKE_COMMAND} -E compare_files< file1> < file2> 。所以你可以简化你在CMake中完整的基于makefile的示例:

  add_custom_command(
TARGET foo
POST_BUILD
COMMAND $ {CMAKE_COMMAND} -E echoRunning $< TARGET_FILE_NAME:foo> ...
COMMAND foo in.txt> out.txt
WORKING_DIRECTORY $ {CMAKE_CURRENT_SOURCE_DIR} / test


add_test(
NAME test1
COMMAND $ {CMAKE_COMMAND} -E compare_files in.txt out.txt
WORKING_DIRECTORY $ {CMAKE_CURRENT_SOURCE_DIR} / test

参考








I have a console application called "foo", which takes a reference text file as input (in.txt) and generates text at standard output (I want to keep this behaviour).

In make (not cmake), I use a test target, which calls foo and redirects the output to a file (out.txt) as follows. Then, I use diff to compare the file out.txt with the expected refernece (ref.txt)

test:
    ./foo -a test/in.txt > test/out.txt
    diff test/out.txt test/ref.txt

This works fine using make. Now my question is; how can I use cmake to create a similar Makefile?

From within a subdrectory called build, I tried

project(foo)
...
add_test(NAME test1 COMMAND ./foo ../test/in.txt > ../test/out.txt)
enable_testing()

Using cmake version 3.5, I get a Makefile without errors, but when I call make test, the test itself fails. It seems the cmake command add_test supports command line arguments, but not the redirection. I tried quotes and escaping witout success. Since I could not pass this part, I didn't try to use diff. I just imagine that I could pack foo and diff in one line using & as you can do with bash. That would be the second step.

解决方案

Turning my comment into an answer

As @Tsyvarev has stated, CTest commands are not run in a shell's context. But you could just add the shell needed yourself and use e.g. sh as the command to be called with add_test().

I've run some tests with your example code and the following did work successfully:

add_test(NAME test1 COMMAND sh -c "$<TARGET_FILE:foo> ../test/in.txt > ../test/out.txt")

This solution is not platform independent (it depends on sh to be available in the search paths).


So if you want to be more flexible you could do something like:

include(FindUnixCommands)

file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/test/in.txt" _in)
file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/test/out.txt" _out)
if (BASH)
    add_test(
        NAME test1
        COMMAND ${BASH} -c "$<TARGET_FILE:foo> ${_in} > ${_out}"
    )
else()
    if (WIN32)
        add_test(
            NAME test1
            COMMAND ${CMAKE_COMMAND} -E chdir $<TARGET_FILE_DIR:foo> $ENV{ComSpec} /c "$<TARGET_FILE_NAME:foo> ${_in} > ${_out}"
        )
    else()
        message(FATAL_ERROR "Unknown shell command for ${CMAKE_HOST_SYSTEM_NAME}")
    endif()
endif()


Additionally there is the possibility to execute a more platform independent diff with ${CMAKE_COMMAND} -E compare_files <file1> <file2>. So you could simplify your complete makefile based example in CMake with:

add_custom_command(
    TARGET foo
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E echo "Running $<TARGET_FILE_NAME:foo> ..."
    COMMAND foo in.txt > out.txt
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test
)

add_test(
    NAME test1
    COMMAND ${CMAKE_COMMAND} -E compare_files in.txt out.txt
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test
)

References

这篇关于如何在cmake add_test中使用重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 18:22
查看更多