Mbed-ce debugging custom targets in VSCode

I have a custom design that is based on the B-L072Z-LRWAN1 and using mbed-ce and VSCode.

My development setup is as documented on the mbed-ce repo and I am using STMcubeIDE for loading and debugging. Everything configures, compiles and loads properly using an STlinkv3.

My problem is I am not getting a configuration loaded into .vscode/launch.json. I can add a configuration and change the link to the proper ./build/…/.elf (it doesn’t figure out the alternate dynamic path set up in the settings.json file) and then it works for debugging, but of course it gets rewritten on rebuilds. I do get a cannot find loader message as described on the mbed-ce github repo discussion for custom targets though.

I’m pretty sure I have followed everything in the custom target example. Is there a step needed that isn’t documented or implemented yet? I’m guessing it might have something to do with the above discussion and creating a custom .cmake file and somewhere getting CMake to read it not from the mbed-os directory.


would be better to post this to Mbed-ce discussions, link the topic what you talking about and share some pictures.

In general the MbedCE auto generates all files for VS-Code.

BR, Jan

Will do.

The mbed-ce/mbed-os repo readme.md discussion link points to the mbed site so I’ve been going here. It looked like the discussions in the mbed-ce repo were more code changing oriented and didn’t want to add noise to that.

Ah yes, if you’re using a custom target, you need to enable an upload method for that target in order for mbed-ce to generate VS Code config files.

You will need to add something like:

# Config options for STM32Cube
# -------------------------------------------------------------
set(STM32CUBE_CONNECT_COMMAND -c port=SWD reset=HWrst)

after the include of app.cmake in your top-level CMakeLists.txt. Then, set -DUPLOAD_METHOD=STM32CUBE.

And regarding the forum, I think this is a good place to ask questions like this. The Mbed CE discussion page has been used more for developer discussion.

I started an “Issue” over on GitHub but will keep this thread going.

Isn’t that the information/settings in the cmake-variants.yaml file provides?

I actually had tried including a custom “upload_method_.cmake” file with those lines in it and include it in the top level CMakeLists.txt file, but no joy.

I tried adding what you suggested to the top level CMakeLists.txt file:

cmake_minimum_required(VERSION 3.19)
cmake_policy(VERSION 3.19)

Initialize Mbed OS build system.

Note: This block must be before the include of app.cmake

set(MBED_APP_JSON_PATH mbed_app.json)
set(CUSTOM_TARGETS_JSON_PATH custom_targets.json)
set(APP_TARGET loraSensor)


Config options for STM32Cube


set(STM32CUBE_CONNECT_COMMAND -c port=SWD reset=HWrst)












option(VERBOSE_BUILD “Have a verbose build process”)

and get the following:

[proc] Executing command: cmake --version

[proc] Executing command: cmake -E capabilities

[variant] Loaded new set of variants

[kit] Successfully loaded 1 kits from C:\Users\tim\AppData\Local\CMakeTools\cmake-tools-kits.json

[proc] Executing command: “C:\Program Files\CMake\bin\cmake.EXE” --version

[proc] Executing command: “C:\Program Files\CMake\bin\cmake.EXE” -E capabilities

[main] Configuring project: loraSensor

[proc] Executing command: “C:\Program Files\CMake\bin\cmake.EXE” --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DMBED_TARGET:STRING=LATIUM_HVC_ABZ -DUPLOAD_METHOD:STRING=STM32CUBE -DSTM32CUBE_UPLOAD_ENABLED:BOOL=TRUE “-DSTM32CUBE_CONNECT_COMMAND:STRING=-c;port=swd;reset=HWrst” -DSTM32CUBE_GDBSERVER_ARGS:STRING=–swd -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE “-SC:/Users/tim/Mbed Programs/mbed-ce/loraSensor” “-Bc:/Users/tim/Mbed Programs/mbed-ce/loraSensor/build/LATIUM_HVC_ABZ-Debug” -G Ninja

[cmake] Not searching for unused variables given on the command line.

[cmake] – Found Python3: C:/Program Files/Python311/python.exe (found version “3.11.7”) found components: Interpreter

[cmake] – Checking for Python package intelhex – found

[cmake] – Checking for Python package prettytable – found

[cmake] – Checking for Python package future – found

[cmake] – Checking for Python package jinja2 – found

[cmake] – Mbed: First CMake run detected, generating configs…

