[CMake] building tests
Marcel Loose
loose at astron.nl
Thu Jul 8 07:22:46 EDT 2010
On Thu, 2010-07-08 at 16:30 +0800, Paul Harris wrote:
>
>
> On 8 July 2010 16:27, Marcel Loose <loose at astron.nl> wrote:
>
> On Thu, 2010-07-08 at 11:12 +0800, Paul Harris wrote:
> >
> >
> > On 7 July 2010 23:38, Marcel Loose <loose at astron.nl> wrote:
> >
> > On Wed, 2010-07-07 at 17:05 +0200, Michael Wild
> wrote:
> > > On 7. Jul, 2010, at 16:01 , Paul Harris wrote:
> > >
> > > > Hi all,
> > > >
> > > > I have looked and can't find the answer, so I
> turn to the
> > list.
> > > >
> > > > I have a CMakeLists.txt and a subdirectory
> called utils,
> > which also
> > has its
> > > > own CMakeLists.txt
> > > >
> > > > In the parent CML.txt, I have something like:
> > > >
> > > > ENABLE_TESTING()
> > > > add_subdirectory(utils)
> > > >
> > > > In my utils CML.txt, I have
> > > >
> > > > ADD_EXECUTABLE(unit_1 units/unit_1.cpp)
> > > > ADD_TEST( unit_1
> ${EXECUTABLE_OUTPUT_PATH}/unit_1 )
> > > >
> > >
> > > Simplify this to
> > >
> > > ADD_TEST(unit_1 unit_1)
> > >
> > > CMake will figure out by itself that unit_1 is a
> target and
> > invoke the
> > executable correctly (your code would break for
> > multi-configuration IDE
> > generators).
> > >
> > > As for the dependencies, I agree that it would be
> nice if
> > the "test"
> > target depended on the executables. But what is
> wrong with
> > "make all
> > test" (apart from the fact that it possibly compiles
> more than
> > you
> > actually need to run the test)? You could also wrap
> the
> > add_executable
> > call in a custom function which creates a custom
> target (say
> > test_exes)
> > and makes it depend on all the executables:
> > >
> > > function(add_test_executable name)
> > > if(NOT TARGET ${name})
> > > add_custom_target(test_exes)
> > > endif()
> > > add_executable(${name} ${ARGN})
> > > add_dependencies(test_exes ${name})
> > > endfunction()
> > >
> > > Then you can do "make test_exes test".
> > >
> > > HTH
> > >
> > > Michael
> >
> >
> > You can further reduce the number of targets that
> get
> > (re)build by going
> > into the directory '${CMAKE_BINARY_DIR}/utils' and
> invoke
> > 'make' there.
> >
> > You could also define a 'check' target that will
> build and run
> > all your
> > test programs. See
> > http://www.cmake.org/Wiki/CMakeEmulateMakeCheck
> >
> > Best regards,
> > Marcel Loose.
> >
> >
> > Thanks Marcel, I combined the solution in the wiki with what
> was
> > discussed in my last email, and I ended up with
> >
> > set (CMAKE_TEST_COMMAND "ctest")
> >
> > function (add_unit_test name)
> > if(NOT TARGET ${name})
> > add_custom_target (check COMMAND
> ${CMAKE_TEST_COMMAND})
> > endif()
> > add_executable(${name} ${ARGN})
> > # or ADD_EXECUTABLE(${name} ${ARGN} EXCLUDE_FROM_ALL)
> > # if you want it to be skipped when building 'all'
> > add_test(${name} ${EXECUTABLE_OUTPUT_PATH}/${name})
> > add_dependencies(check ${name})
> > endfunction()
> >
> >
> >
> > however, I have discovered (with message()) that
> ${CMAKE_TEST_COMMAND}
> > is *empty* - its something I had to set(), which is not
> mentioned in
> > the wiki page you mentioned. It IS kind-of-mentioned in
> "Cmake
> > Scripting of CTest" but not explicitly enough to catch the
> eye.
> >
> > I've edited the wiki page, please check that my edits make
> sense.
> >
> > Thanks
> > Paul
>
> Hi Paul,
>
>
> While re-reading you add_unit_test function above I was
> wondering
> whether this will actually work. The snippet
>
> if(NOT TARGET ${name})
> add_custom_target (check COMMAND ${CMAKE_TEST_COMMAND})
> endif()
>
> strikes me as odd. This will cause multiple definitions of the
> 'check'
> target, which is not allowed, unless you set a policy (don't
> know by
> heart which one exactly). Anyway, multiple definitions of the
> same
> target are only supported by Unix Makefiles; I don't think you
> want to
> restrict yourself unnecessarily.
>
>
>
> this was suggested by Michael in this email thread.
> I thought it might be better to move the add_custom_target to before
> the function - ie always declare it once only. I guess the idea of
> the test is to only register the target once.
>
>
Hmm,
Maybe I missed that mail -- I couldn't find it in my mailbox -- but my
guess is that Michael wrote something like:
if(NOT TARGET check)
add_custom_target (check COMMAND ${CMAKE_TEST_COMMAND})
endif()
You can put that snippet in a macro like my_add_test(), which would then
look something like this:
macro(my_add_test _name)
if(NOT TARGET check)
add_custom_target (check COMMAND ${CMAKE_TEST_COMMAND})
endif()
add_executable(${_name} ${ARGN})
add_test(${_name} ${_name})
add_dependencies(check ${_name})
endmacro(my_add_test)
Of course there's nothing wrong with declaring the custom target 'check'
once (that's the way I do it too). Be sure you do that before the first
call to add_dependencies(), though, otherwise you'll get a CMake error.
Best regards,
Marcel Loose.
More information about the CMake
mailing list