CMake Tools 1.1.0 - Sorry to Keep You Waiting
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
.
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 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:
- You have to know in advance what your
includePath
anddefines
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. 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.includePath
anddefines
may not be portable. One developer box may require a completely differentincludePath
than another.- 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:
- 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.
- If I rapidly update
c_cpp_properties.json
as the environment changes, what willcpptools
do? Could it handle such uses? - Again, this is project-global. Providing for individual files isn’t possible.
- 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 #include
s should resolve,
what #define
s 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:
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:
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”.