[cmake] mbed_config.cmake has been generated and written to ‘C:\Users\tim\Mbed Programs\mbed-ce\loraSensor\build\LATIUM_HVC_ABZ-Debug\mbed_config.cmake’

[cmake] – The C compiler identification is GNU 13.2.1

[cmake] – The CXX compiler identification is GNU 13.2.1

[cmake] – The ASM compiler identification is GNU

[cmake] – Found assembler: C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/bin/arm-none-eabi-gcc.exe

[cmake] – Detecting C compiler ABI info

[cmake] – Detecting C compiler ABI info - done

[cmake] – Check for working C compiler: C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/bin/arm-none-eabi-gcc.exe - skipped

[cmake] – Detecting C compile features

[cmake] – Detecting C compile features - done

[cmake] – Detecting CXX compiler ABI info

[cmake] – Detecting CXX compiler ABI info - done

[cmake] – Check for working CXX compiler: C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/bin/arm-none-eabi-g++.exe - skipped

[cmake] – Detecting CXX compile features

[cmake] – Detecting CXX compile features - done

[cmake] – Mbed: Target does not have any upload method configuration. ‘make flash-’ commands will not be available unless configured by the upper-level project.

[cmake] – Mbed: Not building any Mbed OS tests.

[cmake] – Located STM32CubeIDE: C:/ST/STM32CubeIDE_1.14.0/STM32CubeIDE

[cmake] – Found STLINKTools: C:/ST/STM32CubeIDE_1.14.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.1.100.202311100844/tools/bin/STM32_Programmer_CLI.exe

[cmake] – Mbed: Code upload and debugging enabled via upload method STM32CUBE

[cmake] – Mbed: Detected VS Code IDE, will generate VS Code debug configurations

[cmake] – Configuring done (11.0s)

[cmake] – Generating done (1.3s)

[cmake] – Build files have been written to: C:/Users/tim/Mbed Programs/mbed-ce/loraSensor/build/LATIUM_HVC_ABZ-Debug

You mention setting -DUPLOAD_METHOD=STM32CUBE, that is set in the cmake-variants.yaml file. Is there someplace else it should be set? My .vscode/launch.json file still does not contain any configurations but the .vscode/tasks.json file is being created

