CMake support in Visual Studio 2017 – what’s new in the RC.2 update

In case you missed the latest Visual Studio news, there is a new update for Visual Studio 2017 RC available. You can either upgrade your existing installation or, if you’re starting fresh, install it from the Visual Studio 2017 RC download page. This release comes with several enhancements in Visual Studio’s CMake experience that further simplify the development experience of C++ projects authored using CMake.

Opening multiple CMake projects

You can now open folders with an unlimited number of CMake projects. Visual Studio will detect all the “root” CMakeLists.txt files in your workspace and configure them appropriately. CMake operations (configure, build, debug) as well as C++ IntelliSense and browsing are available to all CMake projects in your workspace.

When more than one CMake project uses the same CMake configuration name, all of them get configured and built (each in their own independent build root folder) when that particular configuration is selected. You also are able to debug the targets from all of the CMake projects that participate in that CMake configuration.

In case you prefer project isolation, you can still create CMake configurations that are unique to a specific CMakeLists.txt file (via the CMakeSettings.json file). In that case, when the particular configuration is selected, only that CMake project will be available for building and debugging and CMake-based C++ IntelliSense will only be available to its source files.

Editing CMake projects

CMakeLists.txt and *.cmake file syntax colorization. Now, when opening a CMake project file, the editor will provide basic syntax colorization and IntelliSense based on TextMate.

Improved display of CMake warnings and errors in Error List and Output Window. CMake errors and warnings are now populated in Error List window and double-clicking on one in either Error List or Output Window will open the CMake file at the appropriate line.

Configuring CMake

Cancel CMake generation. As soon as you open a folder with a CMake project or operate changes on a CMakeLists.txt file, the configuration step will automatically start. If for any reason, you don’t expect it to succeed yet, you can cancel the operation either from the yellow info-bar in the editor or by right-clicking on the root CMakeLists.txt and selecting the option “Cancel Cache Generation”

Default CMake configurations have been updated. By default, VS offers a preset list of CMake configurations that define the set of switches used to run CMake.exe to generate the CMake cache. Starting with this release, these configurations are “x86-Debug”, “x86-Release”, “x64-Debug” and “x64-Release”. Note that if you already created a CMakeSettings.json file, you will be unaffected by this change.

CMake configurations can now specify configuration type (e.g. Debug, Release). As part of a configuration definition inside the CMakeSettings.json, you can specify which configuration type you want the build to be (Debug, MinSizeRel, Release, RelWithDebInfo). This setting is also reflected by C++ IntelliSense.

CMakeSettings.json example:

All CMake operations have been centralized under a “CMake” main menu. Now you can easily access the most common CMake operations for all the CMakeLists.txt files in your workspace from a central main menu called “CMake”.

Use “Change CMake Settings” command to create or edit the CMakeSettings.json file. When you invoke “Change CMake Settings” from either the main menu or the context menu for a CMakeLists.txt, the CMakeSettings.json corresponding to the selected CMakeLists.txt will be open in the editor. If this file does not exist yet, it will be created and saved in the same folder with the CMakeLists.txt.

More granular CMake cache operations are now available. Both in the main menu as well as in the CMakeLists.txt context menu, there are several new operations available to interact with the CMake cache:

Generate Cache: forces the generate step to rerun even if VS considers the environment up-to-date

Clean Cache: deletes the build root folder such that the next configuration runs clean

View Cache: opens the CMakeCache.txt file from the build root folder. You can technically edit the file and save, but we recommend using the CMakeSettings.json file to direct changes into the cache (as any changes to CMakeCache.txt are wiped when you clean the cache)

Open Cache Folder: Open an Explorer window to the build root folder

Building and debugging CMake targets

Build individual CMake targets. VS now allows you to select which target you want to build in addition to opting for a full build.

CMake install. The option to install the final binaries based on the rules described in the CMakeLists.txt files is now available as a separate command.

Debug settings for individual CMake targets. You can now customize the debugger settings for any executable CMake target in your project. When selecting “Debug and Launch Settings” context menu for a specific target, a file launch.vs.json is created that is prepopulated with information about the CMake target you have selected and allows you to specify additional parameters like arguments or debugger type.

As soon as you save the launch.vs.json file, an entry is created in the Debug Target dropdown with the new name. By editing the launch.vs.json file, you can create as many debug configurations as you like for any number of CMake targets.

Join the conversation

Good feedback. Indeed, we’re very cautious about that. Most of the features here though were already mostly implemented, we just wanted to take a bit longer than RC to light up these experiences in the IDE. Some are also based on feedback from customers that we considered critical to address in VS before RTM. Hope you give it a try and share your thoughts.

