Fractale
Fractale

Reputation: 1644

CMake and add test program command

I use usually makefile for project but I want to start learn CMake. I use makefile not only for build my project but also to test my project. It's very useful. How can I do that with CMake?

For exemple this makefile:

pathword=words.txt
flags=-std=c++11 -Wall -Wextra -g -Og
#flags=-std=c++11 -O3 -DNDEBUG -s

default: TextMiningCompiler TextMiningApp

TextMiningCompiler: TextMiningCompiler.cpp trie.cpp
    g++ $(flags) TextMiningCompiler.cpp trie.cpp -o TextMiningCompiler

TextMiningApp: TextMiningApp.cpp
    g++ $(flags) TextMiningApp.cpp -o TextMiningApp

run: TextMiningCompiler TextMiningApp
    ./TextMiningCompiler $(pathword) totoro.txt
    cat test.txt | time ./TextMiningApp totoro.txt

clean:
    trash TextMiningCompiler TextMiningApp

I made this CMakefile:

cmake_minimum_required(VERSION 2.8.9)
project (TextMining)
add_executable(TextMiningApp TextMiningApp.cpp)
add_executable(TextMiningCompiler TextMiningCompiler.cpp trie.cpp read_words_file.cpp)
set_property(TARGET TextMiningApp PROPERTY CXX_STANDARD 11)
set_property(TARGET TextMiningCompiler PROPERTY CXX_STANDARD 11)

How can I have the make run function? or other custom function?

Upvotes: 10

Views: 22505

Answers (2)

Florian
Florian

Reputation: 42902

When it gets to tests in CMake I prefer to use add_test(). It enables - besides calling something like make test to run the tests - the possibility to e.g. get test reports via (distributed with CMake).

Using the name of an executable's CMake target as "command" in add_test() directly replaces it with the excutable's path:

cmake_minimum_required(VERSION 2.8.9)
project (TextMining)

enable_testing()

set(CMAKE_CXX_STANDARD 11)
set(pathword "${CMAKE_SOURCE_DIR}/words.txt")

add_executable(TextMiningCompiler TextMiningCompiler.cpp trie.cpp read_words_file.cpp)
add_test(
    NAME TestTextMiningCompiler 
    COMMAND TextMiningCompiler "${pathword}" "totoro.txt"
)

add_executable(TextMiningApp TextMiningApp.cpp)
add_test(
    NAME TestTextMiningApp 
    COMMAND sh -c "cat ${CMAKE_SOURCE_DIR}/test.txt | time $<TARGET_FILE:TextMiningApp> totoro.txt"
)
set_tests_properties(TestTextMiningApp PROPERTIES DEPENDS TestTextMiningCompiler)

You could further eliminate the dependency to a shell like sh if you would add a commandline parameter to TextMiningApp to pass test.txt as input:

add_test(
    NAME TestTextMiningApp 
    COMMAND TextMiningApp -i "${CMAKE_SOURCE_DIR}/test.txt" "totoro.txt"
)

And no need to add a time call since total time of execution is automatically measured when executing the test via make test (which is btw. equivalent to calling ctest):

$ make test
Running tests...
Test project [... path to project's binary dir ...]
    Start 1: TestTextMiningCompiler
1/2 Test #1: TestTextMiningCompiler ...........   Passed    0.11 sec
    Start 2: TestTextMiningApp
2/2 Test #2: TestTextMiningApp ................   Passed    0.05 sec

100% tests passed, 0 tests failed out of 2

Total Test time (real) =   0.19 sec

Reference

Upvotes: 25

Tsyvarev
Tsyvarev

Reputation: 65928

Command add_custom_target

Adds a target with the given name that executes the given commands.

Usage is straightforward:

add_custom_target(run
     COMMAND ./TextMiningCompiler <pathword> totoro.txt
     COMMAND cat test.txt | time ./TextMiningApp totoro.txt
)
add_dependencies(run TextMiningCompiler TextMiningApp)

Upvotes: 1

Related Questions