Cmake For Visual Studio 2019

Jan 24, 2019 Visual Studio 2019 Preview 2 introduces a new CMake Project Settings Editor to help you more easily configure your CMake projects in Visual Studio. The editor provides an alternative to modifying the CMakeSettings.json file directly and allows you to create and manage your CMake configurations. The v142 toolset that comes with Visual Studio 16 2019 is selected by default. The CMAKEGENERATORTOOLSET option may be set, perhaps via the cmake (1).

-->

Visual Studio C and C++ development isn't just for Windows anymore. This tutorial shows how to use Visual Studio for C++ cross platform development on Windows and Linux. It's based on CMake, so you don't have to create or generate Visual Studio projects. When you open a folder that contains a CMakeLists.txt file, Visual Studio configures the IntelliSense and build settings automatically. You can quickly start editing, building, and debugging your code locally on Windows. Then, switch your configuration to do the same on Linux, all from within Visual Studio.

In this tutorial, you learn how to:

  • clone an open-source CMake project from GitHub
  • open the project in Visual Studio
  • build and debug an executable target on Windows
  • add a connection to a Linux machine
  • build and debug the same target on Linux

Prerequisites

  • Set up Visual Studio for Cross Platform C++ Development

    • First, install Visual Studio and choose the Desktop development with C++ and Linux development with C++ workloads. This minimal install is only 3 GB. Depending on your download speed, installation shouldn't take more than 10 minutes.
  • Set up a Linux machine for Cross Platform C++ Development

    • Visual Studio doesn't require any specific distribution of Linux. The OS can be running on a physical machine, in a VM, or in the cloud. You could also use the Windows Subsystem for Linux (WSL). However, for this tutorial a graphical environment is required. WSL isn't recommended here, because it's intended primarily for command-line operations.

    • Visual Studio requires these tools on the Linux machine: C++ compilers, gdb, ssh, rsync, make, and zip. On Debian-based systems, you can use this command to install these dependencies:

    • Visual Studio requires a recent version of CMake on the Linux machine that has server mode enabled (at least 3.8). Microsoft produces a universal build of CMake that you can install on any Linux distro. We recommend you use this build to ensure that you have the latest features. You can get the CMake binaries from the Microsoft fork of the CMake repo on GitHub. Go to that page and download the version that matches the system architecture on your Linux machine, then mark it as an executable:

    • You can see the options for running the script with -–help. We recommend that you use the –prefix option to specify installing in the /usr path, because /usr/bin is the default location where Visual Studio looks for CMake. The following example shows the Linux-x86_64 script. Change it as needed if you're using a different target platform.

  • Git for windows installed on your Windows machine.

  • A GitHub account.

Clone an open-source CMake project from GitHub

This tutorial uses the Bullet Physics SDK on GitHub. It provides collision detection and physics simulations for many applications. The SDK includes sample executable programs that compile and run without having to write additional code. This tutorial doesn't modify any of the source code or build scripts. To start, clone the bullet3 repository from GitHub on the machine where you have Visual Studio installed.

  1. On the Visual Studio main menu, choose File > Open > CMake. Navigate to the CMakeLists.txt file in the root of the bullet3 repo you just downloaded.

    As soon as you open the folder, your folder structure becomes visible in the Solution Explorer.

    This view shows you exactly what is on disk, not a logical or filtered view. By default, it doesn't show hidden files.

  2. Choose the Show all files button to see all the files in the folder.

Switch to targets view

When you open a folder that uses CMake, Visual Studio automatically generates the CMake cache. This operation might take a few moments, depending on the size of your project.

  1. In the Output Window, select Show output from and then choose CMake to monitor the status of the cache generation process. When the operation is complete, it says 'Target info extraction done'.

    After this operation completes, IntelliSense is configured. You can build the project, and debug the application. Visual Studio now shows a logical view of the solution, based on the targets specified in the CMakeLists files.

  2. Use the Solutions and Folders button in the Solution Explorer to switch to CMake Targets View.

    Here is what that view looks like for the Bullet SDK:

    Targets view provides a more intuitive view of what is in this source base. You can see some targets are libraries and others are executables.

  3. Expand a node in CMake Targets View to see its source code files, wherever those files might be located on disk.

Add an explicit Windows x64-Debug configuration

Cmake for visual studio 2019 full

