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
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().
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
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.
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.
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.
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.