cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 vscode clangd not working under Windows with space in user folder

Mikk Leini
Senior III

I had a Windows account with a space in user folder name (between forename and surname). VScode was installed under AppData subfolder. As a result CMake generated paths like this into compile_commands.json:

"command": "C:\\Users\\MIKKLE~1\\AppData\\Local\\STM32C~1\\bundles\\GNU-TO~2\\1431_S~1.2\\bin\\AR19DD~1.EXE -DDEBUG....

Most of the things worked (compiling and debugging), but vscode highlighted that it can't find includes like these:

#include <stdio.h>
#include <assert.h>

To be correct, clangd language server couldn't find them. Absence of these headers caused further errors. But when resolving other headers like stdint.h, clangd found them from st-arm-clangd bundle folder instead of compiler folder.

The workaround was to add the very same shortened path as query driver into .vscode\settings.json:

 "--query-driver=C:\\Users\\MIKKLE~1\\AppData\\Local\\STM32C~1\\bundles\\GNU-TO~2\\1431_S~1.2\\bin\\AR19DD~1.EXE"

It solved the clangd issue temporarily until ST tools rewrote settings.json.

I thought it's the classical long path issue, but enabling long paths in Windows registry and forcing CMake to use longer paths (512 characters) did not solve it.

After removing space from my Windows user folder it started working normally.

Quick guide: Create temporary admin user, reboot, login with new user, rename user folder and update it in  registry path HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList. Expect trouble with some applications.

I don't know whether it should be solved in CMake, clangd, ST vscode toolset or just made as an installation time warning. I hope ST team decides. So far maybe it helps somebody with the same issue.

16 REPLIES 16
Andrew Neil
Super User

This is common.

Lots of things won't work with spaces (or other "special" characters) in folder and/or file names.

Only the other day:

https://community.st.com/t5/stm32cubeide-mcus/breakpoint-installation-failure-unmatched-quote/m-p/870063/highlight/true#M40489

 

https://community.st.com/t5/stm32cubeide-mcus/breakpoint-installation-failure-unmatched-quote/td-p/870028/highlight/true#:~:text=Spaces%20and%C2%A0other%20%22special%22%20characters%20are%20an%20all%2Dtoo%2Dcommon%20source%20of%20grief%20and%20weird%20behaviour%20%2D%20see%20here.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
Mikk Leini
Senior III