// Auto-generated by Mbed CE. Edits will be erased when CMake is rerun.
“version”: “2.0.0”,
“tasks”: [
“label”: “GDB Server”,
“type”: “shell”,
“command”: “C:/ST/STM32CubeIDE_1.14.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.win32_2.1.100.202310302101/tools/bin/ST-LINK_gdbserver.exe”,
“args”: [“–swd”, “-cp”, “C:/ST/STM32CubeIDE_1.14.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.1.100.202311100844/tools/bin”, “-p”, “23331”, “–halt”],
“isBackground”: true,
// This task is run to start the GDB server, so that the launch configuration can connect to it.
// Problem is, it’s a GDB server, and since it never exits, VSCode
// will never start the debug session. All this is needed so VSCode just lets it run.
“problemMatcher”: [
“pattern”: [
“regexp”: “________________”,
“file”: 1,
“location”: 2,
“message”: 3
“background”: {
“activeOnStart”: true,
“beginsPattern”: “.",
“endsPattern”: ".


I can see where launch.json should be created by mbed-os\tools\cmake\mbed_ide_debug_cfg_generator.cmake right beside tasks.json but so far I can’t see why SCODE_LAUNCH_JSON_CONTENT isn’t updated by the mbed_generate_ide_debug_configuration function.

Not having a lot of CMake experience could have something to do with it …

Also, I have a simple mbed-ce supported board target, i.e. not custom, and it generates the launch.json file just fine.

I’m drilling down into mbed_ide_debug_cfg_generator.cmake and it appears that function(mbed_finalize_ide_debug_configurations) is getting called instead of
function(mbed_generate_ide_debug_configuration CMAKE_TARGET) at:

VS Code generator




A little embarrassing but somehow the:


in my top level CMakeList.txt file wasn’t the last line in the file. I tracked the calls going backwards in this and another recent project started based on the custom targets example and the little comment tagged onto the end of this call in the example popped up as the difference.

Funny how everything seemed to be working except debugging. Sorry for the bother.


Was just about to post that you should check this, glad you found it!

It’s quite annoying, it’s a CMake limitation that there’s no way to automatically have code be called after the complete list of targets is created to write out files like this.

That said, I think we do need to modify the custom targets example repo to include some upload methods as well!

One last question on this: I’ve read the custom targets discussion over at the mbed-ce repo and your discussion about how and where the upload info should be. My setup has it per the VS Code setup instructions in cmake-variants.yaml. I actually don’t seem to need the extra “set” statements in the top level CMakeLists.txt file you suggested as my possible earlier fix and of course compiling and flashing my target was working. Was the yaml file just a convenient place to put these settings in the VS Code case and will that be changing based on the outcome of the custom targets discussion. If the current mbed upload methods for targets is followed using a .cmake file wouldn’t it make the most sense to place and automatically look for this in the ./custom_targets directory so as to not clutter up the top level CMakeLists.txt file?

Yeah, I didn’t realize you were setting those variables already through VS Code, you don’t need to set them in CMake as well!

Currently we don’t have a setup to load custom target upload methods automatically, you have to either set them in CMake (e.g. in an include file) or set the variables on the command line like you did. But I believe @sunnydaywest was working on a PR for that!

There is a branch with a proposed fix but an ongoing discussion which is blocking it. It was said that the current method works well and sometimes you need more targets in one project. But however I’m using that branch and it works perfectly in my case. I don’t get the confusing message anymore that the config isn’t found in the beginning of the build.

1 Like

Eh, since it seems like many people are confused by the message, it’s probably worth adding. Go ahead and submit your PR!

1 Like

We just do not understand to each other, I think. And in case of Sam it is different because he uses his own project sructure what ignoring expected Custom target project logic.

From my point of view this is expected Custom target project tree according to provided example by Jamie. Where Jamie expect to place all settings around upload menthod in top lvl CmakeLists.txt.

├── mbed-os/
├── Build/
├── Custom_targets/
│   ├── YOUR_TARGET/
│   │	└──  somefiles.xxx
│   │	└──  somefiles.xxx
│	└──	CMakeLists.txt
├── CMakeLists.txt
├── mabed_app.json
├── custom_targets.json
└── main.cpp

I suppose Sam’s will be somthing like this and he wanted to have all settings around upload menthod in same config file like regulars target but inside of YOUR_TARGET folder.

├── mbed-os/
├── Build/YOUR_TARGET/BuildProfile(
│   └──  somefiles.xxx (everything around)
├── CMakeLists.txt
├── mabed_app.json
└── main.cpp

My proposal is use very similar folder logic to mbed-os/targets which will small modification of origine Custom targets tree structure

├── mbed-os/
├── Build/
├── Custom_targets/
│   ├── YOUR_TARGET/
│   │	└──  somefiles.xxx
│   │	└──  somefiles.xxx
│	│
│   ├── UploadMethod.cmake
│ 	├── custom_targets.json
│	└──	CMakeLists.txt
├── CMakeLists.txt
├── mabed_app.json
└── main.cpp

How I said 1000 people 1000 ideas, so need one for publish and if anyone else want to deal with this differently, then OK but on its own way without official support.

BR, Jan

this works already by adding

set(MBED_APP_JSON_PATH mbed_app.json)
set(CUSTOM_TARGETS_JSON_PATH custom_targets/custom_targets.json) # This activates the custom targets in custom_targets.json

It seems I’ve stepped into the middle of something here…

My current project uses

set(MBED_APP_JSON_PATH mbed_app.json)
set(CUSTOM_TARGETS_JSON_PATH custom_targets/custom_targets.json) # This activates the custom targets in custom_targets.json

but of course that json just defines the custom targets, it doesn’t provide a method to set the upload method configuration(s).

app.cmake is pseudo hard-coded where it is looking for the upload settings, i.e. mbed-os/targets/upload_method_cfg/ and if your YOUR_TARGET doesn’t have a .cmake file in that directory you get the warning message.

What if we just set the location CUSTOM_TARGETS_PATH in the top level CMakeLists.txt and in that directory is: custom_targets.json(5), YOUR_TARGET directory(ies) AND either: an uploads_methods_cfg directory containing all the custom YOUR_TARGET.cmakes(s) like as in mbed-os/targets OR place the YOUR_TARGET.cmake file in each YOUR_TARGET directory where app.cmake can get at them, OR just place the settings in the YOUR_TARGET/CMakeLists.txt file?

A simple change to app.make can check to see if CUSTOM_TARGETS_PATH is set and follow what ever method is used from above to find the custom upload method.

I am rather new to cmake, mbed-ce build structure, and VS Code so I’m probably missing something here, but if any ideas from above can be used, great.

I like this idea, then the custom targets have all necessary things together.