# Define a pre-build command without creating a new target

**URL:** <https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623>\
**Category:** Code\
**Tags:** os:linux, gen:makefiles\
**Created:** [July 25, 2020, 6:49pm UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623 "2020-07-25T18:49:27Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Artemis](https://discourse.cmake.org/user_avatar/discourse.cmake.org/artemis/32/616_2.png) [@Artemis](https://discourse.cmake.org/u/Artemis)\
**Post date:** [July 25, 2020, 6:49pm UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/1 "2020-07-25T18:49:27Z")

</div>

After reading Professional CMake (almost) back to back, _I’m once again asking for your support_ 🙃  
I’m struggling to define a fixed pre-build command for a target. I need to generate a header with the current time at every build, and I really don’t want to define a custom target just to do that. Targets are a big deal, they’re global, and need work and attention to be reliable.  
So, out of the three main options to define a custom command, as the book suggests, only `add_custom_command` meets the need.  
From the documentation:

> If `DEPENDS` is not specified, the command will run whenever the `OUTPUT` is missing; if the command does not actually create the `OUTPUT` , the rule will always run.

The idea was to create a custom command with two `OUTPUT`s: the generated header file, which establishes a dependency (and precedence) with the related target (the “light”, automatic dependency is enough in this case), and a dummy one, which causes the command to always trigger.

```cmake
add_custom_command(OUTPUT "foo" "${VisualT_BINARY_DIR}/src/buildDate.h"
                   COMMAND ${CMAKE_COMMAND} -P "${VisualT_BINARY_DIR}/cmake/ConfigureBuildDate.cmake"
                   COMMENT "generating build date header"
                   )
add_library(VisualT_library SHARED "${private_headers}" "${public_headers}" "${sources}") #buildDate.h is contained in "private_headers"

```

It doesn’t work. Most of the times. Sometime it does. There’s definitely something wrong with the outputs because they seem to be order-sensitive. I’ve never managed to get it working with the outputs switched. I’ve never read anything about the output order ?  
What I have now is:

```plaintext
====================[Build | VisualT_library | Debug WSL]=====================
/usr/bin/cmake --build "/mnt/d/Users/Nemo/OneDrive - Universita degli Studi di Udine/Shared/c/VisualT/cmake-build-debug-wsl" --target VisualT_library -- -j 12
[33%] generating build date header
Scanning dependencies of target VisualT_library
[33%] generating build date header
[66%] Building C object src/CMakeFiles/VisualT_library.dir/visualt.c.o
[100%] Linking C shared library libvisualt.so
[100%] Built target VisualT_library

Build finished

```

It’s currently _working_, but it looks like it’s generating the header twice, which is wrong.  
What usually happens is that it says “generating build date header” but no file is generated, and the compilation fails due to a missing header. In the case the library was already up to date, it does the same, but no errors are displayed, as no compilation occurs (and that’s still wrong, since the header should have changed).

With the outputs switched:

> **CMake output**
>
> ```plaintext
> /usr/bin/cmake --build "/mnt/d/Users/Nemo/OneDrive - Universita degli Studi di Udine/Shared/c/VisualT/cmake-build-debug-wsl" --target VisualT_library -- -j 12
> [33%] generating build date header
> Scanning dependencies of target VisualT_library
> [66%] Building C object src/CMakeFiles/VisualT_library.dir/visualt.c.o
> /mnt/d/Users/Nemo/OneDrive - Universita degli Studi di Udine/Shared/c/VisualT/src/visualt.c:3:10: fatal error: buildDate.h: No such file or directory
> #include "buildDate.h"
> ^ ~~~~~~~~~~~~
> compilation terminated.
> src/CMakeFiles/VisualT_library.dir/build.make:89: recipe for target 'src/CMakeFiles/VisualT_library.dir/visualt.c.o' failed
> make[3]: *** [src/CMakeFiles/VisualT_library.dir/visualt.c.o] Error 1
> CMakeFiles/Makefile2:199: recipe for target 'src/CMakeFiles/VisualT_library.dir/all' failed
> make[2]: *** [src/CMakeFiles/VisualT_library.dir/all] Error 2
> CMakeFiles/Makefile2:206: recipe for target 'src/CMakeFiles/VisualT_library.dir/rule' failed
> make[1]: *** [src/CMakeFiles/VisualT_library.dir/rule] Error 2
> Makefile:149: recipe for target 'VisualT_library' failed
> make: *** [VisualT_library] Error 2
> 
> ```

---

<div class="post-metadata">

**Author:** ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)\
**Post date:** [July 27, 2020, 8:04am UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/2 "2020-07-27T08:04:30Z")

</div>

Your idea is not wrong. The dummy output makes sure the custom command is always executed and the generated header file is then part of the target sources.

I cannot immediately spot the problem without a working example. The source is probably build in parallel with its generation.

Before moving on with your question - have you had a look at chapter 19.3 Source Control Commits? It implements the same concept, but differently.

