Memory map (.elf.map) file fails to generate with multiple CMake targets

Hi, I’m a developer for my university’s robotics team, where we’ve been using (and having great success) with the mbed ecosystem. As a part of our competition, we create multiple robots, with a lot of code overlap between each robot, so we chose to create a CMake based project (using mbed-tools/Mbed CLI2) with multiple targets.

The project directory is along these lines:

MyCoolRobotProject
    /mbed-os
    /robots
        /MyCoolRobot1
            CMakeLists.txt
            main.cpp

        /MyCoolRobot2
            CMakeLists.txt
            main.cpp

        main.h
        CMakeLists.txt
    CMakeLists.txt

The top CMakeLists is responsible for using the shared mbed-os directory for both of the targets:

# mbed variables
set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "")
set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "")
set(APP_TARGET MyCoolProject)


include(${MBED_PATH}/tools/cmake/app.cmake) # Enable cmake for mbed

project(${APP_TARGET})

add_subdirectory(${MBED_PATH})

link_libraries(mbed-os) # Now mbed-os can be used for my robots
add_subdirectory(robots)

The CMakeLists.txt in my robots directory doesn’t do too much, just adds the MyCoolRobot1 and MyCoolRobot2 dirs:

include_directories(${CMAKE_CURRENT_SOURCE_DIR}) # Include my main.h file

add_subdirectory(MyCoolRobot1 EXCLUDE_FROM_ALL)
add_subdirectory(MyCoolRobot2 EXCLUDE_FROM_ALL)

And lastly, the two CMakeLists.txt in each robot dir (namely, MyCoolRobot1 and MyCoolRobot2) are identical, and differ only in the target name.

project(MyCoolRobot1) # Can also be MyCoolRobot2, the CMakeLists is identical

add_executable(${PROJECT_NAME})

mbed_configure_app_target(${PROJECT_NAME})

get_filename_component(PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
target_sources(${PROJECT_NAME} PRIVATE main.cpp ${PARENT_DIR}/main.h)

mbed_set_post_build(${PROJECT_NAME})

Configuring this CMake project works like a charm, and I can build each target individually using the --target flag. Building the two targets works as expected and I am able to generate a .hex and .bin file for both targets, yet there is no .elf.map file generated for MyCoolRobot1 (although a memory map file is generated for MyCoolRobot2.

I find that when switching the order of the add_subdirectory calls in my robots level CMakeLists, I am able to generate a .elf.map file for MyCoolRobot1, so it appears that only the last directory added using add_subdirectory will have an .elf.map file generated.

Any insight is appreciated, thanks in advance.

Hmm, I have to say, I don’t see anything obvious that would cause that. However, the official Mbed OS CMake build system doesn’t have great support for building multiple executables in one project, especially in older versions (pre 6.15 or so). It wasn’t really designed to do that, and you will end up recompiling mbed-os another time for each executable and library that you add to the project.

My fork, Mbed CE, includes a substantially rewritten build system which fixes lots of issues with using multiple executables. In particular, it allows you to compile Mbed only once regardless of how many executables exist in the project. I don’t know the cause of this error specifically, but I’d be surprised if it was still happening with Mbed CE.

If you want to switch, first you’ll need to change your mbed-os submodule to point to the mbed-ce repo. Then, you’ll need to apply some changes to your CMake scripts:

First of all,

set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "")
set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "")

becomes

set(MBED_APP_JSON_PATH mbed_app.json)

Then,

add_subdirectory(${MBED_PATH})

becomes

add_subdirectory(mbed-os)

Finally, you can remove the line

mbed_configure_app_target(${PROJECT_NAME})

That should be enough to get your project up and running. Then, you can go ahead and follow the setup instructions at the bottom of this page for whatever environment you use.

Hope that helps!

Unfortunately during my robotics competition season, switching to Mbed-CE is not feasible. This looks like a great fork and I look forward to switching over to Mbed-CE during our offseason!

As a temporary solution, I am looking to upgrade mbed-os to 6.15, since as you mentioned, support for multiple executables is lacking pre 6.15, and my team is currently running mbed-os 6.8- Do you think 6.15 solves the issue at hand?

Oh wow, I didn’t realize you were that far behind. Yes, I expect it will.

1 Like