Yep, unfortunately it is. I've put my ST tools usually under C:\ST due to such reasons and keep code in shallow path, but now vscode wants to be in user folder and I didn't see this one coming :(

Thanks for the links @Andrew Neil . I had some other strange issues, I'll check if something could be related.

Tip for those who rename their Windows user folder. CubeMX needs some manual help - parameter RepositoryPath needs to be updated in C:\Users\Username\.stm32cubemx\plugins\updater\updater.ini file.

Cartu38 OpenDev
Lead III

@Mikk Leini 
One way to go is to master STM32Cube bundles install repository.
Let's `cube --help` within a VSCode integrated terminal. You will get:

Cartu38OpenDev_0-1768544369428.png

Have a try to exit VSCode session, define this env variable, move all your former AppData stuff in sync. then start a new VSCode instance.

Is it helping ?

Note: very same for OpenCMSIS packs if required

Cartu38OpenDev_2-1768544546679.png

 

 

MNASTM
ST Employee

Hi Mikk,

Not sure what version you were running, but may I ask what your .vscode/settings.json looks like in the first place?

Now STM32Cube extension generates automatically clangd arguments as follow:

"stm32cube-ide-clangd.arguments": [
        "starm-clangd",
        "--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/14.3.1+st.2/bin/arm-none-eabi-gcc.exe",
        "--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/14.3.1+st.2/bin/arm-none-eabi-g++.exe"
    ]

 Let me know if this helps to avoid your workaround?

Besides that, clangd is supposed to be able to use compile_commands.json with short (8.3) windows path, however it is recommended to avoid it when possible, @Cartu38 OpenDev suggestion is a perfect valid one.

Mikk Leini
Senior III

Hi  @MNASTM

I have/had the same .vsocde/settings.json like you wrote. But that path is long. CMake generated compile_commands.json contains shorted paths if there's space somewhere. clangd does not consider them the same so it cannot find compiler include files.

Maybe @Cartu38 OpenDev 's workaround works also, but I don't want to mess around with it anymore. User folder change causes other issues also. If somebody has time they can create temporary Windows user with whitespace to try it.

It looks like a CMake issue but maybe it tries to avoid escaped quotation marks within JSON string quotes and therefore it creates shortened paths. Here is similar, but not quite same issue report:

The compile_commands.json is not usable with run-clang-tidy - Development - CMake Discourse

The issue for me is solved. But maybe ST team wants to avoid somebody making the same mistake.

Pavel A.
Super User

You can try this hack to get rid of the space in the folder path (note: it depends on the ability of the filesystem to create short 8.3 filenames. On latest Win11 machines, network drives etc. it can be disabled).

https://gist.github.com/pavel-a/9cfdab4244c7bbbcaf9f32e81dfbaf01

Another hack to try: create a symbolic or hard link to your userprofile folder, but without spaces.

For example  mklink /D c:\users\GOOD  "c:\users\aaa bbb"

  

I tried with a space in my bundle path location and I also ended up with shortened path generated in my compile_commands.json. However clangd was able to load it correctly and my headers redirections were fine. 

- tested on windows 11 and st-arm-clangd@19.1.2+st.3.

Feel free to drop us a full log of your "STM32Cube Clangd" output channel, and exact configuration, but for now we will not push investigation further.

Thanks for your valuable feedback,

MNA

Mikk Leini
Senior III

I recreated it easily.

1. Moved "bundles" and "packs" from "C:\Users\###\AppData\Local\stm32cube" into "C:\ST\st bundles" and "C:\ST\st packs".

2. Created Windows User environment variables.

MikkLeini_0-1771156675981.png

CMSIS_PACK_ROOT=C:\ST\st packs
CUBE_BUNDLE_PATH=C:\ST\st bundles

3. Created new random blank CubeMX project for CMake toolchain. I used STM32F100 MCU and saved IOC into "C:\ST\demo" folder. Generated the code.

4. Opened the project folder with vscode. Let ST extensions discover and configure the CMake project. It found right tools:

[proc] Executing command: cube-cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=C:/ST/demo/cmake/gcc-arm-none-eabi.cmake -DCMAKE_COMMAND=cube-cmake -S C:/ST/demo -B C:/ST/demo/build/Debug -G Ninja
[cmake] -- The C compiler identification is GNU 14.3.1
[cmake] -- The CXX compiler identification is GNU 14.3.1
[cmake] -- Detecting C compiler ABI info
[cmake] -- Detecting C compiler ABI info - done
[cmake] -- Check for working C compiler: C:/ST/st bundles/gnu-tools-for-stm32/14.3.1+st.2/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:/ST/st bundles/gnu-tools-for-stm32/14.3.1+st.2/bin/arm-none-eabi-g++.exe - skipped
[cmake] -- Detecting CXX compile features
[cmake] -- Detecting CXX compile features - done

5. Built the project to generate compile_commands.json and verification. Looks okay:

[build] [19/19] Linking C executable demo.elf
[build] Memory region         Used Size  Region Size  %age Used
[build]              RAM:        1584 B         4 KB     38.67%
[build]            FLASH:        3640 B        16 KB     22.22%
[driver] Build completed: 00:00:01.176
[build] Build finished with exit code 0

6. Checked .vscode\settings.json. Looks okay:

{
    "cmake.cmakePath": "cube-cmake",
    "cmake.configureArgs": [
        "-DCMAKE_COMMAND=cube-cmake"
    ],
    "cmake.preferredGenerators": [
        "Ninja"
    ],
    "stm32cube-ide-clangd.path": "cube",
    "stm32cube-ide-clangd.arguments": [
        "starm-clangd",
        "--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/14.3.1+st.2/bin/arm-none-eabi-gcc.exe",
        "--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/14.3.1+st.2/bin/arm-none-eabi-g++.exe"
    ]
}

7. Went to main.c and typed "include <stdio.h>". Open it's definition. Since I have Microsoft Windows SDK installed, it found stdio.h from there.

MikkLeini_1-1771156915747.png

8. Include something more embedded, like <elf.h>. It's not found:

MikkLeini_2-1771157052046.png

9. Look at build\Debug\compile_commands.json:

[
{
  "directory": "C:/ST/demo/build/Debug",
  "command": "C:\\ST\\STBUND~1\\GNU-TO~1\\1431_S~1.2\\bin\\AR19DD~1.EXE -DDEBUG -DSTM32F100xB -DUSE_HAL_DRIVER -IC:/ST/demo/cmake/stm32cubemx/../../Core/Inc -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/CMSIS/Device/ST/STM32F1xx/Include -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/CMSIS/Include  -mcpu=cortex-m3  -Wall -fdata-sections -ffunction-sections -mcpu=cortex-m3  -Wall -fdata-sections -ffunction-sections -O0 -g3 -std=gnu11 -o CMakeFiles\\demo.dir\\Core\\Src\\main.c.obj -c C:\\ST\\demo\\Core\\Src\\main.c",
  "file": "C:\\ST\\demo\\Core\\Src\\main.c",
  "output": "CMakeFiles\\demo.dir\\Core\\Src\\main.c.obj"
},
{
  "directory": "C:/ST/demo/build/Debug",
  "command": "C:\\ST\\STBUND~1\\GNU-TO~1\\1431_S~1.2\\bin\\AR19DD~1.EXE -DDEBUG -DSTM32F100xB -DUSE_HAL_DRIVER -IC:/ST/demo/cmake/stm32cubemx/../../Core/Inc -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/CMSIS/Device/ST/STM32F1xx/Include -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/CMSIS/Include  -mcpu=cortex-m3  -Wall -fdata-sections -ffunction-sections -mcpu=cortex-m3  -Wall -fdata-sections -ffunction-sections -O0 -g3 -std=gnu11 -o CMakeFiles\\demo.dir\\Core\\Src\\stm32f1xx_it.c.obj -c C:\\ST\\demo\\Core\\Src\\stm32f1xx_it.c",
  "file": "C:\\ST\\demo\\Core\\Src\\stm32f1xx_it.c",
  "output": "CMakeFiles\\demo.dir\\Core\\Src\\stm32f1xx_it.c.obj"
},

/* Etc. */
]

Shortened paths there.

9. Close "main.c" and reopen it.

10. Open STM32Cube clang output window to see what it thinks about it:

I[14:17:33.296] Loaded compilation database from c:\ST\demo\build\Debug\compile_commands.json
I[14:17:33.297] ASTWorker building file c:\ST\demo\Core\Src\main.c version 108 with command
[C:/ST/demo/build/Debug]
"C:\\ST\\st bundles\\gnu-tools-for-stm32\\14.3.1+st.2\\bin\\AR19DD~1.EXE" -DDEBUG -DSTM32F100xB -DUSE_HAL_DRIVER -IC:/ST/demo/cmake/stm32cubemx/../../Core/Inc -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/CMSIS/Device/ST/STM32F1xx/Include -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/CMSIS/Include -mcpu=cortex-m3 -Wall -fdata-sections -ffunction-sections -mcpu=cortex-m3 -Wall -fdata-sections -ffunction-sections -O0 -g3 -std=gnu11 -o "CMakeFiles\\demo.dir\\Core\\Src\\main.c.obj" -c -ferror-limit=0 -Wno-implicit-int "-resource-dir=C:\\ST\\st bundles\\st-arm-clangd\\19.1.2+st.3\\lib\\clang\\19" -- "c:\\ST\\demo\\Core\\Src\\main.c"

It uses folder name with spaces, but the compiler executable name is shortened (AR19DD~1.EXE).

11. I modified vscode\settings.json to query the same compiler executable path that CMake generated into compile_commands.json:

{
    "cmake.cmakePath": "cube-cmake",
    "cmake.configureArgs": [
        "-DCMAKE_COMMAND=cube-cmake"
    ],
    "cmake.preferredGenerators": [
        "Ninja"
    ],
    "stm32cube-ide-clangd.path": "cube",
    "stm32cube-ide-clangd.arguments": [
        "starm-clangd",
        "--query-driver=C:\\ST\\STBUND~1\\GNU-TO~1\\1431_S~1.2\\bin\\AR19DD~1.EXE",
        "--query-driver=C:\\ST\\STBUND~1\\GNU-TO~1\\1431_S~1.2\\bin\\AR19DD~1.EXE"
    ]
}

12. Restart clangd and re-open main.c. It detects right path:

MikkLeini_4-1771159209730.png

13. See clangd output. There's more stuff than before:

I[14:41:00.121] Loaded compilation database from c:\ST\demo\build\Debug\compile_commands.json
I[14:41:00.122] --> textDocument/publishDiagnostics
I[14:41:00.122] --> window/workDoneProgress/create(0)
I[14:41:00.122] Enqueueing 18 commands for indexing
I[14:41:00.123] <-- textDocument/codeAction(1)
I[14:41:00.124] <-- textDocument/documentSymbol(2)
I[14:41:00.124] <-- reply(0)
I[14:41:00.124] --> $/progress
I[14:41:00.124] --> $/progress
I[14:41:00.134] <-- textDocument/semanticTokens/full(3)
I[14:41:00.136] <-- textDocument/documentLink(4)
I[14:41:00.180] <-- textDocument/inlayHint(5)
I[14:41:00.188] System includes extractor: successfully executed C:\ST\STBUND~1\GNU-TO~1\1431_S~1.2\bin\AR19DD~1.EXE
    got includes: "C:\ST\st bundles\gnu-tools-for-stm32\14.3.1+st.2\bin\../lib/gcc/arm-none-eabi/14.3.1/include, C:\ST\st bundles\gnu-tools-for-stm32\14.3.1+st.2\bin\../lib/gcc/arm-none-eabi/14.3.1/include-fixed, C:\ST\st bundles\gnu-tools-for-stm32\14.3.1+st.2\bin\../lib/gcc/arm-none-eabi/14.3.1/../../../../arm-none-eabi/include, C:/ST/st bundles/gnu-tools-for-stm32/14.3.1+st.2/lib/gcc/../../lib/gcc/arm-none-eabi/14.3.1/include, C:/ST/st bundles/gnu-tools-for-stm32/14.3.1+st.2/lib/gcc/../../lib/gcc/arm-none-eabi/14.3.1/include-fixed, C:/ST/st bundles/gnu-tools-for-stm32/14.3.1+st.2/lib/gcc/../../lib/gcc/arm-none-eabi/14.3.1/../../../../arm-none-eabi/include"
    got target: "arm-none-eabi"
I[14:41:00.188] ASTWorker building file c:\ST\demo\Core\Src\main.c version 108 with command
[C:/ST/demo/build/Debug]
"C:\\ST\\st bundles\\gnu-tools-for-stm32\\14.3.1+st.2\\bin\\AR19DD~1.EXE" -DDEBUG -DSTM32F100xB -DUSE_HAL_DRIVER -IC:/ST/demo/cmake/stm32cubemx/../../Core/Inc -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/STM32F1xx_HAL_Driver/Inc -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/CMSIS/Device/ST/STM32F1xx/Include -IC:/ST/demo/cmake/stm32cubemx/../../Drivers/CMSIS/Include -mcpu=cortex-m3 -Wall -fdata-sections -ffunction-sections -mcpu=cortex-m3 -Wall -fdata-sections -ffunction-sections -O0 -g3 -std=gnu11 -o "CMakeFiles\\demo.dir\\Core\\Src\\main.c.obj" -c -ferror-limit=0 -Wno-implicit-int -isystem "C:\\ST\\st bundles\\gnu-tools-for-stm32\\14.3.1+st.2\\bin\\../lib/gcc/arm-none-eabi/14.3.1/include" -isystem "C:\\ST\\st bundles\\gnu-tools-for-stm32\\14.3.1+st.2\\bin\\../lib/gcc/arm-none-eabi/14.3.1/include-fixed" -isystem "C:\\ST\\st bundles\\gnu-tools-for-stm32\\14.3.1+st.2\\bin\\../lib/gcc/arm-none-eabi/14.3.1/../../../../arm-none-eabi/include" -isystem "C:/ST/st bundles/gnu-tools-for-stm32/14.3.1+st.2/lib/gcc/../../lib/gcc/arm-none-eabi/14.3.1/include" -isystem "C:/ST/st bundles/gnu-tools-for-stm32/14.3.1+st.2/lib/gcc/../../lib/gcc/arm-none-eabi/14.3.1/include-fixed" -isystem "C:/ST/st bundles/gnu-tools-for-stm32/14.3.1+st.2/lib/gcc/../../lib/gcc/arm-none-eabi/14.3.1/../../../../arm-none-eabi/include" --target=arm-none-eabi "-resource-dir=C:\\ST\\st bundles\\st-arm-clangd\\19.1.2+st.3\\lib\\clang\\19" -- "c:\\ST\\demo\\Core\\Src\\main.c"


----

I enabled clangd verbose mode also, but it didn't tell anything more useful.

I think it's just an incompatibility between CMake and clangd that could be solved with a right "glue" - that would be the ST extension (i guess?) that creates settings.json. Or CMake needs some option to not shorten the command paths or clangd needs some flexibility in path resolving/comparing.