Visual Studio creates a default x64-Debug configuration for Windows. Configurations are how Visual Studio understands what platform target it's going to use for CMake. The default configuration isn't represented on disk. When you explicitly add a configuration, Visual Studio creates a file called CMakeSettings.json. It's populated with settings for all the configurations you specify.

  1. Add a new configuration. Open the Configuration drop-down in the toolbar and select Manage Configurations.

    The CMake Settings Editor opens. Select the green plus sign on the left-hand side of the editor to add a new configuration. The Add Configuration to CMakeSettings dialog appears.

    This dialog shows all the configurations included with Visual Studio, plus any custom configurations that you create. If you want to continue to use a x64-Debug configuration, that should be the first one you add. Select x64-Debug, and then choose the Select button. Visual Studio creates the CMakeSettings.json file with a configuration for x64-Debug, and saves it to disk. You can use whatever names you like for your configurations by changing the name parameter directly in CMakeSettings.json.

Set a breakpoint, build, and run on Windows

In this step, we'll debug an example program that demonstrates the Bullet Physics library.

  1. In Solution Explorer, select AppBasicExampleGui and expand it.

  2. Open the file BasicExample.cpp.

  3. Set a breakpoint that gets hit when you click in the running application. The click event is handled in a method within a helper class. To quickly get there:

    1. Select CommonRigidBodyBase that the struct BasicExample is derived from. It's around line 30.

    2. Right-click and choose Go to Definition. Now you're in the header CommonRigidBodyBase.h.

    3. In the browser view above your source, you should see that you're in the CommonRigidBodyBase. To the right, you can select members to examine. Open the drop-down and select mouseButtonCallback to go to the definition of that function in the header.

  4. Place a breakpoint on the first line within this function. It gets hit when you click a mouse button within the window of the application, when run under the Visual Studio debugger.

  5. To launch the application, select the launch drop-down in the toolbar. It's the one with the green play icon that says 'Select Startup Item'. In the drop-down, select AppBasicExampleGui.exe. The executable name now displays on the launch button:

  6. Choose the launch button to build the application and necessary dependencies, then launch it with the Visual Studio debugger attached. After a few moments, the running application appears:

  7. Move your mouse into the application window, then click a button to trigger the breakpoint. The breakpoint brings Visual Studio back to the foreground, and the editor shows the line where execution is paused. You can inspect the application variables, objects, threads, and memory, or step through your code interactively. Choose Continue to let the application resume, and then exit it normally. Or, halt execution within Visual Studio by using the stop button.

Add a Linux configuration and connect to the remote machine

  1. Add a Linux configuration. Right-click the CMakeSettings.json file in the Solution Explorer view and select Add Configuration. You see the same Add Configuration to CMakeSettings dialog as before. Select Linux-Debug this time, then save the CMakeSettings.json file (ctrl + s).

  2. Visual Studio 2019 version 16.6 or later Scroll down to the bottom of the CMake Settings Editor and select Show advanced settings. Select Unix Makefiles as the CMake generator, then save the CMakeSettings.json file (ctrl + s).

  3. Select Linux-Debug in the configuration drop-down.

    If it's the first time you're connecting to a Linux system, the Connect to Remote System dialog appears.

    If you've already added a remote connection, you can open this window by navigating to Tools > Options > Cross Platform > Connection Manager.

  4. Provide the connection information to your Linux machine and choose Connect. Visual Studio adds that machine as to CMakeSettings.json as your default connection for Linux-Debug. It also pulls down the headers from your remote machine, so you get IntelliSense specific to that remote connection. Next, Visual Studio sends your files to the remote machine and generates the CMake cache on the remote system. These steps may take some time, depending on the speed of your network and power of your remote machine. You'll know it's complete when the message 'Target info extraction done' appears in the CMake output window.

Set a breakpoint, build, and run on Linux

