Showing results for 
Search instead for 
Did you mean: 

Is STM32 VS Code Extension multi-root workspace compatible?

Associate II

I have a project which has two STM32H5 MCUs. They each have a folder ("a" and "b") which contains their code, CMake folder, etc. Both of these folders 'a' and 'b', along with a folder of shared .c and .h files ("shared") exist at the top level of the git repo. By opening each of the MCU folders 'a' and 'b' individually in VSCode, I am able to build/program/debug that one micro just fine. But to switch between them I have to close the folder and then open the other folder.

I have not found a way to open the higher level folder (which contains 'a', 'b' and 'shared') within VSCode and be able to build/program/debug one or the other micros from there. My expectation is that STM32 VS Extension would need to support the VSCode mult-root workspace APIs in order to do this:

Is that an option? If not, is it on the roadmap? It would be a very useful feature for lots of folks as multi-MCU designs are very common these days. (My last project had 5 STM32 MCUs on one board.)


mattias norlander
ST Employee

Hi Brian,

Just like you say. This is a bit of a headache. Specifically when dealing with multi-core, TrustZone, or BootFlash devices or just any single-core device with a bootloader and an application project. In these cases, you end up with more than one project (a + b in your example).

The multi-root workspace API is something we are looking at. There are challenges here.

  • Which context should the editor index?
  • When I launch debug, what should happen? Should this depend on the active CMake context?
    • Unless users understand VS Code and Msfts CMake extension, the behavior may seem a bit odd and scary.

If I remember well, we did an analysis half year ago and saw that not so many extensions support this multi-root workspace API. Maybe that will change, who knows...

In the roadmap we may talk about short-term and long-term.

  • Short-term we may make some fixes to try to better propagate the context to have edit/compile/debug in-sync.
  • Long-term: More analysis to be done.


Will be interesting to get some feedback on our next small-scale VS Code extension update on this topic!

Thank you very much for the excellent, detailed, and honest reply Mattias. It clearly is a difficult problem for you and the extensions - I didn't even think of the multi-core or TrustZone use cases, but they will all share this problem.


Maybe I can help out a little bit by giving my experience as a daily user who is experiencing problems because of this issue. Ignore the fact that I'm building for two processors A and B. My immediate, daily frustration at this point is the shared code. I'm using a workspace file in VSCode that allows me to not only see the main processor folded (A) but also the shared code folder (shared) in my folder tree in VSCode. The problem comes in when I am debugging any file in the shared folder. Let's say I change a line in shared/code.c and then I want to build and debug. So I hit F5. But because the source file that currently has focus (shared/code.c) is NOT within the main project folder (A), VSCode doesn't know how to build. It asks me to please attempt to find the CMakeLists.txt file. So here's my frustration: every time I need to build/debug, I have to click over to one of the source files that IS in the main project folder (A), and THEN hit F5 to build/debug. I know this sounds like a little thing, but it's a step backward from all of the previous IDEs I've used (Keil, IAR, CubeIDE) where they don't care which source code has focus, a build command will always build the 'active' project. So your edit/build/debug cycle is faster and less annoying on them compared to VSCode.

Maybe there's something simple you can do in your STM32 VS Code Extension to have a concept of an 'active' project (i.e. which CMakeLists.txt should be used whenever the user wants to build). If VSCode didn't have to infer that based on which source code file has focus, that would completely solve my problem, and it may make the more general problem of mulit-project workspaces easier to solve too. If there were 5 processors each with their own main project folder (A, B, C, D, E) and each with their own CMakeLists.txt file, the 'active' project setting could point to only one of them at a time and so the system would always know which one to build when the user hits F5 (or F7).

I understand your use case. Let me discuss a bit internally...

If I remember well, CubeIDE being Eclipse/CDT-based also derives the "active context" from which file is open in the editor.


