raspberrypi / pico-vscode

The official VS Code extension for Raspberry Pi Pico development. It includes several features to simplify project creation and deployment.
https://marketplace.visualstudio.com/items?itemName=raspberry-pi.raspberry-pi-pico
Mozilla Public License 2.0
124 stars 14 forks source link

cmake-kits.json incorrect CXX compiler #107

Open Neril opened 1 day ago

Neril commented 1 day ago

TL;DR - the .vs-code/cmake-kits.json, compilers -> CXX value seems incorrectly set by default. It picks gcc.exe, not the g++ exe as the C++ compiler.


This seems easy enough to replicate: On Windows, create a project from the "blink" example, I chose SDK 1.5.1 and left the settings as default. This was on a Windows PC that had never have VS Code or Pico SDK on it before.

This resulted in a .vs-code/cmake-kits.json file like this:

[
    {
        "name": "Pico",
        "compilers": {
            "C": "${userHome}/.pico-sdk/toolchain/13_2_Rel1/bin/arm-none-eabi-gcc.exe",
            "CXX": "${userHome}/.pico-sdk/toolchain/13_2_Rel1/bin/arm-none-eabi-gcc.exe"
        },
        "toolchainFile": "${env:USERPROFILE}/.pico-sdk/sdk/1.5.1/cmake/preload/toolchains/pico_arm_gcc.cmake",
        "environmentVariables": {
            "PATH": "${command:raspberry-pi-pico.getEnvPath};${env:PATH}"
        },
        "cmakeSettings": {
            "Python3_EXECUTABLE": "${command:raspberry-pi-pico.getPythonPath}"
        }
    }
]

From some research, this may be related to the cmake plugin explicitly looking for a binary called "g++". ARM have prefixed the binary name with "arm-none-eabi-". Ref: https://github.com/microsoft/vscode-cmake-tools/blob/main/docs/kits.md#scan-for-kits

This incorrect config probably doesn't cause an issue with the blink example, but it did cause an issue with the project I was trying to work with that used C++: the build step failed at link time with various errors related to missing std c++ lib internal functions.

Related side notes (possibly separate issues):

  1. The project I was using also required that I switch to using the cmake plugin as it had various unusual cmake aspects. I noticed that when I changed the SDK version then the toolchainFile value would not update the path, i.e. it would still reference sdk/1.5.1 after switching to 2.0.0 (though the other settings in the file and elsewhere would update).
  2. After deleting the .vscode directory and reimporting the project to point at SDK 2.0.0 from the import, I noticed that it still tried to use cmake/preload/toolchains/pico_arm_gcc.cmake for the toolchainFile. AIUI, the names under 2.0.0 are slightly different, I assume because of the new Pico 2 ARM cores and RISC-V cores - so, I don't think that will work (if it's used).
Neril commented 1 day ago

A correction on (only) note 2 above: Actually, I can't see how to regenerate cmake-kits.json file / make it update to a new toolchain. Switching the SDK for cmake to use after initial blink import doesn't seem to affect the compiler version held in cmake-kits.json, shown in the cmake "change kit" drop down and then used / passed to cmake explicitly via -DCMAKE_CXX_COMPILER:FILEPATH=. The cmake dropdown for Pico still (only) lists the original/initial compiler version. This didn't lead to any obvious version skew issues for me, but presumably it would be nice if the default toolchain for the current SDK version were used.

I couldn't replicate my reported pico_arm_gcc.cmake behavior above - when freshly importing the blink example using 2.0.0: the cmake-kits.json file correctly picked up .../.pico-sdk/sdk/2.0.0/cmake/preload/toolchains/pico_arm_cortex_m0plus_gcc.cmake so something else must have been happening to lead me astray.

Neril commented 1 day ago

To clarify : my comment immediately above only applies to my side note.

i.e. the wrong CXX entry was still generated with 2.0.0.

It's just that I was unable to replicate the toolchainFile issue I mentioned, probably my mistake.

I was still unable to get the cmake-kits.json to regenerate automatically, which would lead to an old toolchain being used even after upgrading to a new SDK. i.e. moving an existing project from 1.5.1 -> 2.0.0. doesn't appear to regenerate the cmake-kits.json file. This leads to the cmake tool referencing the headers, etc. from 2.0.0 (correctly), but not using the default (newer) compiler version associated with it.

As a workaround for the cmake-kits.json issue, I imported a fresh example project using 2.0.0 and then just replaced the content of the cmake-kits.json file my existing project with the content of the new one. After fixing the CXX value, obviously.