Bug? add_custom_command() ignores head file outputs

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug? add_custom_command() ignores head file outputs

Adam B
Hello all,

I'm relatively new to CMake but I've encountered some unexpected behavior.  Perhaps it's by design or perhaps it's a bug - you tell me.  The short story is this:

It appears that add_custom_command() is ignored if the only OUTPUT is a C header file (.h).  The generated makefiles do not include the custom command.  However, if I also list a C source file (.c) as a second output, the makefiles get the command.

Here's a simplified setup to reproduce the problem:

---------project_dir/-----------

    CMakeLists.txt
    hello.c
    hello.h
    update_hello_h.sh

--------CMakeLists.txt---------

cmake_minimum_required(VERSION 2.8)
project(cmake_test)

set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM ON)  #so hello.h never gets cleaned away

add_custom_command(OUTPUT hello.h COMMAND ./update_hello_h.sh DEPENDS update_hello_h.sh)

add_executable(hello hello.c)

------------hello.c----------------

#include <stdio.h>
#include "hello.h"
int main(int argc, char ** argv)
{
    printf(HELLO_MSG "\n");
    return 0;
}

-----------hello.h----------------

#define HELLO_MSG "Hello Fri Aug 24 09:01:53 PDT 2012"

-------update_hello_h.sh-----

#!/bin/sh
echo "#define HELLO_MSG" \"Hello `date`\" > hello.h

----------------------------------

What I would expect is for CMake to add a makefile rule to execute ./update_hello_h.sh if it's newer than hello.h.  No such rule gets generated.  However, if you add hello.c like so:

    add_custom_command(OUTPUT hello.h hello.c COMMAND ./update_hello_h.sh DEPENDS update_hello_h.sh)

Then a rule gets generated.  Is this a bug or am I missing something?  I feel like I'm lying to CMake by telling it that hello.c is an output when it really isn't.

I'm using CMake 2.8.0 on Ubuntu 10.04.

Much thanks!
- Adam B.



Videx, Inc. | 1105 NE Circle Blvd. | Corvallis, OR 97330 | (541) 738-5500
This email is intended only for the addressee(s) and may include material that is privileged, confidential, and protected from disclosure.  No contract is intended.  ©2012 Videx, Inc.


--

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
Reply | Threaded
Open this post in threaded view
|

Re: Bug? add_custom_command() ignores head file outputs

Rolf Eike Beer
Adam B wrote:

> Hello all,
>
> I'm relatively new to CMake but I've encountered some unexpected behavior.
> Perhaps it's by design or perhaps it's a bug - you tell me.  The short
> story is this:
>
> It appears that add_custom_command() is ignored if the only OUTPUT is a C
> header file (.h).  The generated makefiles do not include the custom
> command.  However, if I also list a C source file (.c) as a second output,
> the makefiles get the command.
>
> Here's a simplified setup to reproduce the problem:
>
> ---------project_dir/-----------
>
>      CMakeLists.txt
>      hello.c
>      hello.h
>      update_hello_h.sh
>
> --------CMakeLists.txt---------
>
> cmake_minimum_required(VERSION 2.8)
> project(cmake_test)
>
> set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM ON)  #so hello.h never
> gets cleaned away
Who cares, noone builds in the source directory anyway, hm? ;)

> add_custom_command(OUTPUT hello.h COMMAND ./update_hello_h.sh DEPENDS
> update_hello_h.sh)
>
> add_executable(hello hello.c)

Adding hello.h here may fix your problem.


Eike
--

--

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

signature.asc (205 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Bug? add_custom_command() ignores head file outputs

Andreas Pakulat-2
In reply to this post by Adam B
Hi,

On Fri, Aug 24, 2012 at 7:27 PM, Adam B <[hidden email]> wrote:
> Hello all,
>
> I'm relatively new to CMake but I've encountered some unexpected behavior.
> Perhaps it's by design or perhaps it's a bug - you tell me.  The short story
> is this:

It is a bug, but not in CMake, its in your cmake code.

> It appears that add_custom_command() is ignored if the only OUTPUT is a C
> header file (.h).  The generated makefiles do not include the custom
> command.  However, if I also list a C source file (.c) as a second output,
> the makefiles get the command.

If you look at the add_custom_command documentation you'll notice that
it says "if a target defined in the same directory depends on the
output of a custom command a dependency rule is set up so the custom
command runs before the target is being built" (slightly different
wording, written from the top of my head). Your target however only
has the .c file in its source list and hence nothing in your target
depends on an output of the custom command and hence no such rule is
set up. You can either include the .h file in the list of sources for
your target (CMake does not generate compile-rules for files it
recognizes as C/C++ headers), you can setup a custom target that
depends on the .h file and has some no-op as command and make your
executable depend on the custom target or (as you already did) have
the .c file in the output of the custom command.

Andreas
--

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
Reply | Threaded
Open this post in threaded view
|

Re: Bug? add_custom_command() ignores head file outputs

Adam B
On 08/24/2012 11:09 AM, Andreas Pakulat wrote:
Hi,

On Fri, Aug 24, 2012 at 7:27 PM, Adam B [hidden email] wrote:
Hello all,

I'm relatively new to CMake but I've encountered some unexpected behavior.
Perhaps it's by design or perhaps it's a bug - you tell me.  The short story
is this:
It is a bug, but not in CMake, its in your cmake code.

It appears that add_custom_command() is ignored if the only OUTPUT is a C
header file (.h).  The generated makefiles do not include the custom
command.  However, if I also list a C source file (.c) as a second output,
the makefiles get the command.
If you look at the add_custom_command documentation you'll notice that
it says "if a target defined in the same directory depends on the
output of a custom command a dependency rule is set up so the custom
command runs before the target is being built" (slightly different
wording, written from the top of my head). Your target however only
has the .c file in its source list and hence nothing in your target
depends on an output of the custom command and hence no such rule is
set up. You can either include the .h file in the list of sources for
your target (CMake does not generate compile-rules for files it
recognizes as C/C++ headers), you can setup a custom target that
depends on the .h file and has some no-op as command and make your
executable depend on the custom target or (as you already did) have
the .c file in the output of the custom command.
The light comes on!  Thanks for the detailed explanation, Andreas.  Adding the .h file to the executable sources list did the trick.  (And thank you Eike for suggesting that too.)

Andreas




Videx, Inc. | 1105 NE Circle Blvd. | Corvallis, OR 97330 | (541) 738-5500
This email is intended only for the addressee(s) and may include material that is privileged, confidential, and protected from disclosure.  No contract is intended.  ©2012 Videx, Inc.


--

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