Because it's a desktop application, you need to provide some additional configuration information to the debug configuration.

  1. In the CMake Targets view, right-click AppBasicExampleGui and choose Debug and Launch Settings to open the launch.vs.json file that's in the hidden .vs subfolder. This file is local to your development environment. You can move it into the root of your project if you wish to check it in and save it with your team. In this file, a configuration has been added for AppBasicExampleGui. These default settings work in most cases, but not here. Because it's a desktop application, you need to provide some additional information to launch the program so you can see it on your Linux machine.

  2. To find the value of the environment variable DISPLAY on your Linux machine, run this command:

    In the configuration for AppBasicExampleGui, there's a parameter array, 'pipeArgs'. It contains a line: '${debuggerCommand}'. It's the command that launches gdb on the remote machine. Visual Studio must export the display into this context before that command runs. For example, if the value of your display is :1, modify that line as follows:

  3. Launch and debug your application. Open the Select Startup Item drop-down in the toolbar and choose AppBasicExampleGui. Next, either choose the green play icon in the toolbar, or press F5. The application and its dependencies are built on the remote Linux machine, then launched with the Visual Studio debugger attached. On your remote Linux machine, you should see an application window appear.

  4. Move your mouse into the application window, and click a button. The breakpoint is hit. Program execution pauses, Visual Studio comes back to the foreground, and you see your breakpoint. You should also see a Linux Console Window appear in Visual Studio. The window provides output from the remote Linux machine, and it can also accept input for stdin. Like any Visual Studio window, you can dock it where you prefer to see it. Its position is persisted in future sessions.

  5. You can inspect the application variables, objects, threads, memory, and step through your code interactively using Visual Studio. But this time, you're doing it all on a remote Linux machine instead of your local Windows environment. You can choose Continue to let the application resume and exit normally, or you can choose the stop button, just as with local execution.

  6. Look at the Call Stack window and view the Calls to x11OpenGLWindow since Visual Studio launched the application on Linux.

What you learned

In this tutorial, you cloned a code base directly from GitHub. You built, ran, and debugged it on Windows without modifications. Then you used the same code base, with minor configuration changes, to build, run, and debug on a remote Linux machine.

Next steps

Learn more about configuring and debugging CMake projects in Visual Studio:

CMake Projects in Visual Studio
Configure a Linux CMake project
Connect to your remote Linux computer
Customize CMake build settings
Configure CMake debugging sessions
Deploy, run, and debug your Linux project
CMake predefined configuration reference

-->

Native CMake support is available in Visual Studio 2017 and later. To see the documentation for these versions, set the Visual Studio Version selector control for this article to Visual Studio 2017 or Visual Studio 2019. It's found at the top of the table of contents on this page.

All executable CMake targets are shown in the Startup Item dropdown in the toolbar. Select one to start a debugging session and launch the debugger.

You can also start a debug session from Solution Explorer. First, switch to CMake Targets View in the Solution Explorer window.

Then, right-click on an executable and select Debug. This command automatically starts debugging the selected target based on your active configuration.

Customize debugger settings

You can customize the debugger settings for any executable CMake target in your project. They're found in a configuration file called launch.vs.json, located in a .vs folder in your project root. A launch configuration file is useful in most debugging scenarios, because you can configure and save your debugging setup details. There are three entry points to this file:

  • Debug Menu: Select Debug > Debug and Launch Settings for ${activeDebugTarget} from the main menu to customize the debug configuration specific to your active debug target. If you don't have a debug target selected, this option is grayed out.
  • Targets View: Navigate to Targets View in Solution Explorer. Then, right-click on a debug target and select Add Debug Configuration to customize the debug configuration specific to the selected target.
  • Root CMakeLists.txt: Right-click on a root CMakeLists.txt and select Add Debug Configuration to open the Select a Debugger dialog box. The dialog allows you to add any type of debug configuration, but you must manually specify the CMake target to invoke via the projectTarget property.

You can edit the launch.vs.json file to create debug configurations for any number of CMake targets. When you save the file, Visual Studio creates an entry for each new configuration in the Startup Item dropdown.

Reference keys in CMakeSettings.json

To reference any key in a CMakeSettings.json file, prepend cmake. to it in launch.vs.json. The following example shows a simple launch.vs.json file that pulls in the value of the remoteCopySources key in the CMakeSettings.json file for the currently selected configuration:

Environment variables defined in CMakeSettings.json can also be used in launch.vs.json using the syntax ${env.VARIABLE_NAME}. In Visual Studio 2019 version 16.4 and later, debug targets are automatically launched using the environment you specify in CMakeSettings.json. You can unset an environment variable by setting it to null.

Launch.vs.json reference

