[CMake] adding a custom command with the file name as a target

Michael Hertling mhertling at online.de
Fri Mar 11 14:30:25 EST 2011


On 03/11/2011 08:00 PM, David Cole wrote:
> On Fri, Mar 11, 2011 at 12:05 PM, Jim Newsome <jnewsome at cmu.edu> wrote:
>> Unfortunately it seems that the target needs to have a different name
>> from its dependencies. When building I get:
>> make[2]: Circular CMakeFiles/hello.bin <- hello.bin dependency dropped.
>>
>> Another workaround I thought of is to change the output filename to,
>> e.g., _hello.bin and have a command in the target to move _hello.bin
>> to hello.bin. Unfortunately this forces _hello.bin to be regenerated
>> every time. I suppose I could work around _that_ by copying instead of
>> moving, but that's getting fairly ugly.
>>
>> On Fri, Mar 11, 2011 at 11:56 AM, Tyler <tyler at cryptio.net> wrote:
>>> The target in the Makefile is created with the add_custom_target()
>>> call. So just change yours to:
>>>
>>> add_custom_target(hello.bin ALL DEPENDS hello.bin)
>>>
>>> hth,
>>> tyler
>>>
>>> On Fri, Mar 11, 2011 at 7:58 AM, Jim Newsome <jnewsome at cmu.edu> wrote:
>>>> I'd like to do something like add_custom_command, with the output file
>>>> name as a target in the generated makefile. Is there an elegant way of
>>>> doing this?
>>>>
>>>> The closest I've come is:
>>>> add_executable (hello hello.c)
>>>> add_custom_command(OUTPUT hello.bin
>>>>                    COMMAND objcopy --output-format=binary hello hello.bin
>>>>                   DEPENDS hello
>>>>                   COMMENT "objcopying hello to hello.bin")
>>>> add_custom_target(bin ALL DEPENDS hello.bin)
>>>>
>>>> However, the target name in the generated makefile is 'bin' rather
>>>> than 'hello.bin'. Is there a way to make 'hello.bin' itself a target
>>>> in the generated makefile?
>>>
>> _______________________________________________
>> 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
>>
> 
> How about making the *named output* of your custom command simply be a
> sentinel file (with a different name) that just happens to produce the
> real file (with the same name as the target)...?
> 
> Something like this:
> 
> add_executable (hello hello.c)
> add_custom_command(OUTPUT hello.bin.sentinel
>                   COMMAND objcopy --output-format=binary hello hello.bin
>                   COMMAND ${CMAKE_COMMAND} -E touch hello.bin.sentinel
>                   DEPENDS hello
>                   COMMENT "objcopying hello to hello.bin")
> add_custom_target(hello.bin ALL DEPENDS hello.bin.sentinel)
> 
> Does that work?

No, you won't have a dependency of the hello.bin custom target on the
hello.bin file, i.e. if the latter is removed, it won't be rebuilt.
Instead, use absolute paths for the custom target's dependencies:

add_executable (hello hello.c)
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/hello.bin
                   COMMAND <hello-to-${CMAKE_BINARY_DIR}/hello.bin>
                   DEPENDS hello
                   COMMENT "objcopying hello to hello.bin")
add_custom_target(hello.bin ALL DEPENDS ${CMAKE_BINARY_DIR}/hello.bin)
                  ^^^^^^^^^             ^^^^^^^^^^^^^^^^^^^

Apparently, that's sufficient to distinguish the hello.bin custom
target from the equally named output file of the custom command.

Regards,

Michael


More information about the CMake mailing list