Why do not you believe the MS people? If they say this is the RC this IS the RC. And it will be released at the prescribed time by weight at all costs. There are no Gates or Ballmer to prevent this anymore. Just look at the Windows Server 2016. It requires a third-party component for it’s normal functionality (containers) and the component is the open-source slapdash article with it’s own development cycle totally weird to the enterprise world. Though I believe the MS does its best to compete in the modern world where the software is given away for free. And it looks obvious that they just cannot afford the quality they used to provide earlier on.

Two Xbox Live Services, more than 3 mobile phone services, more than 4 telemetry services and in total more than 10 non-sense services running by default on a Server. Not a serious server OS.

Any serious company never install a Server OS like this. Serious IT’s never recommends an OS Server like this. I don’t believe any company installing this. Seeing how Linux Server marketplace grows this next years. Microsoft is really doing what users needs and demands, like Windows 10.

P.D.: Microsoft don’t like this comment, or don’t like to make public that this fantastic services are installed by default in Windows Server 2016 because i post it again, this is the second time I post it, the first time Microsoft delete my post telling the same thing.

What about out-of-source builds? For big (especially cross-platform) projects normally man does not open cmakelists.txt and does not build ‘in-sources’, instead he creates a separate folder and inside the folder runs something like ‘cmake -G … ‘ and ‘cmake –build .’. Is it possible (or is it planned to implement this) to put that .json config in some empty folder and let VS work in ‘out-of-source’ mode?

There are no intermediate/temporary CMake files that are getting created in the source folder today as far as I know. Out-of-source builds is exactly what VS does by default. It picks a folder under %LOCALAPPDATA%\CMakeBuild for the CMake output that you can overwrite in the CMakeSettings.json file by changing the buildRoot property. The CMakeSettings.json is not meant to be a temporary file but a file that is associated with the root CMakeLists.txt that you can potentially share with the rest of the team and it serves are as a recipe on how to invoke CMake. Can you expand on how you believe CMakeSettings.json might get in the way?

Probably a dumb question, but… Is it possible to configure cmake/VS-cmake tool to use C++ nuget packages for a project, possibly within ifdef(WIN32)? I love nuget and I don’t want to lose this convenience while moving to cmake-based cross-platform dev. Thanks!

I’m not aware of an easy way to do that, but have you looked at https://aka.ms/vcpkg and its long list of C++ libraries that are already supported? It comes with both MSBuild and CMake integration out-of-the-box and it’s pretty easy to get going

It looks like the tool that the MSBuild CustomBuild task invoked has experienced a crash or internal error. To get better diagnostics, I recommend changing the “buildCommandArgs” to “-m -v:diag” and request another build. Then in the very verbose log look for the same error and the surrounding messages to see if there are more clues on what the issue is. If you believe the issue to be a VS problem, please open a new issue ticket here: https://developercommunity.visualstudio.com/. Thanks!

Is the CMake support developed as a pure add-in? Would it be possible for users or the community to develop support for other (meta-)build systems with equality parity to the CMake support? Are the necessary docs for the add-in APIs available, if indeed it is an add-in?

While it is technically possible to develop an extension equivalent to the CMake support, not all VS Extensibility APIs are currently documented so there is some effort and risk in taking on that endeavor. For now I recommend taking a look at the generic “Open Folder” support https://aka.ms/openfolder/cpp which provides similar capabilities to CMake through more granular json configuration files for C++ IntelliSense, building and debugging. What other build systems do you have in mind? (please reach out to me offline at mluparu at microsoft dotcom if you want to chat more about this)

I’m aware of the Open Folder support. I’m pleased with the concept. I’m still interested in generalizing that little bit of extra integration the CMake integration has since as an engineer I don’t like the idea of magic one-off solutions that can’t be reused for anything else. :)

In the immediate moment, I’d like to be able to add first class support for proprietary build systems that many companies use (e.g. Unreal’s build system, or Blizzard’s fork of premake, or so on).

But really, I’d want to see the community implement solid support for anything other than CMake. :) I consider CMake to be this generation’s Autotools. ;) See meson, build2, gn, fastbuild, premake, tup, and many many others for what the community is doing to try to find a way forward from CMake.

Even sticking with CMake, there’s very strong reasons for community support. e.g. we may want to use VS2017 with CMake 4.x when it’s out for example but it sounds so far like we’d be stuck with 3.6 indefinitely (which doesn’t even work for us – CMake 3.7 already has major fixes that we’re chomping at the bit to use, e.g. it _finally_ makes it possible to get PCHs in GCC/Clang to work reliably with the Ninja backend). If the community can’t upgrade, maintain, extend, or fix this VS add-in then it won’t stay up-to-date with the upgrades, maintenance, extensions, and fixes that go into CMake itself!