There are many launch.vs.json properties to support all your debugging scenarios. The following properties are common to all debug configurations, both remote and local:

  • projectTarget: Specifies the CMake target to invoke when building the project. Visual Studio autopopulates this property if you enter launch.vs.json from the Debug Menu or Targets View. This value must match the name of an existing debug target listed in the Startup Item dropdown.

  • env: Additional environment variables to add using the syntax:

  • args: Command-line arguments passed to the program to debug.

Launch.vs.json reference for remote projects and WSL

In Visual Studio 2019 version 16.6, we added a new debug configuration of type: cppgdb to simplify debugging on remote systems and WSL. Old debug configurations of type: cppdbg are still supported.

Configuration type cppgdb

  • name: A friendly name to identify the configuration in the Startup Item dropdown.
  • project: Specifies the relative path to the project file. Normally, you don't need to change this path when debugging a CMake project.
  • projectTarget: Specifies the CMake target to invoke when building the project. Visual Studio autopopulates this property if you enter launch.vs.json from the Debug Menu or Targets View. This target value must match the name of an existing debug target listed in the Startup Item dropdown.
  • debuggerConfiguration: Indicates which set of debugging default values to use. In Visual Studio 2019 version 16.6, the only valid option is gdb. Visual Studio 2019 version 16.7 or later also supports gdbserver.
  • args: Command-line arguments passed on startup to the program being debugged.
  • env: Additional environment variables passed to the program being debugged. For example, {'DISPLAY': '0.0'}.
  • processID: Linux process ID to attach to. Only used when attaching to a remote process. For more information, see Troubleshoot attaching to processes using GDB.

Additional options for the gdb configuration

  • program: Defaults to '${debugInfo.fullTargetPath}'. The Unix path to the application to debug. Only required if different than the target executable in the build or deploy location.
  • remoteMachineName: Defaults to '${debugInfo.remoteMachineName}'. Name of the remote system that hosts the program to debug. Only required if different than the build system. Must have an existing entry in the Connection Manager. Press Ctrl+Space to view a list of all existing remote connections.
  • cwd: Defaults to '${debugInfo.defaultWorkingDirectory}'. The Unix path to the directory on the remote system where program is run. The directory must exist.
  • gdbpath: Defaults to /usr/bin/gdb. Full Unix path to the gdb used to debug. Only required if using a custom version of gdb.
  • preDebugCommand: A Linux command to run immediately before invoking gdb. gdb doesn't start until the command completes. You can use the option to run a script before the execution of gdb.

Additional options allowed with the gdbserver configuration (16.7 or later)

  • program: Defaults to '${debugInfo.fullTargetPath}'. The Unix path to the application to debug. Only required if different than the target executable in the build or deploy location.

    Tip

    Deploy is not yet supported for local cross-compilation scenarios. If you are cross-compiling on Windows (for example, using a cross-compiler on Windows to build a Linux ARM executable) then you'll need to manually copy the binary to the location specified by program on the remote ARM machine before debugging.

  • remoteMachineName: Defaults to '${debugInfo.remoteMachineName}'. Name of the remote system that hosts the program to debug. Only required if different than the build system. Must have an existing entry in the Connection Manager. Press Ctrl+Space to view a list of all existing remote connections.

  • cwd: Defaults to '${debugInfo.defaultWorkingDirectory}'. Full Unix path to the directory on the remote system where program is run. The directory must exist.

  • gdbPath: Defaults to ${debugInfo.vsInstalledGdb}. Full Windows path to the gdb used to debug. Defaults to the gdb installed with the Linux development with C/C++ workload.

  • gdbserverPath: Defaults to usr/bin/gdbserver. Full Unix path to the gdbserver used to debug.

  • preDebugCommand: A Linux command to run immediately before starting gdbserver. gdbserver doesn't start until the command completes.

Cmake Visual Studio 2019 Example

Deployment options

