Building your C++ application with Visual Studio Code

Over the last few months, we have heard a lot of requests with respect to adding capability to Visual Studio Code to allow developers to build their C/C++ application. The task extensibility in Visual Studio Code exists to automate tasks like building, packaging, testing and deploying. This post is going to demonstrate how using task extensibility in Visual Studio Code you can call compilers, build systems and other external tasks through the help of the following sections:

Installing C/C++ build tools

In order to build your C++ code you need to make sure you have C/C++ build tools (compilers, linkers and build systems) installed on your box. If you can already build outside Visual Studio Code you already have these tools setup, so you can move on to the next section.

To obtain your set of C/C++ compilers on Windows you can grab  the Visual C++ build tools SKU. By default these tools are installed at ‘C:\Program Files (x86)\Microsoft Visual C++ Build Tools’. You only need to do this if you don’t have Visual studio installed. If you already have Visual Studio installed, you have everything you need already.

If you are on a Linux platform which supports apt-get you can run the following commands to make sure you grab the right set of tools for building your C/C++ code.

sudo apt-get install g++
sudo apt-get install clang

On OS X, the easiest way to install the C++ build tools would be to install Xcode command line tools. You can follow this article on the apple developer forum. I would recommend this instead of installing clang directly as Apple adds special goodies to their version of the clang toolset. Once installed you can run these commands in a terminal window to determine where the compiler and build tools you need were installed.

xcodebuild -find make
xcodebuild -find gcc
xcodebuild -find g++
xcodebuild -find clang
xcodebuild -find clang++

Creating a simple Visual Studio Code task for building C/C++ code

To follow this specific section you can go ahead and download this helloworld C++ source folder. If you run into any issues you can always cheat and download the same C++ source folder with a task pre-configured.

If you are just picking up C++ and want to understand different components involved in performing a simple build you can review this guide.

In Visual Studio Code tasks are defined for a workspace and Visual Studio Code comes pre-installed with a list of common task runners. In the command palette (Ctrl+Shift+P (Win, Linux), ⇧⌘P (Mac)) you can type tasks and look at all the various task related commands.

commands

On executing the ‘Configure Task Runner’ option from the command palette you will see a list of pre-installed tasks as shown below, in the future we will grow the list of task runners for popular build systems but for now go ahead and pick up the others template from this list.

preinstalledtasks

This will create a tasks.json file in your .vscode folder with the following content:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "echo",
    "isShellCommand": true,
    "args": ["Hello World"],
    "showOutput": "always"
}
Setting it up for Windows

The easiest way to setup Visual Studio Code on Windows for C/C++ building is to create a batch file called ‘build.bat’ with the following commands:

@echo off
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64     
set compilerflags=/Od /Zi /EHsc
set linkerflags=/OUT:hello.exe
cl.exe %compilerflags% helloworld.cpp /link %linkerflags%

Please note that the location of vcvarsall.bat file which sets up the right environment for building could be different on your machine. Also if you are using the Visual C++ build SKU, you will need to call the following command instead:

call “C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat” x64

Once the build script is ready you can then modify your tasks.json to directly call your batch file on Windows by making the following changes to the automatically generated tasks.json file.

