Files
VS-Code-CMake-helper/README.md
2026-10-26 20:44:41 +00:00

101 lines
8.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VS Code CMake Helper
CMake in VS Code the way CLion does it. Standalone: it doesn't need (or want) Microsoft's CMake Tools, so turn that off in workspaces where this one runs. Projects are read through CMake's File API (CMake 3.14+; presets need 3.19+, test results 3.21+).
## What it does
- **Profiles** (the Profiles view, the `$(layers)` item in the status bar): each one is a build directory with its own build type, generator, toolchain, cache variables and environment. They come from the `cmakeHelper.profiles` setting and from the configure presets in `CMakePresets.json` / `CMakeUserPresets.json`. With neither, there's CLion's default: **Debug** in `cmake-build-debug`. Switching profiles reads that directory's last configure if there is one, and configures otherwise.
- **Targets** (the Targets view): executables, libraries and custom targets (`add_custom_target`; `showUtilityTargets` turns them off; CTest's dashboard targets are never listed), each with its sources in CMake's source groups. Inline buttons ▶ Run, 🐞 Debug, 🔨 Build. The menu has *Set as Active*, *Edit Run Configuration…*, *Rebuild*, *Go to Definition in CMakeLists* and *Copy Path of the Built File*.
- **One active target** in the status bar: `$(target) app`, then 🔨 ▶ 🐞. Keys as in CLion: **Ctrl+F9** build, **Shift+F10** run, **Shift+F9** debug, **Alt+Shift+F10** choose the target.
- **Run configurations per target**, edited as CLion's *Run/Debug Configurations* (*Edit Run Configuration…* on a target, or *Edit Configurations…* in the target picker): every target on the left, by kind; on the right its executable (the target's own, another target's, or a file: what a custom target or a library runs after it's built), program arguments, working directory (default: the executable's directory), environment (`A=1;B=2`) and *Before launch: Build*. A custom target with no executable is only built by ▶, as in CLion; 🐞 debugs the program its command runs (`COMMAND app --flag`: `app` with `--flag`, in the command's directory, with `cmake -E env`'s variables), after building what the target depends on (not the target itself, which would run the command). The command comes from the build system, so this needs a Ninja or Makefile generator. They're kept in the workspace settings under `cmakeHelper.runConfigurations`.
- **Debugging** through C/C++ (`cppdbg`, or `cppvsdbg` with MSVC), CodeLLDB or LLDB DAP: the first one installed, or the one set in `cmakeHelper.debugger`. Extra launch properties go in `cmakeHelper.debugConfiguration`.
- **CTest in the Test Explorer**: tests are grouped by the target whose executable they run, and by suite for names like `Suite.Test`. Each one sits at its `TEST(…)` / `TEST_CASE("…")` / `BOOST_AUTO_TEST_CASE(…)` in the sources (with ▶ in the gutter), or else at its `add_test`. Running builds the tests' targets first, then calls `ctest` and reads the results from JUnit. Debugging starts the test's command under the debugger. Tests that `gtest_discover_tests` finds only after a build show up once the build is done.
- **Code lenses**: ▶ Run / 🐞 Debug above `main()` in an executable's sources, and Run / Debug / Build above each `add_executable` / `add_custom_target`, and Build above each `add_library`, in CMake files.
- **Load CMake Project** on a `CMakeLists.txt` (the explorer's and the editor's context menu, as in CLion): that folder becomes the project (`cmakeHelper.sourceDirectory`) and it's configured; on the project's own `CMakeLists.txt` the menu has *Reload CMake Project*.
- **Reload**: when one of the project's CMake files changes, a notification and a `Reload CMake` item in the status bar appear (`cmakeHelper.autoReload`: `ask`, `always`, `never`). *Reset Cache and Reload Project* removes `CMakeCache.txt` and `CMakeFiles/` first. A generator mismatch offers the reset by itself.
- `compile_commands.json` is exported (`exportCompileCommands`), and can be copied where clangd looks for it (`copyCompileCommands`, e.g. `${sourceDir}/compile_commands.json`).
- For `launch.json` / `tasks.json`: `${command:cmakeHelper.activeProgram}`, `${command:cmakeHelper.activeTarget}`, `${command:cmakeHelper.buildDirectory}`, `${command:cmakeHelper.buildType}`.
## Embedded and remote debugging
As CLion's *Embedded GDB Server* and *Remote GDB Server* run configurations: **CMake: Edit GDB Server Configurations…** (or *New GDB Server Configuration…* in the target picker). A configuration chosen in the target picker (it shows there under the targets) is what the toolbar's 🔨, ▶ and 🐞 act on; choosing a target goes back to running it here.
- **Embedded GDB Server**: a GDB server started here (OpenOCD, SEGGER J-Link, ST-LINK's st-util, pyOCD: *Fill in for* sets the usual arguments), gdb (`gdb-multiarch`, `arm-none-eabi-gdb`…) connected with `target remote`, the program downloaded (*Always*, *If updated*, *Never*) between two reset commands. 🐞 debugs it; ▶ is *Download & Run*: flash, start it (`monitor reset run` by default), detach, no debugger.
- **Remote GDB Server**: gdb connected to a gdbserver elsewhere, with a sysroot and path mappings. With an SSH host the program is first uploaded (scp) and gdbserver started there over SSH, and ▶ runs it there.
Debugging goes through C/C++ (`ms-vscode.cpptools`, `cppdbg`), which starts the server and connects. The configurations are kept in the workspace setting `cmakeHelper.gdbConfigurations`.
## Profiles in settings
**CMake: Edit Profiles…** (the ⚙ on a profile, or in the profile picker) edits them as CLion's Settings › Build › CMake does: the list with add, remove, copy and move, and each profile's name, *Enable profile*, build type, toolchain file, generator, CMake options, build directory, build options and environment; OK / Cancel / Apply. Presets are shown read-only; copying one makes a profile of it. It writes the workspace setting below (cache variables become `-D` CMake options).
```jsonc
"cmakeHelper.profiles": [
{ "name": "Debug", "buildType": "Debug" },
{ "name": "Release", "buildType": "Release", "generator": "Ninja" },
{
"name": "ASan",
"buildType": "RelWithDebInfo",
"buildDirectory": "cmake-build-asan",
"cacheVariables": { "CMAKE_CXX_FLAGS": "-fsanitize=address", "BUILD_TESTING": true },
"environment": { "ASAN_OPTIONS": "detect_leaks=1" }
}
]
```
## Toolbar
`cmakeHelper.toolbar` says where CLion's toolbar (profile, target, Build, Run,
Debug) goes:
- `statusBar` (default): in the status bar.
- `editorTitle`: Build, Run, Debug and the profile and target pickers as
buttons at the top of the editors; the names stay in the status bar.
- `titleBar`: in VS Code's title bar, as in Jarvis's web IDE. An extension
can't put anything there, so VS Code itself is patched: `media/titlebar.js`
goes next to its `workbench.html` and into it, and `product.json`'s checksum
is updated so VS Code doesn't call its installation corrupt. VS Code is
usually root's, so it asks for your password (pkexec). After a VS Code update
(which drops the patch) or an update of this extension, it offers to patch
again. **CMake: Remove the CMake Toolbar from the Title Bar** undoes it.
## Updates
The extension looks at the latest release of `shin/VS-Code-CMake-helper` on
git.cernikovi.cz on start and every 10 minutes, and offers a newer one: Install
downloads its `.vsix` and installs it. The repository is private, so it needs a
Gitea access token with read access: **CMake: Set Gitea Token for CMake Helper
Updates** (kept in VS Code's secret storage). **CMake: Check for CMake Helper
Updates** looks now; it's also in the Targets view's `…` menu and in the
extension's context menu in the Extensions view. `cmakeHelper.updates.check`
turns it off.
A release is made by the CI on a `v*` tag matching the version in `package.json`.
## Development
Everything runs in the image of the `Dockerfile`: Node for the extension, and
CMake, Ninja, g++ and GDB for what it drives.
- **Dev container:** open this folder in VS Code and *Reopen in Container*
(Dev Containers extension). `npm ci` runs on creation; F5 **Run Extension
(example)** opens `example/`, a small project (a library, an executable, a
CTest test) to try it on.
- **Without VS Code:** `./scripts/docker.sh <command>` runs a command in the
image, in this folder and as you, e.g. `./scripts/docker.sh npm run package --
--skip-license`; without a command it's a shell.
The title bar patch (`cmakeHelper.toolbar`: `titleBar`) can't be tried in the
container: there the extension runs remotely and VS Code's installation is
the host's.
## Building
```
npm install
npm run compile # out/
npm run package # .vsix
```
To try it, open this folder in VS Code and press F5 (Run Extension), or install the `.vsix`.