[CMake] CUSTOM COMMAND triggered several times

Michael Wild themiwi at gmail.com
Fri Aug 21 05:03:44 EDT 2009


Hi Arnaud

Thing is, CMake doesn't do any of the deciding whether something is  
out of date or not. This is delegated to the native build system.  
Let's look at Make. Here, CMake generates a normal rule, looking  
something like this (where I left the CMake-variables unsubstituted):

${${PROJECT_NAME}_WOK_GENERATED_INCLUDE}:  ${${PROJECT_NAME}_CDLS}
	woktcl ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.tcl


This tells Make how to produce the outputs ${$ 
{PROJECT_NAME}_WOK_GENERATED_INCLUDE} which depend on ${$ 
{PROJECT_NAME}_CDLS} using woktcl. And all Make versions I know of  
simply compare modification time stamps. Nothing CMake can do anything  
about, really.

So, what happens in your case probably is the following (and tell me  
if I'm wrong). Your TCL script looks at the CDL files and then decides  
whether it should update the output or not, right? If it doesn't, the  
time-stamp of some of the outputs won't be updated, resulting in Make  
thinking the target is out of date. And since probably more than one  
target depends on the output of your custom-command (if you're  
generating headers, every source file including any of the generated  
headers will depend on the custom command), the custom command will be  
run for every target depending on its output, resulting in your  
multiple executions. Now, the way to solve this is really simple:

ADD_CUSTOM_COMMAND(
    OUTPUT ${${PROJECT_NAME}_WOK_GENERATED_INCLUDE}
    COMMAND woktcl ARGS ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.tcl
    COMMAND ${CMAKE_COMMAND} ARGS -E touch ${$ 
{PROJECT_NAME}_WOK_GENERATED_INCLUDE
    DEPENDS ${${PROJECT_NAME}_CDLS}
    COMMENT "Generating ${PROJECT_NAME} include files from CDLs"
  )

The line I added just ensures that the modification time of all output  
files will be updated, no matter whether your script made any changes  
or not.

I hope this helps

Michael

PS: I notice you replied to Tyler directly. Please keep your messages  
on the list, such that others can profit from the discussion (and can  
follow it). For most mail-clients this works best by just hitting  
"reply-to-all". The mailing list (with the default settings) is then  
smart enough to not send a duplicate to people figuring in the To: and  
Cc: fields.

On 21. Aug, 2009, at 10:24, Arnaud Devalkeneer wrote:

> Hello Tyler,
>
> I am not fully agree with your opinion.
>
> In my case, I can't change the command behaviour I call. So I must  
> tune
> cmake scripts to make it works.
> In other words, the sentence :
> " If the DEPENDS are newer than the
> OUTPUT, then the OUTPUT *must* be out of date and should be  
> regenerated."
> is a too strong assumption in my case.
>
> More comparison between last make execution time AND last modified
> dependency times must be enough to make cmake awares of
> custom command triggering in a general case (like for source files I  
> guess).
> Mustn't it?
>
> Anyway there is a workaround using temporary files, but it is not so
> beautifull...
>
> Thanks a lot for your support.
>
> Arnaud.
>
> On Wed, Aug 19, 2009 at 5:13 PM, Tyler Roscoe <tyler at cryptio.net>  
> wrote:
>
>> Putting this back on the list.
>>
>> On Wed, Aug 19, 2009 at 01:55:14PM +0200, Arnaud Devalkeneer wrote:
>>> I just understood the cmake behaviour.
>>> In fact cmake seems to compare last modified times for output and
>>> dependencies.
>>> If the dependencies are younger than the output, the command is
>> triggered.
>>> Right?
>>>
>>> But if the custom command has its own state machine to decide if the
>> output
>>> should be re-generated according to dependencies change,
>>> this mechanism does not work if the output is not regenerated. In  
>>> this
>> case,
>>> the output always remains older than dependencies, and the command  
>>> is
>> always
>>> called.
>>>
>>> In my mind I thought that cmake behaviour is ONLY based on last make
>>> executing time and last modified dependencies times. But it seems  
>>> not !!
>>> It seems that a comparaison between last modified times of output  
>>> and
>>> dependencies occurs which is I think an error in a general purpose.
>>> Cmake should not make assumption about user command, and potential  
>>> update
>> of
>>> the output. Are you agree with that?
>>
>> Maybe I'm not understanding you, but are you saying that you don't  
>> want
>> CMake to check whether the OUTPUT is out of date, just the DEPENDS  
>> are
>> out of date? That doesn't make sense. If the DEPENDS are newer than  
>> the
>> OUTPUT, then the OUTPUT *must* be out of date and should be  
>> regenerated.
>>
>> tyler
>>
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake



More information about the CMake mailing list