Use the following options to separate your build machine (defined in CMakeSettings.json) from your remote debug machine.

  • remoteMachineName: Remote debug machine. Only required if different than the build machine. Must have an existing entry in the Connection Manager. Press Ctrl+Space to view a list of all existing remote connections.
  • disableDeploy: Defaults to false. Indicates whether build/debug separation is disabled. When false, this option allows build and debug to occur on two separate machines.
  • deployDirectory: Full Unix path to the directory on remoteMachineName that the executable gets copied to.
  • deploy: An array of advanced deployment settings. You only need to configure these settings when you want more granular control over the deployment process. By default, only the files necessary for the process to debug get deployed to the remote debug machine.
    • sourceMachine: The machine from which the file or directory is copied. Press Ctrl+Space to view a list of all the remote connections stored in the Connection Manager. When building natively on WSL, this option is ignored.
    • targetMachine: The machine to which the file or directory is copied. Press Ctrl+Space to view a list of all the remote connections stored in the Connection Manager.
    • sourcePath: The file or directory location on sourceMachine.
    • targetPath: The file or directory location on targetMachine.
    • deploymentType: A description of the deployment type. LocalRemote and RemoteRemote are supported. LocalRemote means copying from the local file system to the remote system specified by remoteMachineName in launch.vs.json. RemoteRemote means copying from the remote build system specified in CMakeSettings.json to the different remote system specified in launch.vs.json.
    • executable: Indicates whether the deployed file is an executable.

Execute custom gdb commands

Visual Studio supports executing custom gdb commands to interact with the underlying debugger directly. For more information, see Executing custom gdb lldb commands.

Enable logging

Enable MIEngine logging to see what commands get sent to gdb, what output gdb returns, and how long each command takes. Learn more

Configuration type cppdbg

The following options can be used when debugging on a remote system or WSL using the cppdbg configuration type. In Visual Studio 2019 version 16.6 or later, configuration type cppgdb is recommended.

  • name: A friendly name to identify the configuration in the Startup Item dropdown.

  • project: Specifies the relative path to the project file. Normally, you don't need to change this value when debugging a CMake project.

  • projectTarget: Specifies the CMake target to invoke when building the project. Visual Studio autopopulates this property if you enter launch.vs.json from the Debug Menu or Targets View. This value must match the name of an existing debug target listed in the Startup Item dropdown.

  • args: Command-line arguments passed on startup to the program being debugged.

  • processID: Linux process ID to attach to. Only used when attaching to a remote process. For more information, see Troubleshoot attaching to processes using GDB.

  • program: Defaults to '${debugInfo.fullTargetPath}'. The Unix path to the application to debug. Only required if different than the target executable in the build or deploy location.

  • remoteMachineName: Defaults to '${debugInfo.remoteMachineName}'. Name of the remote system that hosts the program to debug. Only required if different than the build system. Must have an existing entry in the Connection Manager. Press Ctrl+Space to view a list of all existing remote connections.

  • cwd: Defaults to '${debugInfo.defaultWorkingDirectory}'. Full Unix path to the directory on the remote system where program is run. The directory must exist.

  • environment: Additional environment variables passed to the program being debugged. For example,

  • pipeArgs: An array of command-line arguments passed to the pipe program to configure the connection. The pipe program is used to relay standard input/output between Visual Studio and gdb. Most of this array doesn't need to be customized when debugging CMake projects. The exception is the ${debuggerCommand}, which launches gdb on the remote system. It can be modified to:

    • Export the value of the environment variable DISPLAY on your Linux system. In the following example, this value is :1.

    • Run a script before the execution of gdb. Ensure execute permissions are set on your script.

  • stopOnEntry: A boolean that specifies whether to break as soon as the process is launched. The default is false.

  • visualizerFile: A .natvis file to use when debugging this process. This option is incompatible with gdb pretty printing. Also set showDisplayString when you set this property.

  • showDisplayString: A boolean that enables the display string when a visualizerFile is specified. Setting this option to true can cause slower performance during debugging.

  • setupCommands: One or more gdb command(s) to execute, to set up the underlying debugger.

  • miDebuggerPath: The full path to gdb. When unspecified, Visual Studio searches PATH first for the debugger.

  • Finally, all of the deployment options defined for the cppgdb configuration type can be used by the cppdbg configuration type as well.

Debug using gdbserver

You can configure the cppdbg configuration to debug using gdbserver. You can find more details and a sample launch configuration in the Microsoft C++ Team Blog post Debugging Linux CMake Projects with gdbserver.

Cmake Visual Studio 2019 Not Found

See also

Visual Studio Code

CMake projects in Visual Studio
Configure a Linux CMake project
Connect to your remote Linux computer
Customize CMake build settings
Configure CMake debugging sessions
Deploy, run, and debug your Linux project
CMake predefined configuration reference