Above is an example in CubeIDE where we have shared folders inside a "hierarchical" project structure. Notice that the hammer build icon is greyed out when the shared Drivers folder is selected. Same thing if I open a shared c-file from that folder. But if I open the same folder when it is linked inside one of the "child-projects" then CubeIDE understands the context and will enable and execute builds properly.
In my view the best way to solve this solution is to offer two modes:

  • OPT1: Automatic context - let the IDE figure out what you try to build/debug based on which file is open. Has some pros and cons. If you don't share code this can work well.
  • OPT2: Strict context - you select the proejct context which will apply to at least edit/build. If you want to switch to work on another project you have to select that manually. Full control - no magic!

I am her just brainstorming and interesting to catch as much feedback as possible to guide our roadmap in the right direction. Feel free to vote for OPT1/OPT2 or both. 🙂
And if you are willing to share your thoughts on "why" you need this or that, then I am sure it will help us consolidate a better view of the problem/solution.

Thanks @brian_schmalz for sharing - keep the feedback coming!

Associate II

Well look at that - I didn't realize that CubeIDE does automatic context resolution. That's really interesting. Maybe that means that OPT1 is the way to go for the VSCode extension as that's the behavior most users are already used to (even if they don't explicitly know it) as they migrate from CubeIDE to VSCode. Maybe.

Personally I prefer OPT2. Or, maybe with a little more color: I prefer the option of having OPT2 available to me. I would guess that for many users, much of the time (particularly for simple projects) OPT1 as a default is the right way to go. If the IDE can just figure things out on its own, why confuse the user with extra settings and concepts. 

But if there could be an extra (optional) setting within the workspace file that I could add, which would force VSCode to always know which CMakeLists.txt file to use for building (i.e. bypassing its automatic context finding), that would give me the ability to invoke behavior OPT2 whenever I want, but have the default be OPT1 when that setting is not present. That seems like the best of both worlds.

Having that ability not only solves my immediate debugging frustration with shared files, but also potentially solves mulit-processor builds as well. I could simply open two instances of VSCode, with different workspaces in each. Those workspaces specify what shared source folders to display, as well as which CMakeLists.txt file to use for building.

For many simple projects none of this complexity is really necessary. However, almost all of the projects I work on professionally have either more than one MCU (latest project was 5 STM32s) or shared code of some sort, or both. VSCode will need to somehow support those more complex build/debug/test situations in order to be the IDE choice for those professional projects.

mattias norlander
ST Employee

To summarize parts of your reply, I think of the phrase "flexibility and sane defaults". This phrase is a dogma flying in the VS Code IDE-team and something we target.

You mention the word Debugging frustration, in VS Code context. The reason you face this is because our launch.json (assuming you use what we generate), relies on CMake variables. So when CMake switches context the CMake variables will point to potentially the wrong elf-file... Is this what you refer to?

If so have a look inside the .vscode/launch.json:

"executable": "${command:cmake.launchTargetPath}",
// Let CMake extension decide executable: "${command:cmake.launchTargetPath}"
// Or fixed file path: "${workspaceFolder}/path/to/filename.elf"

Would that help you solve that aspect?

In the future we want cut cord between CMake and debug. We can auto-detect the elf-file and set relative paths, in case multiple elf-files we can present a menu to let you choose! <-- Example of what I mean with "flexibility and sane defaults".

All-in-all, I think that would solve your debugging frustration. What is your view?
I hope we get feedback from others willing to contribute as well!

Associate II

Not quite, unfortunately. The problem I'm seeing isn't (I don't think) related to where the .elf file is located, but rather where the CMakeList.txt file is located relative to the source file that currently has focus.

If I make a change to one of the source files that's in my Shared folder, and leave that source file as the source file with focus in the editer, then hit F7 to build, I get the following that appears at the top of VSCode:


Even if I select the correct CMakeLists.txt file (which is in the "A" folder) no build actually happens.

I need to switch focus to one of the source code files that's within the "A" folder by clicking on it, then hitting F7 and the build goes just fine then.

This all happens before I get to the step where I would want to program/debug.

I did try setting the relative path to the .elf file, as well as hard coding the entire path to the .elf file in the launch.json file, and that did not change any of the above behavior.