CMake directory hierarchy question

I have a project for an embedded target that contains source code for a bootloader and source code for two sets of user code for two different microcontrollers, call them mcu_A and mcu_B.

The folder structure is as follows:

root/
    CMakeLists.txt
    bootloader/
        CMakeLists.txt
        ...
    mcu_A/
        CMakeLists.txt
        ...
    mcu_B/
        CMakeLists.txt
        ...

Generally, the workflow for us currently (using homebrewed makefiles and not using CMake) is that we are working on some source code in either mcu_A or mcu_B and once we want to test out some new code, we call “make install”, which calls some post-processing targets before calling a bootloader that uploads the new firmware. One of the post process steps for instance is to combine the two hex files from mcu_A and mcu_B into a single hex file that is uploaded in the install step.

The nice thing about this setup is that you can call “make install” in either mcu_A/ or mcu_B/ and they call a Makefile in the top level that knows to depend on the mcu_A and mcu_B hex files, merges them, and then hands it off to the install target. We want to keep this structure.

For a quick TLDR, this is my problem currently:
The problem that I am facing is that I can call upload in the toplevel, but that target is not made available to the mcu_A/mcu_B folders. I had thought about defining upload as a duplicate in the lower folders but when I tried that, it complains that upload is defined twice. Here are my CMakeLists files for my proof of concept:

root/CMakeLists.txt

add_subdirectory(mcu_A)
add_subdirectory(mcu_B)

add_custom_target(upload COMMAND echo “Calling upload from top level” DEPENDS compile_mcu_A compile_mcu_B)

root/mcu_A/CMakeLists.txt

add_custom_target(compile_mcu_A ALL COMMAND echo “mcu_A Code is being compiled”)

root/mcu_B/CMakeLists.txt

add_custom_target(compile_mcu_B ALL COMMAND echo “mcu_B Code is being compiled”)

I am still fairly new to CMake, so I’m sure I am missing a key architectural concept that could be preventing this from working, but my hope is that it is do-able and like ant pointers

What you’re trying to do, is based on the idea of using recursive makefiles.
But that is a makefile generator specific detail. Other generators may do it differently. e.g. MSVC projects are per target (AFAIK) and for Ninja everything is in a single file.

I suggest to do an upload_A and an upload_B target. The upload could simply depend on them, but if you want to flash the combined hex file instead, I guess it’s a completely independent target.