{  
   // See https://go.microsoft.com/fwlink/?LinkId=733558
   // for the documentation about the tasks.json format
   "version": "0.1.0",
   "windows": {
      "command": "build.bat",
      "isShellCommand": true,
      "showOutput": "always"
   }

Initiate a build by bringing up the command palette again and executing the ‘Run Build Task’ command.

build

This should initiate the build for our C++ application and you should be able to monitor the build progress in the output window.

output

Now even though this is a Windows specific example you should be able to re-use the same series of steps to call a build script on other platforms as well.

Calling Clang and GCC from Visual Studio Code task for building C/C++ code

Alright let us now see how we can achieve building our C/C++ application without calling an external batch file using some popular toolsets like GCC and Clang directly without a build system in play.

To follow this specific section you can go ahead and download this helloworld C++ source folder. If you run into any issues you can always cheat and download the same C++ source folder with a task pre-configured.

Tasks.json allow you to specify qualifiers like the one below for ‘OS X’. These qualifiers similar will allow you create specific build configurations for your different build targets or as shown in this case for different platforms.

  "OS X": {
        "command": "clang++",
        "args": [
            "-Wall",
            "helloWorld.cpp",
            "-v"
          ],
        "isShellCommand": true,
        "showOutput": "always",
        "problemMatcher": {
            "owner": "cpp",
            "fileLocation": [
                "relative",
                "${workspaceRoot}"
            ],
            "pattern": {
                "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
                "file": 1,
                "line": 2,
                "column": 3,
                "severity": 4,
                "message": 5
            }
  }

Another thing to highlight in this snippet is the ‘problemMatcher’ section. Visual Studio Code ships with some of the most common problem matchers out of the box but many compilers and other tools define their own style of errors and warnings. Need not worry you can create your own custom problem matcher as well with Visual Studio Code. This site which helps test out regex online might also come in handy.

The pattern matcher here will work well for Clang and GCC toolsets so just go ahead and use them. The figure below shows them in effect when you initiate the show problems command in Visual Studio Code (Cntrl+Shift+M (Win, Linux), ⇧⌘M (Mac)).

error

Calling Makefiles using Visual Studio Code task extensibility

Similar to the manner how you configure tasks.json to call the compiler, you can do the same for makefiles. Take a look at the sample tasks.json below, the one new concept in this tasks.json file is the nesting of tasks. Both ‘hello’ and ‘clean’ are tasks in the makefile where as ‘compile w/o makefile’ is a separate task but this example should show you how you can setup tasks.json in cases where there are
multiple build systems at play. You can find the entire sample here.

Note this is an OSX, Linux specific example but to obtain the same behavior on Windows you can replace ‘bash’ with ‘cmd’ and ‘args’ with ‘/C’.

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
   "version": "0.1.0",
    "osx": {
        "command": "bash",
        "args": ["-c"],
        "isShellCommand": true,
        "showOutput": "always",
        "suppressTaskName": true,
        "options": {
            "cwd": "${workspaceRoot}"
        },
        "tasks": [
            {
                "taskName": "hello",
                "args": [
                    "make hello"
                ],
                "isBuildCommand": true
            },
            {
                "taskName": "clean",
                "args": [
                    "make clean"
                ]
            },
            {
                "taskName": "compile w/o makefile",
                "args": [
                    "clang++ -Wall -g helloworld.cpp -o hello"
                ],
                "echoCommand": true
            }
        ]
    }
}

Two more things to mention here is that whichever task you associate the ‘isBuildCommand’ with becomes your default build task in Visual Studio Code. In this case that would be the ‘hello’ task. If you would like to run the other tasks bring up the command palette and choose ‘Run Task’ option.

task1

task2

Then choose the individual task to run e.g. ‘clean’ task. Alternatively, you can also wire the build task as a different key binding. For doing so bring up File -> Preferences -> Keyboard shortcuts and add the following key binding to your task. Bindings currently only exist for build and test tasks but an upcoming fix in the October release will allow bindings for individual tasks as well.

[
  {
        "key": "f7",
       "command": "workbench.action.tasks.build"
    }
]

Calling MSBuild using Visual Studio Code task extensibility

MSBuild is already a pre-installed task that Visual Studio Code comes with. Bring up the command palette and choose MSBuild, this will create the following task.json it should be easy then to add your MSBuild solution, project name to the ‘args’ section and get going.

{
 // See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
  "version": "0.1.0",
  "command": "msbuild",
  "args": [
        // Ask msbuild to generate full paths for file names.
        "/property:GenerateFullPaths=true"
    ],
    "taskSelector": "/t:",
    "showOutput": "silent",
    "tasks": [
    {
            "taskName": "build",

            // Show the output window only if unrecognized errors occur.
            "showOutput": "silent",
           
            // Use the standard MS compiler pattern to detect errors, warnings and infos
           "problemMatcher": "$msCompile"
        }
    ]
}

Calling CMake using Visual Studio Code extensibility

There are currently two Visual Studio Code extensions in the Visual Studio Code marketplace. The first extension provides the language service support for CMake the latter will allow for building your CMake targets. For a good CMake experience in Visual Studio Code install both extensions.

extensions

Once configured you should be able to build specific CMake targets and perform other CMake actions as illustrated in the figure below.

cmake

Wrap Up

This post provides some guidance with examples on how to use Visual Studio Code task extensibility to build your C/C++ application. If you would like us to provide more guidance on this or any other aspect for Visual Studio Code by all means do reach out to us by continuing to file issues at our Github page and keep trying out this experience and if you would like to shape the future of this extension please join our Cross-Platform C++ Insiders group, where you can speak with us directly and help make this product the best for your needs.