VS Code - cmake - ninja - intellisense problem

I migrated (with substantial help from folks like @MultipleMonomials and @JonnyK ) the “Blinky” example program from MBed Studio to VS Code. I got it to build and run ok, but I noticed a problem with the intellisense feature of the VS Code IDE.

Basically, intellisense does not appear to work… for instance, here is a screenshot of a snippet of a cpp file:
Screen Shot 2022-10-17 at 2.20.58 PM
Notice the squigglies… If I hover over one of those (e.g. LED_RED), it produces a pop-up with the message: identifier “LED_RED” is undefined. However, the project builds just fine.

I dug a bit into this, and from what I understand, there was an implication that the intellisense feature is built on Make. Back when I last used VS Code (another job), the CMake built Makefiles, which could be used by intellisense to parse the code and allow you to easily navigate around.

Apparently, things have changed, and now CMake invokes a build system called Ninja, which bypasses the need for Make – so intellisense doesn’t have the makefiles for navigation.

Or maybe I’m completely not understanding how intellisense works, and I’ve just missed a setting somewhere.

Can somebody point me in the right direction to get past this?

I’m running on a MacBook with
macOS Monterey 12.6
build variant Debug MAX32620FTHR
GCC 10.3.1 arm-none-eabi-gcc
IntelliSense mode: $(default)
Include path setting:

${workspaceFolder}
${workspaceFolder}/mbed-os/**

Here is my c_cpp_properties.json file:

{

    "configurations": [
        {
            "name": "Mac",
            "includePath": [
                "${workspaceFolder}",
                "${workspaceFolder}/mbed-os/**"
            ],
            "defines": [],
            "macFrameworkPath": [],
            "compilerPath": "/opt/homebrew/bin/arm-none-eabi-gcc",
            "cStandard": "gnu17",
            "cppStandard": "gnu++17",
            "intelliSenseMode": "${default}",
            "configurationProvider": "ms-vscode.makefile-tools"
        }
    ],
    "version": 4
}

The line: “configurationProvider”: “ms-vscode.makefile-tools” looks suspicious, but I’m having some difficulty figuring out where it comes from or how to change it.

Aha!!! I think I found it. After digging through VSCode C/C++ Schema Reference, I saw that I could specify “configurationProvider”: “ms-vscode.cmake-tools” for that line that looked suspicious.

And it actually worked. So this problem is solved. I’ll leave it up in case somebody else stumbles over the same problem.

2 Likes

Thanks, I have now also checked this setting again and my config looks now like this:

c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Mbed",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "compilerPath": "c:\\Program Files (x86)\\GNU Arm Embedded Toolchain\\10 2021.10\\bin\\arm-none-eabi-g++.exe",
            "intelliSenseMode": "${default}",
            "cStandard": "c17",
            "cppStandard": "c++17",
            "configurationProvider": "ms-vscode.cmake-tools"
        }
    ],
    "version": 4
}

The important thing is the configurationProvider: cmake-tools. Then Intellisense can use the cmake generated file compiler_settings.json and then Intellisense can parse the correct include path. This file is generated by a cmake setting which is not enabled for the original mbed-os cmake, so this magic cannot work with mbed-os. However, mbed-os could be simply improved by enabling this setting?
Please correct me if I’m wrong.

I have named the set ‘Mbed’, I think the setting Win32 or Mac is misleading, because it refers to the target environment. There can be multiple configurations, they are selectable in blue status bar.
One nasty thing is the compiler path, it should be unnecessary because it also known and selected by cmake. Its not clear to me what to set here.
edit:
I have changed the compiler_path now to “” and it still works, e.g. a printf() is found in the current gcc includes. But it is difficult to test. I have reset the intellisense database and waited for the DB to rebuild, but it is not clear what maybe remains in a cache.

I noticed that in the MBed Studio, I could use printf() to write to the debug console. So far, I have not been able to figure out how to get printf() to output anywhere I could find when using VSCode, so yes, that’s hard to test. I’m hoping that this is simply the result of some environment variable or internal setting that I have not yet found. If I can’t puzzle that out fairly soon, I’ll ask about that one in a new thread.

As for the configuration name, I interpreted that as the name of the development host, so I didn’t think of it as misleading to specify “Mac” since I’m using a company MacBook for development.

Speaking of which, some of the problems I’ve run into on my current project can be traced directly to my relative lack of familiarity with macOS. I’m used to various Linux distros, and the subtle difference of the underlying Unix implementation from Apple tend to clash with my Linux finger-habits :slight_smile:

Hello guys,

I absolutely do not understand things around settings of VSCode, but I did not set anything of these settings what you did.
I did not try any large project, but I do not have any issue with intellisense. Jamie’s Cmake build system creates launch.json and set some necessary settings automatically.

{
    "configurations": [
	{
	    "type": "cortex-debug",
	    "name": "Connect to GDB main NUCLEO_F767ZI Debug",
	    "executable": "C:/Users/User/MbedCE_Test/build/main.elf",
	    "cwd": "${workspaceRoot}",
	    "gdbPath": "C:/Program Files (x86)/GNU Arm Embedded Toolchain/9 2020-q2-update/bin/arm-none-eabi-gdb.exe",
		"objdumpPath": "C:/Program Files (x86)/GNU Arm Embedded Toolchain/9 2020-q2-update/bin/arm-none-eabi-objdump.exe",
		"servertype": "external",
		"gdbTarget": "localhost:23331",
		"request": "attach"
	},
    ]
}

Nothing more nothing less, just this and automatically.

BR, Jan

Hi Jan,

the launch.json is needed for the debugger settings and does not affect the intellisense.

The Intellisense needs to know which files are included in a project. The mbed-os contains zillions of files, but not all need to be analysed. E.g., the target PinNames.h exits many times, so a symbol PA_0 is found many times when all sources are analyzed. In earlier attempts from Jan Jongboom, he used a python script to generate the include_path in c_cpp_properties.json (the Intellisense config). But this was also not the best way.
Now cmake is able to generate a config file name compile_commands.json in the build dir and the Intellisense extension can consume this file. CMake needs the setting CMAKE_EXPORT_COMPILE_COMMANDS=TRUE to do this. I haven’t found this in Jamies CE, but it works.
edit: -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE is set on first cmake call

Now I have tried to add turning on this setting also in the mbed-os cmake and the compile_commands.json is also created. But the original cmake is not adapted to the VSC cmake tools, the build dir name is different and the VSC extension cannot find the compile commands. It works when I set the “compileCommands”: “cmake_build/…” in the c_cpp_properties.json. But this is not conveniant, just to understand the relations. Jamies cmake is much better to use with VSC.