# Running postbuild tasks with ninja

**URL:** https://discourse.cmake.org/t/running-postbuild-tasks-with-ninja/13623
**Category:** Code
**Tags:** os:windows, gen:ninja
**Created:** [February 23, 2025, 10:18am UTC](https://discourse.cmake.org/t/running-postbuild-tasks-with-ninja/13623 "2025-02-23T10:18:17Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![noahdav](https://discourse.cmake.org/user_avatar/discourse.cmake.org/noahdav/32/4950_2.png) [@noahdav](https://discourse.cmake.org/u/noahdav)
#### Post date: [February 23, 2025, 10:18am UTC](https://discourse.cmake.org/t/running-postbuild-tasks-with-ninja/13623/1 "2025-02-23T10:18:17Z")

</div>

Hi,

We have been using the visual studio generators and it seems to work for the most part but there are a few issues that we are trying to solve that are not supported with the visual studio generators. We have been looking at using Ninja instead. It seems to solve these problems but it has its own issues. With visual studio we use POST\_BUILD command to kick off the the signing and then copying the files (after signing completes) to a know folder structure. This code is quite complex and has extensive use of generator expressions to try to figure out the where the files get copied for each target.

Now that we are looking into using Ninja we are running into issues with the post build, My understanding is that ninja is starting the postbuild once the target is built but it does not wait for the linker to complete. Therefore these post build targets are unable to find the final created files.

I have tried to add dependencies in the target that post build runs but this causes circular dependencies that Ninja cannot deal with. I have also tried to make the Ninja post build wait for the target to link but this does not seem to work in all of our cases.

```auto
add_custom_command(TARGET ${TARGET_NAME}
    POST_BUILD
    DEPENDS $<TARGET_FILE:${TARGET_NAME}>
    COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${postbuild_target} --config $<CONFIG>
    COMMENT "Running postbuild ${TARGET_NAME}")

```

This works fine with the VS generators. Does anyone have any suggestions to how to make Ninja wait for the linker to complete before we start the post build task.

If this is not the right approach how do other people do signing or other post build tasks with ninja. In our case we have some windows files system drivers that need to be signed in order to get deployed in our test environment. Therefore since signing (test signing is ok) is required we want this to happen as part of the build of the specified target. Requiring the entire build to have a signing phase is too slow in order to just build thee filters especially with active development. Any help or suggestions would be greatly appreciated.

Thanks

---

<div class="post-metadata">

### Author: ![scivision](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/a87d85/32.png) [@scivision](https://discourse.cmake.org/u/scivision)
#### Post date: [February 23, 2025, 12:18pm UTC](https://discourse.cmake.org/t/running-postbuild-tasks-with-ninja/13623/2 "2025-02-23T12:18:32Z")

</div>

This is probably a different type of signing than you are using, but here is a method I use to sign binary executables with gpg. Particularly this line

> <https://github.com/scivision/cmake-gpg-sign/blob/49b1cd0528898995009400eb4ece93ed1e2a5a6c/cmake/FindGPG.cmake#L76>

---

<div class="post-metadata">

### Author: ![noahdav](https://discourse.cmake.org/user_avatar/discourse.cmake.org/noahdav/32/4950_2.png) [@noahdav](https://discourse.cmake.org/u/noahdav)
#### Post date: [February 23, 2025, 6:08pm UTC](https://discourse.cmake.org/t/running-postbuild-tasks-with-ninja/13623/3 "2025-02-23T18:08:57Z")

</div>

Thanks for the info but we are already do doing something similar to this which does work however. However it does not wait for the original target to be linked in some cases so the final target will be compiled and symbol file exist but the linker has not completed. I need a way to ensure that POST\_BUILD is not started until the linker has completed.

Thanks  
Noah

---

<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: [February 20, 2026, 2:26am UTC](https://discourse.cmake.org/t/running-postbuild-tasks-with-ninja/13623/4 "2026-02-20T02:26:53Z")

</div>

Why use a `POST_*` command? A standalone `add_custom_command` should be sufficient:

```cmake
function (gpg_sign target)
  add_custom_command(
    OUTPUT "$<TARGET_FILE:${target}>.asc"
    DEPENDS "$<TARGET_FILE:${target}>"
    COMMAND "${GPG_EXECUTABLE}" --detach-sign --armor --output "$<TARGET_FILE:${target}>.asc" "$<TARGET_FILE:${target}>"
    COMMENT "GPG signing ${target}")
endfunction ()

```

I would also recommend specifying the identity as part of the command as well.

---

<div class="post-metadata">

### Author: ![scivision](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/a87d85/32.png) [@scivision](https://discourse.cmake.org/u/scivision)
#### Post date: [June 4, 2026, 7:06pm UTC](https://discourse.cmake.org/t/running-postbuild-tasks-with-ninja/13623/5 "2026-06-04T19:06:03Z")

</div>

This is a nice idea, but `add_custom_command(OUTPUT)` cannot contain a target-dependent expression like `$<TARGET_FILE`
