A Simple VSCode Setup for C++ Developers

Tru Hoang
The Startup
Published in
8 min readMay 27, 2020

As a software developer, I’ve tried different integrated development environment (IDE) and text editors for code development (vim, Emacs, Sublime Text, etc). Out of the ones I’ve tried, Microsoft Visual Studio Code (VSCode) stands out among the rest as a flexible and lightweight editor. What’s great about VSCode is its extensibility with various plug-ins from the Extension Marketplace. Did I also mention that it’s free AND is updated every month!?

As a developer whose primary coding language is C++ I find VSCode provides all the tools, e.g. gdb debugger, and features, e.g. IntelliSense, that ease the development process. However, when I first started using the editor, online search turns up articles that focuses more on what extensions to use, which for a beginner, blindly installing them can quickly bloat up the editor and makes it difficult to configure the extensions to be useful.

In this article, I’m going to focus on 4 topics to help the uninitiated set up their VSCode environment for coding in C++:

  1. Set up VSCode workspace
  2. Set up debugger settings
  3. Set up build instructions
  4. Essential extensions for code development

Set Up VSCode Workspace

VSCode uses the workspace concept to apply custom settings and allow the user to specify commands that only apply to the codes in that workspace. The codes DO NOT have to be physically in the same folder!

A workspace and its settings are represented by a .code-workspace file in the directory. When you add this folder into the workspace (right-click on the Explorer window and select Add folder to Workspace), VSCode will search for the file and establish the workspace.

VSCode workspace settings

In the above screenshot, I placed my .code-workspace in the Coding_Workspace folder which contains several git repos. These subfolders are also added into the workspace using Add folder to Workspace to create a multi-root workspace. This is extremely useful when you are working on multiple repos and want to specify commands for specific repos. This will be more apparent when I explain how to setup build instructions.

If you are starting from scratch, simply open a new VSCode window. Select Add workspace folder on the Welcome screen. Choose a folder you want to make as your workspace. Select File > Save Workspace As and the .code-workspace file will be automatically created with minimum settings filled out. When you add other folders into the workspace, this file will be automatically updated by VSCode with the name of the folder so it can be used to create specific instructions for files in that folder only.

Another thing VSCode will do when you first create a workspace is creating a .vscode folder. This folder is where local settings and instructions are stored.

.vscode folder is where settings and instructions are stored

Two files you should pay special attention to are tasks.json and launch.json. The first specifies build instructions. The second specifies settings for the debug environment.

Set Up Build Instructions

VSCode supports custom tasks that simplify your development process and reduce typing and memorization. These tasks can also be chained together to form more complex build or run tasks.

All of the custom tasks are stored in tasks.json in .vscode sub-folder. Each can be specified in a comma separated list surrounded by braces {} as shown in the figure below.

Single Task

Each tasks have properties for the user to define. Here we only focus on what I think are essential. For a comprehensive list, refer to the link in the footnote¹.

  1. label: This is a string to help you identify what this task will do. It is also use as the name in the drop down menu when choosing Tasks: Run Task in the Command Palette (Ctrl+Shift+P).
  2. type: The type of command that is being executed. Supports shell or process.
  3. command: The command that you want VSCode to execute.
  4. args: Array of comma separated arguments you want to pass to the command. For example,-DCMAKE_BUILD_TYPE=Debug to tell CMake to generate makefile with debug flags.
  5. group: The group you want VSCode to organize this task in. Supports build, test, and none.

group also supports making the task a default when using the keyboard shortcut Ctrl+Shift+B. To do this, instead of specifying one of the 3 options above, in braces {} specify the following properties:

  1. kind: build, test, none.
  2. isDefault: true, false.

If all of your tasks has the property isDefault set to true then the shortcut will open a drop-down menu for you to choose which to execute.

NOTE: There is another property presentation that allows you to manipulate the output of the tasks. By default, it is set to always start a new terminal and print to it (for more information refer to the footnote¹).