---

<div class="post-metadata">

**Author:** ![Artemis](https://discourse.cmake.org/user_avatar/discourse.cmake.org/artemis/32/616_2.png) [@Artemis](https://discourse.cmake.org/u/Artemis)\
**Post date:** [July 27, 2020, 9:05am UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/3 "2020-07-27T09:05:46Z")

</div>

I’ve made a minimal reproducible example: [dummy.zip](https://discourse.cmake.org/uploads/short-url/nwCcp234sVSHw0JFCO55xz6s4Dq.zip) (1.0 KB)  
The three behaviours I get are:

#### with `add_custom_command(OUTPUT "${dummy_BINARY_DIR}/date.h" "foo"`

> **output**
>
> ```plaintext
> ====================[Build | dummy | Debug]===================================
> /usr/bin/cmake --build /mnt/d/Users/Nemo/Desktop/dummy/cmake-build-debug --target dummy -- -j 12
> Scanning dependencies of target dummy
> [33%] Building C object CMakeFiles/dummy.dir/main.c.o
> /mnt/d/Users/Nemo/Desktop/dummy/main.c:2:10: fatal error: date.h: No such file or directory
> #include "date.h"
> ^ ~~~~~~~
> compilation terminated.
> CMakeFiles/dummy.dir/build.make:88: recipe for target 'CMakeFiles/dummy.dir/main.c.o' failed
> make[3]: *** [CMakeFiles/dummy.dir/main.c.o] Error 1
> CMakeFiles/Makefile2:94: recipe for target 'CMakeFiles/dummy.dir/all' failed
> make[2]: *** [CMakeFiles/dummy.dir/all] Error 2
> CMakeFiles/Makefile2:101: recipe for target 'CMakeFiles/dummy.dir/rule' failed
> make[1]: *** [CMakeFiles/dummy.dir/rule] Error 2
> Makefile:137: recipe for target 'dummy' failed
> make: *** [dummy] Error 2
> 
> ```

#### with `add_custom_command(OUTPUT "foo" "${dummy_BINARY_DIR}/date.h"`

- case 1: ~~the header change doesn’t trigger a recompilation~~ fixed by clearing the CMake cache

> **output**
>
> ```plaintext
> ====================[Build | dummy | Debug]===================================
> /usr/bin/cmake --build /mnt/d/Users/Nemo/Desktop/dummy/cmake-build-debug --target dummy -- -j 12
> [33%] generating build date header
> [100%] Built target dummy
> 
> Build finished
> 
> ```

- case 2: it works, but two “generating” messages are print, which is suspicious

> **output**
>
> ```plaintext
> ====================[Build | dummy | Debug]===================================
> /usr/bin/cmake --build /mnt/d/Users/Nemo/Desktop/dummy/cmake-build-debug --target dummy -- -j 12
> [33%] generating build date header
> Scanning dependencies of target dummy
> [33%] generating build date header
> [66%] Building C object CMakeFiles/dummy.dir/main.c.o
> [100%] Linking C executable dummy
> [100%] Built target dummy
> 
> Build finished
> 
> ```

* * *

> [@hex](#):
>
> Before moving on with your question - have you had a look at chapter 19.3 Source Control Commits? It implements the same concept, but differently.

It implements the same concept, but he runs it at configure time, with `execute_process()`, so he doesn’t really have to handle dependencies.

---

<div class="post-metadata">

**Author:** ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)\
**Post date:** [July 27, 2020, 9:36am UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/4 "2020-07-27T09:36:58Z")

</div>

> [@Artemis](#):
>
> It implements the same concept, but he runs it at configure time, with `execute_process()` , so he doesn’t really have to handle dependencies.

nope, it runs at build time. Try it! 😉

personally I wouldn’t use configure\_file twice, that’s very confusing. Try it in one go. You don’t need ConfigureDate.cmake.in. You can set time and paths directly without the need of execute\_process or custom\_command.

---

<div class="post-metadata">

**Author:** ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)\
**Post date:** [July 27, 2020, 12:33pm UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/5 "2020-07-27T12:33:56Z")

</div>

You are right it runs at configuration time. There is no clean way to generate sources at build time, it is not a good idea anyway since it always forces your build out of date.

Anyway, here is a suggestion:

```cmake
add_custom_command( TARGET dummy
	PRE_BUILD
	COMMAND ${CMAKE_COMMAND} -P ${dummy_SOURCE_DIR}/ConfigureDate.cmake
)

```

This adds an extra build step every time dummy target is build. The command runs CMake in script mode to generate the header file, which is then used to build dummy.

---

<div class="post-metadata">

**Author:** ![Artemis](https://discourse.cmake.org/user_avatar/discourse.cmake.org/artemis/32/616_2.png) [@Artemis](https://discourse.cmake.org/u/Artemis)\
**Post date:** [July 27, 2020, 12:39pm UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/6 "2020-07-27T12:39:34Z")

</div>

That’s exactly what I’d need, but apparently `PRE_BUILD` is supported by the Visual Studio generator only. Even The Book states:

> POST\_BUILD tasks are relatively common, but PRE\_LINK and PRE\_BUILD are rarely needed since they can usually be avoided by using the OUTPUT form of add\_custom\_command() instead (see the next section).

Well they _could_ be avoided if `add_custom_command()` worked as intended.

---

<div class="post-metadata">

**Author:** ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)\
**Post date:** [July 27, 2020, 12:47pm UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/7 "2020-07-27T12:47:15Z")

</div>

hmm, yes I can see that `PRE_BUILD` acts like `PRE_LINK` when using GNU Makefiles generator. The binary contains the time from the previous build 😬

---

<div class="post-metadata">

**Author:** ![fdk17](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/ea666f/32.png) [@fdk17](https://discourse.cmake.org/u/fdk17)\
**Post date:** [July 27, 2020, 4:00pm UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/8 "2020-07-27T16:00:01Z")

</div>

Note that building the example project using the Ninja generator doesn’t show this particular problem with the header file being created twice.

You can see the issue running “make VERBOSE=1” where all the dependency data is invalidated and the custom commands are rerun. Looking at the Makefiles it seems that the dependency file and the target both depend on the output of the custom commands.

This might be an additional reason why custom targets are suggested in this kind of use case. It’ll also should avoid the parallel make error you mentioned (but I wasn’t able to reproduce that problem).

---

<div class="post-metadata">

**Author:** ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)\
**Post date:** [July 27, 2020, 9:06pm UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/9 "2020-07-27T21:06:34Z")

</div>

```auto
[33%] Generating date.h, foo
cmake -P /tmp/test/ConfigureDate.cmake
cd /tmp/test/build && cmake -E cmake_depends "Unix Makefiles" /tmp/test /tmp/test /tmp/test/build /tmp/test/build /tmp/test/build/CMakeFiles/dummy.dir/DependInfo.cmake --color=
Deleting primary custom command output "/tmp/test/build/date.h" because another output "/tmp/test/build/foo" does not exist.
Dependee "/tmp/test/build/CMakeFiles/dummy.dir/DependInfo.cmake" is newer than depender "/tmp/test/build/CMakeFiles/dummy.dir/depend.internal".
Dependee "/tmp/test/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/tmp/test/build/CMakeFiles/dummy.dir/depend.internal".
Scanning dependencies of target dummy

```

`Deleting primary custom command output` -\> I cannot find any explanation on the internet as of why the file has been deleted, and why it hasn’t been created again before building the c object.

The documentation states that `SYMBOLIC` property must be set for `foo` because the file does not exist but this didn’t make any difference.

Dependee messages are normal and generally harmless.

---

<div class="post-metadata">

**Author:** ![Artemis](https://discourse.cmake.org/user_avatar/discourse.cmake.org/artemis/32/616_2.png) [@Artemis](https://discourse.cmake.org/u/Artemis)\
**Post date:** [July 28, 2020, 10:44am UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/10 "2020-07-28T10:44:57Z")

</div>

There’s definitely something weird going on with `add_custom_command()`

---

<div class="post-metadata">

**Author:** ![Artemis](https://discourse.cmake.org/user_avatar/discourse.cmake.org/artemis/32/616_2.png) [@Artemis](https://discourse.cmake.org/u/Artemis)\
**Post date:** [July 31, 2020, 5:07pm UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/11 "2020-07-31T17:07:35Z")

</div>

So is `add_custom_command()`'s behaviour the expected one for the Makefile generator?  
Is it a bug? Is it something else?

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [August 5, 2020, 8:27am UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/12 "2020-08-05T08:27:53Z")

</div>

I was hoping to find time to investigate this one, but that is looking unlikely. If you can provide a minimal example with steps to reproduce the problem (I think the elements are mostly here in this discussion already), please report this as a bug in the issue tracker. Hopefully someone else can then pick it up from there, or explain why the current behavior is like it is (seems a bug from a quick scan through the discussion so far though).

[https://gitlab.kitware.com/cmake/cmake/-/issues/](https://gitlab.kitware.com/cmake/cmake/-/issues/)

---

<div class="post-metadata">

**Author:** ![Artemis](https://discourse.cmake.org/user_avatar/discourse.cmake.org/artemis/32/616_2.png) [@Artemis](https://discourse.cmake.org/u/Artemis)\
**Post date:** [August 5, 2020, 2:13pm UTC](https://discourse.cmake.org/t/define-a-pre-build-command-without-creating-a-new-target/1623/13 "2020-08-05T14:13:43Z")

</div>

The problem was explained in the issue:  
[https://gitlab.kitware.com/cmake/cmake/-/issues/21061](https://gitlab.kitware.com/cmake/cmake/-/issues/21061)

It currently can’t be done, a custom target must be used
