As of this writing, CMake Tools is approaching its five-hundredth GitHub item (This includes issues and pull requests). I set out to make a simple extension to do the bare bones of what I needed, but now have one of the most popular extensions in the VSCode marketplace. I’m humbled, truly.

In my last post, I talked about how I wanted to get more IDE-style features and start to approach the functionality of heavy-duty development environments. I’m proud to announce the first iteration into that territory with CMake Tools 1.1.0!

VSCode API additions have been made over the past year that I haven’t yet utilized — until now. Let’s take a look in order of most exciting features.

The Updates

Automatic Configuration

We’ll start pretty slow. This one’s simple but useful for some later feature additions. Upon opening a project, CMake Tools will check if you have configured it to auto-configure projects. If not, it will ask you and possibly persist your choice to settings.json.

Automatic Project Configuration

The Project Outline

Other IDEs like QtCreator and big-brother Visual Studio have featured this for a while: A CMake-centric view of a project. This features grouping of source files based on their owning targets, as well as shortcuts to perform actions on those targets based on the editor’s understanding thereof.

CMake Tools 1.1.0 introduces the first iteration of this feature as a tree view that displays the project with targets layed out based on their position in the filesystem:

The Project Outline

The outline will only populate after a project has been configured. Enabling automatic configure allows the Project Outline to be read as soon as possible.

From the outline, you can browse the sub-projects available in the workspace, the targets of each sub-project, and the source files within those targets.

The context menu for each target allows you to set the target as the default build target or build it one-shot. The context menu for executable targets allow one to set the executable as the launch/debug target, or just one-shot launch/debug the target.

Right-clicking a target also shows an Open CMakeLists.txt item, which will jump to the CMakeLists.txt where the target is defined to the line where that target is first declared.

Clicking on a source file will open it in the editor. Right-click on a source file allows one to compile the individual source file in a new terminal window. This can be useful for debugging compile flags and options.

The Project Outline is still in its first iteration. If you find any issues or have any feedback/requests, feel welcome to open a GitHub issue!

The Moment You’ve All Been Waiting For…

Of the nearly five-hundred issues opened against the extension, the oldest still open is Issues #22. From the day I started working on CMake Tools I’ve wanted a good story for C++ code navigation and auto-completion. The trouble is in the complexity of C++’s build process. #include directories can live anywhere. Preprocessor definitions and compiler flags can have a huge effect on what gets included and what code might look like. It’s a tough story.

Microsoft’s C/C++ extension (cpptools) is the most used extension for native developers, and provides a good IntelliSense and browsing engine that supports most C++ constructs in use today. The big trouble? Configuring it!

For a long time, cpptools’ primary configuration interface was the c_cpp_properties.json file. In it you could specify the includePath and defines for you project. This presented a few big problems for complex projects:

  1. You have to know in advance what your includePath and defines are. If you find package paths dynamically or on a case-by-case basis, you may not have the slightest idea where packages will live. If you have many of these packages you’ll end up maintaining a very large list of paths.
  2. defines can vary based on environmental factors or CMake configurations. For example, NDEBUG will be defined in a release build, but _DEBUG needs to be defined in a debug build.
  3. includePath and defines may not be portable. One developer box may require a completely different includePath than another.
  4. The settings in c_cpp_properties.json are project-wide, while compiler options can (and often!) vary on a file-by-file basis.

Auto-generating a best-guess c_cpp_properties.json file wouldn’t be hard. There have been several attempts to do so, including “glue” extensions which will auto-generate this file based on CMake Tools’ API. There’s a reason I’ve never bitten the bullet and implemented the auto-generation of c_cpp_properties.json myself. I’ll defer to the old adage, variously (and incorrectly) attributed to Mark Twain, HL Mencken, and others:

For every complex problem, there is a solution that is simple, obvious, and wrong.*

Generating the c_cpp_properties.json file presents a few problems:

  1. Not all files have the same flags. Which one do I chose? Do I append all flags from all files? That would mean that none of the files will have the correct flags.
  2. If I rapidly update c_cpp_properties.json as the environment changes, what will cpptools do? Could it handle such uses?
  3. Again, this is project-global. Providing for individual files isn’t possible.
  4. If I go this route, it will be cemented for all time as a half-baked solution.

Well, all the worries are now a thing of the past: CMake Tools 1.1.0 now integrates with cpptools to provide a featureful, complete, and correct editing experience!

cpptools Integration has Landed!

cpptools now exposes an extensibility API for custom configuration provision. CMake Tools 1.1.0 implements and uses that API. Put ‘em together and you’ve got IntelliSense that knows exactly where your #includes should resolve, what #defines are in effect, what compiler you are using, and what -std flag you’ve set for a file.

So what does it look like? Well, first you configure your CMake Project like so:

Custom Configuration Provider Startup

And click Allow in the notification box that appears.

That’s it. You’re done!

cpptools and CMake Tools are now talking back-and-forth to coordinate on giving you the most accurate and complete IntelliSense results yet!

These integrations are new, so if you find any issues please open a ticket on the CMake Tools GitHub page.

A Demonstration

I said I’d finally be satisfied when the VS Code editor could have a certain behavior that I’ve found in many other IDEs in the past. Rather than describe it wordily I’ll just show the behavior in action:

Debug Release Switching

It’s been fun, GitHub Issue #22, but it’s time to say good-bye.


* Note that no famous author or scholar actually said these words verbatim. It’s a misquote of an excerpt from a letter written by HL Mencken. The original words don’t quite have the same nice cadence: There is always a well-known solution to every human problem—neat, plausible, and wrong.