[CMake] Unit tests, but not CTest

Magnus Therning magnus at therning.org
Thu May 13 04:43:53 EDT 2010


On Thu, May 13, 2010 at 07:46, Michael Hertling <mhertling at online.de> wrote:
> On 05/13/2010 07:36 AM, Magnus Therning wrote:
>> On 13/05/10 02:31, Michael Hertling wrote:
>>> On 05/11/2010 10:51 AM, Magnus Therning wrote:
>>>> I'm still having problems with this.
>>>>
>>>> I put together this:
>>>>
>>>>     project( test-post-build NONE )
>>>>     cmake_minimum_required( VERSION 2.8 )
>>>>
>>>>     set( output ${CMAKE_CURRENT_BINARY_DIR}/foo )
>>>>     add_custom_command( OUTPUT ${output}
>>>>         COMMAND touch ${output}
>>>>         COMMENT "Touching foo"
>>>>         )
>>>>     add_custom_target( foo.build ALL DEPENDS ${output} )
>>>>
>>>>     add_custom_command( TARGET ${output}
>>>>         POST_BUILD
>>>>         COMMAND echo "POST_BUILD ${output}"
>>>>         )
>>>>
>>>>     add_custom_command( TARGET foo.build
>>>>         POST_BUILD
>>>>         COMMAND echo "POST_BUILD foo.build"
>>>>         )
>>>>
>>>> Based on your description above I expected this behaviour:
>>>>
>>>>     % cmake ..
>>>>     -- Configuring done
>>>>     -- Generating done
>>>>     -- Build files have been written to:
>>>> /home/magnus/Play/test/cmake/post_build/_build
>>>>     % make
>>>>     Scanning dependencies of target foo.build
>>>>     [  0%] Touching foo
>>>>     POST_BUILD /home/magnus/Play/test/cmake/post_build/_build/foo
>>>>     POST_BUILD foo.build
>>>>     [100%] Built target foo.build
>>>>     % make
>>>>     POST_BUILD foo.build
>>>>     [100%] Built target foo.build
>>>>
>>>> However, that's not the case.  I only ever see the 'POST_BUILD foo.build'
>>>> printed. [...]
>>>
>>> AFAIK, this is because your "add_custom_command(TARGET ${output} ...)"
>>> is not associated with an actual target but with just a file whereas
>>> "add_custom_command(TARGET foo.build ...)" actually refers to a target
>>> "foo.build" defined by ADD_CUSTOM_TARGET(). Indeed, you may issue any
>>> ADD_CUSTOM_COMMAND(TARGET ...) for undefined targets without causing
>>> an error, but their commands will never be executed, of course.
>>>
>>>> [...] So, what target can I use to get the desired behaviour of the
>>>> POST_BUILD only being run after an actual build?
>>>
>>> Just use a target - but really a target - after whose rebuild you like
>>> to have your post-build custom commands being run.
>>>
>>> Hope this helps.
>>
>> I'm sorry, but it doesn't :-(  I have two POST_BUILD commands above, one
>> attached to the creation of a file and one to a target.  The former I thought
>> was attached to the creation of a file (the OUTPUT of a command) the latter to
>> a custom target (which depends on the OUTPUT of the former).  The former is
>> *never* run, the latter is *always* run.  The explanations in this thread so
>> far has explained why CMake behaves this way, but how do I make the creation
>> of the file into "a target - but really a target" so I can attach the
>> POST_BUILD command to it?
>>
>> Would you mind correcting my CMake script from above as an example of how it
>> can be done?
>>
>> I have the following:
>>
>>      project( test-post-build NONE )
>>      cmake_minimum_required( VERSION 2.8 )
>>
>>      set( output ${CMAKE_CURRENT_BINARY_DIR}/foo )
>>      add_custom_command( OUTPUT ${output}
>>          COMMAND touch ${output}
>>          COMMENT "Touching foo"
>>          )
>>
>> I now want the text "POST_BUILD" echoed to stdout iff the command to create
>> ${output} is run.  (With the explanations I've gotten in this thread so far I
>> don't even see how that can be done.)
>
> OK, I see. Perhaps, the solution for your concern is pretty easy: Try
>
>     add_custom_command( OUTPUT ${output}
>         COMMAND touch ${output}
>         COMMAND echo "POST_BUILD ${output}"
>         COMMENT "Touching foo"
>         )
>
> and forget the "add_custom_command( TARGET ${output} ... )". This just
> means that the latter's command is directly tied to the generation of
> ${output}, and so, you even get exactly what you expected at first:
>
> % cmake ..
> -- Configuring done
> -- Generating done
> -- Build files have been written to: [...]
> % make
> Scanning dependencies of target foo.build
> [  0%] Touching foo
> POST_BUILD [...]/foo
> POST_BUILD foo.build
> [100%] Built target foo.build
> % make
> POST_BUILD foo.build
> [100%] Built target foo.build
>
> In other words, there would be no need to attach additional commands to
> ADD_CUSTOM_COMMAND(OUTPUT ...) via ADD_CUSTOM_COMMAND(TARGET ...), but
> one can specify them directly within the former, and for more complex
> operations, one can use ADD_CUSTOM_COMMAND()'s DEPENDS option to
> trigger arbitrary targets when the OUTPUT is regenerated.
>
> Is this the desired behaviour?

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.  Ideally I'd
like to write macros that would be used this way:

    add_ocaml_executable( myexe ... )
    add_ocaml_unittest( myexe )

However, if I understand you correctly that wouldn't be possible.  Instead
I'll have to either create a specific macro for an executable that is a unit
test, or pass a flag to add_ocaml_executable().

/M

-- 
Magnus Therning                        (OpenPGP: 0xAB4DFBA4)
magnus@therning.org          Jabber: magnus@therning.org
http://therning.org/magnus         identi.ca|twitter: magthe


More information about the CMake mailing list