[CMake] piping commands to executable

Michael Hertling mhertling at online.de
Fri May 20 05:05:28 EDT 2011


On 05/18/2011 07:46 PM, Yngve Inntjore Levinsen wrote:
> Dear developers,
> 
> I have a bit of an issue with ctest. In our project we usually generate a binary which we pipe in scripts with the commands we want to execute (some defined parser language). Now at first I would have liked to do something like
> ADD_TEST(testsample "executable < script.txt") 
> ADD_TEST(testsample executable < script.txt) 
> or perhaps
> ADD_TEST(testsample "executable" "< script.txt") 
> 
> The first one fails because "executable < script.txt" is not found anywhere. The second and third just hangs (the executable will enter interactive mode if it does not get anything piped in, much like how python behaves).
> 
> I solved this before by adding tests which were executing a simple bash script, where the command
> executable < script.txt
> was added. This works, but then when I want to do memory checks etc, that will not work since the memory check is done on the bash script and not the actual process (or so it seems to me). Is there any clever solution on how to pipe commands into an interpreter. As an example, you could show me how to do this test perhaps:
> echo 'print "hello"' | python
> 
> I apologize if I am using wrong terms or if this is easily found in the documentation. My understanding of piping in and out and right and left is slightly limited...
> 
> 
> Thanks,
> Yngve

AFAIK, I/O redirection is not supported in tests, see [1,2], so you
should actually use a shell script or the like to achieve your goal.
Regarding the memory checking issue, cf. [3], have you already tried
to invoke the executable to be tested by the shell's "exec" builtin?
This results in the shell's process to be replaced by the executable,
so there will be only *one* process spawed by ctest, and the memory
checker should get it right - not tested, just a spontaneous idea.
Look at the following CMakeLists.txt for an example:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(PIPETEST C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
ENABLE_TESTING()
FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.c
"#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
    int c;
    printf(\"PID=%d (executable)\\n\",getpid());
    while ((c=fgetc(stdin))!=EOF) fputc(c,stdout);
    return 0;
}\n")
ADD_EXECUTABLE(main main.c)
FILE(WRITE ${CMAKE_BINARY_DIR}/input.txt "Hello from stdin!\n")
FILE(WRITE ${CMAKE_BINARY_DIR}/main.sh
"echo \"PID=\$\$ (shell)\"
exec $1 < $2\n")
ADD_TEST(NAME pipetest
    COMMAND sh ${CMAKE_BINARY_DIR}/main.sh
    $<TARGET_FILE:main> ${CMAKE_BINARY_DIR}/input.txt)

The main executable prints its PID and copies the standard input to
standard output. It's invoked by the main.sh shell script via "exec"
with standard input read from the input.txt file after printing the
shell's PID. When performing the test with "ctest -V", you'll see
that both PIDs are the same; without "exec", they would differ.

'hope that helps.

Regards,

Michael

[1] http://www.mail-archive.com/cmake@cmake.org/msg02175.html
[2] http://www.mail-archive.com/cmake@cmake.org/msg30402.html
[3] http://www.mail-archive.com/cmake@cmake.org/msg16075.html


More information about the CMake mailing list