Supporting CMake in VS is a good step because it is close to ubiquitous right now and of course supporting existing technology is super important. However, we’re seeing a renaissance in build systems these days (which we haven’t seen since the days when CMake first gained popularity) and being able to let the community support those systems (or any proprietary in-house systems) without needing to write VS/msbuild converters would be most excellent. :)

I feel there’s a lot of strong discussion to have here that doesn’t fit well to a comment box on an article like this. I’d be happy to have a more in-depth conversion; if that’s welcome on your end, I’m sure we could arrange it. :)

These updates are pretty awesome! With these changes, I am much more likely to use this CMake integration.

Consider renaming the “Open Cache Folder” menu item as “Open Build Directory” or “Open Build Folder.” This is clearer to me; to me, the “CMake cache” is only the “CMakeCache.txt” file, and nothing else. Having this item in the menu is fantastic, though, and I plan to use it often. I also understand the desire to avoid a new term (everything else uses the term “cache”), so I think it is also fine to leave this as “Open Cache Folder.”

Do all the CMake-generated VS projects still appear in the Solution Explorer? Or is the only way to build a CMake target now to right-click the CMakeLists.txt and click “Build >”?

I’m worried about confusion between CMake and VS terms: both VS and CMake use the word “configuration”; it is a little confusing that CMakeSettings.json has a “configuration” field that contains a “configuration” field (the outer one being VS’s, the inner one being CMake’s). Similarly for the term “project”. A VS project is analogous to a CMake target and a VS solution is analogous to a CMake project. If you could find a way to clear up confusion with these terms, that would be great (i.e., always prefacing “project” with “CMake project”).

Odd question. I have code that uses CaptureStackBackTrace + SymFromAddr (dbghelp.lib) to do native callstacks and this all works fine with VS 2015, however it fails with 2017.

CaptureStackBackTrace is good — it succeeds and VS’s debugger window even translates the raw addresses I get back into their correct english stack names (neat). However, SymFromAddr always fails with a GetLastError of 487 or 126.

Could this be due to differing c runtimes or is this something else to go and investigate?

Does RC2 fix C++ intellisense for included header files in CMake projects? I’ve tried RC1 with target_include_directories(..) and things compile, but intellisense is totally lost for everything that is outside of the project directory. This is a showstoppper for using these new style CMake projects in visual studio.

Finally found the solution for this: add SYSTEM to the target_include_directories and use #include with angle brackets instead of quotes. For my particular case this was actually more correct so that was good, although it is still a bit odd that target_include_directories without SYSTEM does not add any include-paths to quote-#includes.

The intellisense bug with header files does not seem to be fixed on my end… But it seems to happen very randomly as rebuilding the project can either fix or break the feature. And the fix you mention does not seem to work for me. Hopefully it will be fixed in the next version..!

Any chance of splitting “buildRoot” into “cacheRoot” and “buildRoot”? While I’m definitely a cmake newb, I don’t think in cmake land that CMAKE_BINARY_DIR actually has anything to do with where the cache file is. Personally, I don’t know how anyone can be okay with having a mess of generated cmake files cluttering the actual build folder.

Seems like cacheRoot could default to whatever is set for buildRoot if it’s not specified, which wouldn’t break existing settings files.

Eh. Scratch that I’m just a huge newb. Search for out-of-source builds if you’re interested in the topic. Otherwise you can set CMAKE_INSTALL_PREFIX in your CMakeSettings.json and use “Install CMakeLists.txt” from the CMAKE menu to basically get what I was after.

How can we set the output folder for target files when built? I tried to set the CMAKE_RUNTIME_OUTPUT_DIRECTORY in the variables section of the CMakeSettings.json, but it doesn’t work. The output bin folder remains in a subfolder of the buildRoot, where the CMake cache is stored. Thanks.

Is there any way to use variable like ${workspaceRoot} in the variables section of the CMakeSettings.json? The issue is that the backslash used between folder in ${workspaceRoot} are not escaped (\\) and so, the path is rejected by CMake. Thanks.

You really need to upgrade to CMake 3.7.1 before you release VS 2017! Without it, one cannot build Tesseract OCR as a CMake-based solution. Simply substituting the CMake 3.7.1 components for the CMake 3.6 components that Microsoft provides does not result in successful generation of CMake Cache contents, apparently because the interface libcmake that Microsoft provides doesn’t work successfully with CMake 3.7.1.

While it is true that you could manually use CMake 3.7.1 to generate the tesseract solution, that is less than ideal

Is there a way to change the debugging environment in the launch.vs.json file to change the PATH when debugging? (Like it can be done with the debugging environment in the regular Visual Studio projects)

I’m having troubles with the includes. Everything seems to be working fine with existing code when I loaded the CMake project but when adding a new header it won’t find includes (in angle brackets) that other headers have no trouble finding. I’ve deleted and recreated the cache a few times and it doesn’t help.