# Create target that only runs other target

**URL:** <https://discourse.cmake.org/t/create-target-that-only-runs-other-target/885>\
**Category:** Code\
**Created:** [March 29, 2020, 11:00am UTC](https://discourse.cmake.org/t/create-target-that-only-runs-other-target/885 "2020-03-29T11:00:03Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Leon0402](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/ccd318/32.png) [@Leon0402](https://discourse.cmake.org/u/Leon0402)\
**Post date:** [March 29, 2020, 11:00am UTC](https://discourse.cmake.org/t/create-target-that-only-runs-other-target/885/1 "2020-03-29T11:00:03Z")

</div>

Hi everyone,

I’m currently building a cmake for compiling and flashing microcontroller applications (avr).  
The important part looks like that:

```
function(add_avr_executable targetName)
    add_executable(${targetName} ${ARGN})
    set_target_properties(${targetName} PROPERTIES OUTPUT_NAME "${targetName}.elf")

    add_custom_command(TARGET ${targetName} POST_BUILD BYPRODUCTS ${targetName}.hex
        COMMAND ${CMAKE_OBJCOPY} -O ihex -j .data -j .text ${targetName}.elf ${targetName}.hex 
    )

    add_custom_target(${targetName}_run )
    add_dependencies(${targetName}_run ${targetName}_clean ${targetName} ${targetName}_upload)

    add_custom_target(${targetName}_upload COMMAND ${AVRDUDE} -p ${MCU} -c ${PROGRAMMER} -U #[[-P ${PORT} -b ${BAUD}]] flash:w:${targetName}.hex:i DEPENDS ${targetName}.hex)
    add_custom_target(${targetName}_size COMMAND ${AVR_SIZE} --mcu=${MCU} -C --format=avr ${targetName}.elf )#DEPENDS ${targetName}.elf)
    add_custom_target(${targetName}_nm COMMAND ${CMAKE_NM} --size-sort -S -C -t decimal ${targetName}.elf DEPENDS ${targetName}.elf)
    add_custom_target(${targetName}_clean COMMAND ${CMAKE_COMMAND} -E remove ${targetName}.hex ${targetName}.elf)
    add_custom_target(${targetName}_fuses COMMAND ${AVRDUDE} -v -p ${MCU} -c ${PROGRAMMER} -Pusb -U lfuse:w:0xe2:m -U hfuse:w:0xdb:m -U efuse:w:0xff:m)
endfunction()

```

So the basic “workflow” is:  
clean -\> build -\> flash -\> size

When I used just makefiles, I created a target “run”, which will just run all these targets in the specified order. I tried the same as you can see with add\_dependencies().  
But my first experience is that it sometimes work, but sometimes it doesn’t. It seems to give no gurantee that the specified order will also be the order of execution.

How can I achieve that I have a target run, which does build the other targets in a specified order?

Thanks everyone! Also, if you have any more feedback on how to improve that code snippet, I would appreciate it a lot. I’m quite new to cmake 🙂

---

<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:** [March 29, 2020, 4:05pm UTC](https://discourse.cmake.org/t/create-target-that-only-runs-other-target/885/2 "2020-03-29T16:05:42Z")

</div>

There is no order specified between these targets except that `_run` happens after `_clean` and `_upload`. The order of the `add_custom_target()` commands don’t matter and the ordering can be anything unless specified with `add\_dependencies().

---

<div class="post-metadata">

**Author:** ![Leon0402](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/ccd318/32.png) [@Leon0402](https://discourse.cmake.org/u/Leon0402)\
**Post date:** [March 29, 2020, 4:23pm UTC](https://discourse.cmake.org/t/create-target-that-only-runs-other-target/885/3 "2020-03-29T16:23:37Z")

</div>

I think you missunderstood me.  
I added one target:

```
add_custom_target(${targetName}_run )

```

This target should do nothing else than call other targets:  
targetName\_clean -\> targetName -\> targetName\_upload

in exactly this order! So first cleaning, then building, then flashing  
This is why I added these as dependencies:

```
add_dependencies(${targetName}_run ${targetName}_clean ${targetName} ${targetName}_upload)

```

But it turns out, that cmake doesn’t respect this order. Sometimes it calls upload before building, or cleans the projects at the end, which doesn’t make a lot of sense

To make it more clear, here is my command:  
cmake --build build --target targetName\_clean targetName targetName\_upload

It’s quite a long command and I would like to simplify it with a “shortcut target”, which will do the exact same thing.  
cmake --build build --target targetName\_run

---

<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:** [March 30, 2020, 2:14am UTC](https://discourse.cmake.org/t/create-target-that-only-runs-other-target/885/4 "2020-03-30T02:14:02Z")

</div>

> [@Leon0402](#):
>
> I added one target:
> 
> ```auto
> add_custom_target(${targetName}_run )
> 
> ```
> 
> This target should do nothing else than call other targets:  
> targetName\_clean → targetName → targetName\_upload
> 
> in exactly this order! So first cleaning, then building, then flashing

Targets don’t call other targets.

> [@Leon0402](#):
>
> This is why I added these as dependencies:
> 
> ```auto
> add_dependencies(${targetName}_run ${targetName}_clean ${targetName} ${targetName}_upload)
> 
> ```
> 
> But it turns out, that cmake doesn’t respect this order. Sometimes it calls upload before building, or cleans the projects at the end, which doesn’t make a lot of sense

The command ensures that `a top-level <target> depend on other top-level targets to ensure that they build before <target> does.` It does not ensure that there is any specific ordering of the “other top-level targets” between themselves which is what you seem to expect.

I would be surprised if clean and upload swapped when using the project over and over again. But I would not be surprised it it changed when regenerating the project and the new project had a different order.

Try this instead which has the inter-target dependency you describe.

```auto
add_dependencies(${targetName}_run ${targetName}_upload)
add_dependencies(${targetName}_upload ${targetName})
add_dependencies(${targetName} ${targetName}_clean)

```

My worry is that unless you changed a source code file then ${targetName} doesn’t need to build and the post build event to generate the hex file won’t run.

I think that you may be better off just having `${targetName}_run` call all the necessary commands instead. `add_dependencies` can accept more than one command.

---

<div class="post-metadata">

**Author:** ![Leon0402](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/ccd318/32.png) [@Leon0402](https://discourse.cmake.org/u/Leon0402)\
**Post date:** [April 5, 2020, 9:06am UTC](https://discourse.cmake.org/t/create-target-that-only-runs-other-target/885/5 "2020-04-05T09:06:25Z")

</div>

> hich is what you seem to expect  
> At least I hoped it would behave like that, but it didn’t.

> Try this instead which has the inter-target dependency you describe.

```auto
add_dependencies(${targetName}_run ${targetName}_upload)
add_dependencies(${targetName}_upload ${targetName})
add_dependencies(${targetName} ${targetName}_clean)

```

This goes in the right direction. In fact I kinda have it already like that I think as upload depends on hex. And it actually always rebuilds the elf/hex file if anything changes, which is perfect.  
But add\_dependencies(${targetName} ${targetName}\_clean) that’s not true. While it’s certainly one use case to call “clean” before “build”, it’s certainly not necessary. I mean, I could live with that … I haven’t figured yet out, when I need to clean the project, so I do it always anyway.

But say, I want a shortcut, which does all that and prints the size at the end (which is what arduino does). Then this approach is not possible anymore, as ${targetName}\_size should certainly not depend on run or upload.  
So I was looking for a more generic approach, which allows me to run targets in a specific order with only one command, without having any dependencies between them.

> I think that you may be better off just having `${targetName}_run` call all the necessary commands instead

I guess, I have to use this approach. But I really don’t like copy and pasting. It’s not even possible to refactor the commands in the target (by using custom\_command) and use them in multiple targets.  
For me this is a missing feature in cmake.

---

<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:** [April 6, 2020, 10:24am UTC](https://discourse.cmake.org/t/create-target-that-only-runs-other-target/885/6 "2020-04-06T10:24:31Z")

</div>

> [@Leon0402](#):
>
> But say, I want a shortcut, which does all that and prints the size at the end (which is what arduino does). Then this approach is not possible anymore, as ${targetName}\_size should certainly not depend on run or upload.  
> So I was looking for a more generic approach, which allows me to run targets in a specific order with only one command, without having any dependencies between them.

> [@Leon0402](#):
>
> But I really don’t like copy and pasting. It’s not even possible to refactor the commands in the target (by using custom\_command) and use them in multiple targets.  
> For me this is a missing feature in cmake.

> [@fdk17](#):
>
> I think that you may be better off just having `${targetName}_run` call all the necessary commands instead. `add_dependencies` can accept more than one command.

Just noticed the typo. I’ll try to fix it if I can. But here is an example of what I was trying to convey.

```auto
add_custom_target(${targetName}_run 
  COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR } --target ${targetName}_clean
  COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR } --target ${targetName}
  COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR } --target ${targetName}_upload
  )

add_custom_target(${targetName}_run_size 
  COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR } --target ${targetName}_run
  COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR } --target ${targetName}_size
  )

```

Then you don’t need additional `add_dependencies` in the function `add_avr_executable`. You just issue the targets to be executed: clean elf and hex, build elf and hex, and upload. Then you can reuse the commands in new commands. For example `${targetName}_run_size`. Or you can issue it from the command line using the `--build` CMake option or from the build tool like `make`.

---

<div class="post-metadata">

**Author:** ![Leon0402](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/ccd318/32.png) [@Leon0402](https://discourse.cmake.org/u/Leon0402)\
**Post date:** [April 6, 2020, 3:52pm UTC](https://discourse.cmake.org/t/create-target-that-only-runs-other-target/885/7 "2020-04-06T15:52:22Z")

</div>

That’s smart! It’s exactly what I wanted, just a little bit more complicated 😃 Maybe cmake will add in future a feature to reference them directly.

I was just wondering:

There is no option to get the call options, right?

So that I could do something like:  
`COMMAND ${CMAKE_COMMAND} CMAKE_CALL_OPTIONS --target ${targetName}_clean`

So the options I use for $targetName\_run will be reused for the other targets for example --build /some/directiory. That would make it perfect 🙂
