# Prevent rebuild every time for add\_custom\_target

**URL:** https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556
**Category:** Code
**Created:** [December 5, 2023, 3:32am UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556 "2023-12-05T03:32:34Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![fksun](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/7c8e57/32.png) [@fksun](https://discourse.cmake.org/u/fksun)
#### Post date: [December 5, 2023, 3:32am UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/1 "2023-12-05T03:32:34Z")

</div>

Hello all,

When using `add_custom_target` with `ALL` option, I found that the target is built every time I run `ninja`.

Following the guidelines in [https://discourse.cmake.org/t/add-custom-command-rebuilds-every-time/8213](https://discourse.cmake.org/t/add-custom-command-rebuilds-every-time/8213) (Unfortunately no solution is available), I figured out why this happens.

Below is the CMake command:

```auto
add_custom_target(${EXE_NAME} ALL
    COMMAND clang++-14 ${BC_FIN} -o ${EXE_FIN}
    DEPENDS ${BC_FIN}
)

```

And it generates the following `ninja` commands:

```auto
#############################################
# Custom command for CMakeFiles/SameDest

build CMakeFiles/SameDest | ${cmake_ninja_workdir}CMakeFiles/SameDest: CUSTOM_COMMAND SameDest-instrument.bc || librecord_branch.so
  COMMAND = cd <redacted>/build && clang++-14 <redacted>/build/SameDest-instrument.bc -o <redacted>/build/SameDest

```

And `ninja -d explain` says:

```auto
ninja: Entering directory `build'
ninja explain: output CMakeFiles/SameDest doesn't exist
ninja explain: CMakeFiles/SameDest is dirty
ninja explain: SameDest is dirty

```

Obviously, the reason that causes rebuilding every time is `CMakeFiles/SameDest` does not exist, because my custom target does not output to that directory.

I manage to have a simple workaround by setting a link:

```auto
add_custom_target(${EXE_NAME} ALL
    COMMAND clang++-14 ${BC_FIN} -o ${EXE_FIN}
    COMMAND ln -s ${EXE_FIN} ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${EXE_NAME}
    DEPENDS ${BC_FIN}
)  

```

Though everything works fine now, I’m curious about a clean way to build a custom target, i.e. without manually setting a soft link.

* * *

Thanks,  
Fengkai

---

<div class="post-metadata">

### Author: ![fksun](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/7c8e57/32.png) [@fksun](https://discourse.cmake.org/u/fksun)
#### Post date: [December 5, 2023, 3:41am UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/2 "2023-12-05T03:41:27Z")

</div>

P.S. I use `add_custom_target` to invoke `clang` to create binary from bitcode.

Since bitcode is not recognized by `cmake`, `add_executable` will complain about no source file.

`add_custom_command` will not be executed if its `OUTPUT` is not a `DEPEND` of other targets.

---

<div class="post-metadata">

### Author: ![fksun](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/7c8e57/32.png) [@fksun](https://discourse.cmake.org/u/fksun)
#### Post date: [December 5, 2023, 1:19pm UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/3 "2023-12-05T13:19:12Z")

</div>

I’ve made some further inspection, but that only makes me more confused:

When I use:

```auto
add_custom_command(OUTPUT ${EXE_FIN}
        COMMAND clang++-14 ${BC_FIN} -o ${EXE_FIN}
        DEPENDS ${BC_FIN}
)
add_custom_target(${EXE_NAME}-fin ALL
        DEPENDS ${EXE_FIN}
)

```

Then `ninja.build` would create a **phony** comand for this object:

```auto
#############################################
# Phony custom command for CMakeFiles/SameDest-fin

build CMakeFiles/SameDest-fin | ${cmake_ninja_workdir}CMakeFiles/SameDest-fin: phony SameDest || librecord_branch.so

```

I’m not sure what `phony` means, but I guess that is why in the case `ninja` does not try to inspect whether `CMakeFiles/SameDest-fin` is valid, and thus does not trigger a rebuild.

---

<div class="post-metadata">

### Author: ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)
#### Post date: [December 5, 2023, 1:46pm UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/4 "2023-12-05T13:46:28Z")

</div>

> [@fksun](#):
>
> `add_custom_command` will not be executed if its `OUTPUT` is not a `DEPEND` of other targets.

And that leads to the idiomatic way to do this in CMake: create a custom command to produce the output you want (let’s call it `X`), and then create a custom target that will `DEPENDS` on the custom command’s output (`X`). The target will always build, but since it won’t have a `COMMAND`, all it will do is bring its dependencies (i.e. `X`) up to date. If `X` doesn’t exist or is out of date, the custom command will build it. If `X` is up to date, nothing happens.

---

<div class="post-metadata">

### Author: ![fksun](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/7c8e57/32.png) [@fksun](https://discourse.cmake.org/u/fksun)
#### Post date: [December 6, 2023, 2:08am UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/5 "2023-12-06T02:08:31Z")

</div>

Hi Petr,

Thanks for your reply!

> And that leads to the idiomatic way to do this in CMake

Did not know that. Thanks for letting me know!

It’s weird that the behavior of `add_custom_target` without specifying `COMMAND` is not documented, even so many people seem to use it in that way…

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [December 6, 2023, 1:03pm UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/6 "2023-12-06T13:03:44Z")

</div>

> [@fksun](#):
>
> It’s weird that the behavior of `add_custom_target` without specifying `COMMAND` is not documented, even so many people seem to use it in that way…

Can you please [open an issue](https://gitlab.kitware.com/cmake/cmake/-/issues) about the lacking documentation?

---

<div class="post-metadata">

### Author: ![jtxa](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jtxa/32/1535_2.png) [@jtxa](https://discourse.cmake.org/u/jtxa)
#### Post date: [December 6, 2023, 9:39pm UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/7 "2023-12-06T21:39:34Z")

</div>

The linked discourse topic is just a question of some person, there’s no guideline in there.  
That person already used a custom command, which you didn’t. And his cause of rebuilds is most likely the glob for source files, which seems to also include regularly changed `.DS_Store` files from MacOS.

Please rely on the CMake documentation:  
The first paragraph of [add\_custom\_target](https://cmake.org/cmake/help/latest/command/add_custom_target.html) explains the behavior of always building and refers to `add_custom_command` as alternative.  
The second paragraph of [add\_custom\_command](https://cmake.org/cmake/help/latest/command/add_custom_command.html) adds more details and even links an example where that combination is used.

---

<div class="post-metadata">

### Author: ![fksun](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/7c8e57/32.png) [@fksun](https://discourse.cmake.org/u/fksun)
#### Post date: [December 13, 2023, 8:49am UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/8 "2023-12-13T08:49:15Z")

</div>

Haven’t check the mailbox for days. I will do that after finalizing some details. Thanks for your advice!

---

<div class="post-metadata">

### Author: ![fksun](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/f/7c8e57/32.png) [@fksun](https://discourse.cmake.org/u/fksun)
#### Post date: [December 13, 2023, 8:59am UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/9 "2023-12-13T08:59:23Z")

</div>

> The first paragraph of [add\_custom\_target](https://cmake.org/cmake/help/latest/command/add_custom_target.html) explains the behavior of always building and refers to `add_custom_command` as alternative.

I’ve already checked that. But I don’t think ‘always building’ equals to ‘force building’. The latter should be built whenever some changes have been made, while the latter suggests unconditional rebuild.

In my case, `add_custom_target` with specifying `COMMAND` will generate files under `CMakeFiles/<target_name>`, and if user command outputs elsewhere, that directory is never created and thus causing an unwanted **force building** even the source file is unchanged.

> The second paragraph of [add\_custom\_command](https://cmake.org/cmake/help/latest/command/add_custom_command.html) adds more details and even links an example where that combination is used.

Thanks for the link, it does describe the joint use of `add_custom_command` and `add_custom_target`, though the example is not aimed for it. Honestly I only learned how to prevent race condition after reading that, but not creating a custom target without `COMMAND`.

I’m still quite new to CMake, so please correct me if I’m wrong. Thanks!

---

<div class="post-metadata">

### Author: ![jtxa](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jtxa/32/1535_2.png) [@jtxa](https://discourse.cmake.org/u/jtxa)
#### Post date: [December 13, 2023, 9:59pm UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/10 "2023-12-13T21:59:20Z")

</div>

You have to think about, how all build tools work.  
A build rule defines, how an output file is created, and which files are needed (so called dependencies).  
The major task of build tools is to avoid executing all build rules, otherwise you could have written a shell script.  
Makes usually do this by comparing the time stamp of the output file, with all dependencies. And only if a dependency is newer than the output, a rebuild of that rule is necessary. Ninja has some advanced techniques.

As `add_custom_target` explains, it has no output file by definition. In that case, a make cannot compare time stamps, it has to always execute the build rule.  
So by definition it is always built, when the target is called.

For me, the word “force” implies, that you want to force the execution, even if it could be avoided. This is usually the case if you use e.g. `make -B` to force the re-creation of object files and executeables, even if they are up-to-date.

Edit: fixed the `make -B` instead of `make -k`

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [December 19, 2023, 3:18am UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/11 "2023-12-19T03:18:48Z")

</div>

> [@jtxa](#):
>
> This is usually the case if you use e.g. `make -k` or `ninja -k 0` to force the re-creation of object files and executeables, even if they are up-to-date.

The `-k` flags just tell the tools to not stop scheduling new tasks when a command fails (those depending on the failed task are not scheduled however). Perhaps you mean the `make -B` flag (`ninja` has no equivalent)?

> [@jtxa](#):
>
> For me, the word “force” implies, that you want to force the execution, even if it could be avoided.

There’s no “forcing” done though. An `add_custom_target(COMMAND)` has no output and is therefore “never up-to-date” and needs to be run whenever the target is requested. Using the `ALL` flag makes this happen for “default” builds, but otherwise can be used to do things like a “deploy” command that always tries to deploy (whatever that means for the project at hand).

---

<div class="post-metadata">

### Author: ![jtxa](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jtxa/32/1535_2.png) [@jtxa](https://discourse.cmake.org/u/jtxa)
#### Post date: [December 19, 2023, 8:44pm UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/12 "2023-12-19T20:44:57Z")

</div>

@ben.boeckel  
It was too late at night. My mind mixed up the options. I usually use OpusMake where it’s `-a` and I knew it is a different letter on gnumake and picked the wrong one.  
And that what I tried to explain, that only something like `-B` can be named as forced, but `add_custom_target` is simply built always by design.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [December 19, 2023, 9:43pm UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/13 "2023-12-19T21:43:49Z")

</div>

Is there somewhere in CMake docs that say it is “forced”? Or is it just the comment above?

---

<div class="post-metadata">

### Author: ![jtxa](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jtxa/32/1535_2.png) [@jtxa](https://discourse.cmake.org/u/jtxa)
#### Post date: [December 19, 2023, 10:38pm UTC](https://discourse.cmake.org/t/prevent-rebuild-every-time-for-add-custom-target/9556/14 "2023-12-19T22:38:48Z")

</div>

It’s not about the documentation, but this comment:

> [@fksun](#):
>
> I’ve already checked that. But I don’t think ‘always building’ equals to ‘force building’. The latter should be built whenever some changes have been made, while the latter suggests unconditional rebuild.
> 
> In my case, `add_custom_target` with specifying `COMMAND` will generate files under `CMakeFiles/<target_name>`, and if user command outputs elsewhere, that directory is never created and thus causing an unwanted **force building** even the source file is unchanged.