You can see in the figure above that I use {workspaceFolder:pcl} in args and cwd. Remember when I talked about the multi-root workspace? This allows me to execute the CMake command in the pcl folder itself and not having to worry about relative or absolute paths. VSCode automatically expands the expression; in my case, ~/Code_Workspace/pcl/.

In addition to workspaceFolder VSCode predefines other variables that can be used to generalize settings that require paths. Please see the footnote⁴ for more details.

Chaining Tasks

Another powerful feature of specifying your tasks in tasks.json is it allows you to chain the single tasks together. To do this simply create a new task with the following properties:

  1. label: Specify a unique name for the task
  2. dependsOn: Array of comma-separated labels of the single task
  3. dependsOrder: Specify the order in which the task will be executed. The current task will be executed last and each task must return before the next executes. Supports sequence.

This feature is useful for chaining build tasks together or build and run unit tests combo.

Set Up Debugger Settings

In my opinion this is a powerful feature that makes VSCode standout among other text editors. Similar to tasks, users can setup their debug environment in launch.json in a comma-separated list as seen in the screenshot below.

Example of launch.json

Each debug session supports many properties. The list below is not comprehensive and focuses on ones that I think are essential. For the full list, please refer to the footnotes² ³.

  1. name: Unique name that differentiate the debug tasks from one another.
  2. type: The type of debugger to use. If you installed the C/C++ extension then cppdbg is available. A few others shipped with the editor are node, php, go for other programming languages.
  3. request: launch a new process or attach to a running process. If attach is chosen, the debug window will show a drop-down menu of running process with IDs to choose from.
  4. program: path to the executable you want to debug.
  5. args: comma-separated list of arguments to pass to the executable.
  6. stopAtEntry: true or false whether the debugger will break at the entry of the code.
  7. cwd: the working directory to find dependencies. Setting to ${workspaceFolder} is the standard.
  8. externalConsole: true or false whether to launch the debug terminal in an external console.
  9. MIMode: This is specific to C/C++ extension and is required. Supports gdb or lldb.
  10. setupCommands: This is specific to C/C++ extension and is option. The setting in the figure above suffices.
  11. preLaunchTask: A comma-separated list of task names from tasks.json to run before launching the debugger. For example, building the code in debug mode before debugging.
  12. postDebugTask: A comma-separated list of task names from tasks.json to run after the debug session. Can be used to clean up temporary files.

You may notice from the screenshot that I’ve again use ${workspaceFolder:pcl} for cwd and program. This tells VSCode that I want the debugger, in this case gdb, to latch on to an executable test in the pcl folder in my workspace and make the that folder the root directory when running the debugger.

Note: If you find the list of properties to set daunting, no worries, VSCode will show available options when you press when editing the .json files!

Essential Extensions For Code Development

And finally, the following is a list of extensions I found useful and think are essential for C++ developers:

Note: If you are working with ROS and your primary OS is Linux. I recommend also downloading the ROS extension.

The list is not extensive and may not include other extensions that other developers may find helpful. I recommend sticking with those listed above for a few weeks before browsing through the marketplace (you can definitely get loss in that place!).

Each of these extension provide commands that can be accessed through the Command Palette. You can start typing what you want to achieve and VSCode will slowly narrow down the options. Not only that, the displayed commands are sorted by recently used.

Git pull from the Command Palette

For extensions dealing with code repositories like Git, they allow the user to choose the repository the selected command should apply to.

Which repository do I want to apply “git pull”?

Some other extensions, like C/C++, do not add executable commands but rather optional settings that can enhance the editor even more. For example, C/C++ syntax highlighting.

C/C++ extension settings

Summary

In this article, I have shown how to set up VSCode workspace and settings to aid in C++ development. This is what I’ve found working for me and have been helping me immensely in my coding journey and I hope it can do the same for you.

For ROS developers, I recommend reading the following articles on how to set up VSCode to integrate ROS workflow into your development and testing:

https://erdalpekel.de/?p=157

Happy coding!

--

--

Tru Hoang
The Startup

An enthusiast of all-things robotics and an avid reader of sci-fi novels. A big fan of Isaac Asimov’s Foundation series and Robot series.