[CMake] Unit tests, but not CTest

Michael Hertling mhertling at online.de
Fri May 14 17:28:36 EDT 2010


On 05/14/2010 08:24 AM, Magnus Therning wrote:
> On 14/05/10 01:14, Michael Hertling wrote:
>> On 05/13/2010 10:43 AM, Magnus Therning wrote:
> [...]
>>> It's not ideal.
>>>
>>> I'm writing some CMake scripts to ease the use of OCaml with CMake.  There are
>>> basically two macros at this point:
>>>
>>> • add_ocaml_library()
>>> • add_ocaml_executable()
>>>
>>> Both of them can somewhat simplistically be thought of as just wrappers around
>>> add_custom_command().  In some cases the OCaml executable is a unit test,
>>> which means I'd like the executable to be run after being built. [...]
>>
>> OK, as far as I understand your concern, you have two separate tasks:
>>
>> (1) (Re)build the executable using ADD_CUSTOM_COMMAND() and,
>> (2) in some cases, run it as a unit test after its (re)build.
>>
>> IMO, these two can't be adequately expressed as Make-time dependencies: Who
>> depends on who? Of course, (1) on (2) does not, but vice versa does not
>> succeed, also, since you want *(1)* to trigger (2) after (1) itself has been
>> rebuilt, and this is nothing you can explain to Make as usual dependencies
>> between two targets unless you are willing to trigger (2) explicitly when
>> you mean (1). Thus, you can't use ADD_CUSTOM_TARGET() to achieve the desired
>> workflow via pure target interdependencies, and since
>> ADD_CUSTOM_COMMAND(TARGET ... POST_BUILD) which would probably do the job
>> isn't applicable in your case it turns out that (2) - even if optional -
>> should be integrated in (1) manually.
> 
> Thanks for this analysis, it makes the problem a lot clearer to me.  One thing
> it doesn't clarify is how ADD_CUSTOM_COMMAND( TARGET ... POST_BUILD ) could
> *ever* be useful. [...]

ADD_CUSTOM_COMMAND(TARGET ...) enhances the commands associated with
the named target, i.e. you can hook into that target's build process:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)

PROJECT(CUSTOM_COMMAND_DEMO C)

FILE(WRITE main.c "void main(){}")
ADD_EXECUTABLE(exe main.c)

ADD_CUSTOM_COMMAND(TARGET exe PRE_BUILD COMMAND echo "Pre build")
ADD_CUSTOM_COMMAND(TARGET exe POST_BUILD COMMAND echo "Post build")

After cmaking, look at the end of CMakeFiles/exe.dir/build.make:

[...]
exe: CMakeFiles/exe.dir/main.c.o
exe: CMakeFiles/exe.dir/build.make
exe: CMakeFiles/exe.dir/link.txt
        @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --red
--bold "Linking C executable exe"
        echo Pre\ build
        $(CMAKE_COMMAND) -E cmake_link_script
CMakeFiles/exe.dir/link.txt --verbose=$(VERBOSE)
        echo Post\ build
[...]

Thus, ADD_CUSTOM_COMMAND(TARGET ...) doesn't modify the dependencies of
the named target but the associated commands. So, it provides a general
possibility to have arbitrary commands run when a target is (re)built.

> [...] I'm still to see an example of any buildable target that
> such a post-build command can be connected to and only triggered on (re)build.

Imagine your add_ocaml_executable() using ADD_EXECUTABLE() instead of
ADD_CUSTOM_COMMAND(OUTPUT ...); in this case, you would have a, say,
fully-fledged CMake target which additional commands can be attached
to by ADD_CUSTOM_COMMAND(TARGET ...), and indeed, that is a suitable
place for your automated unit testing. Obviously, CMake's file-level
targets defined by ADD_CUSTOM_COMMAND(OUTPUT ...) are not sufficient
for this purpose although they appear as usual Make targets if others
depend on them, but so, you've to specify the desired commands right
in the ADD_CUSTOM_COMMAND(OUTPUT ...). Perhaps, this would be worth
a feature request.

Regards,

Michael


More information about the CMake mailing list