45

In VS Code I have to run the build task first and then start debugging, while in CLion I just click debug, then it builds automatically if necessary and starts debugging. Is there a way to automate this in VS Code as well?

NoNameProvided
  • 8,608
  • 9
  • 40
  • 68
Svilen
  • 635
  • 1
  • 6
  • 6

2 Answers2

59

Adding a build task to the Launch.Json


What you are looking for is probably how to link a build task to your debug config. I'll try to illustrate the process below.

debug configs

To access your build configs, go to the Debug bar on the side (1), and press the gear icon to access your launch.json config file (2). You will need to add a pre-launch task under your configurations in that launch.json file, and link it to your build task (3).

Defining the Build Task in Tasks.Json


tasks.json file

Then, you will need to set up your build task, by running it with ctrl-shift-b.

If it already exists (as implied in your post), you can find it in your .vs-code folder in the tasks.json file. If you open that task.json file, you will find the build task in the list. All you need to do now is to take the 'label' of that task and place it in your launch.json in that pre-launch config.

Good luck!

Appendix


Appendix added with examples for clean build and running configs in parallel following a shared pre-launch build.

Q: What to do if the build task fails, but the launch process starts with the old binary?

A: Potential solution given by @JoKing: add a new task that deletes the binary and execute this task before each build by requiring it in the build task with the "dependsOn" option. An example is given below for how it might look in the tasks.json file, source

   "tasks": [
    {
      "taskName": "build",
      "command": "tsc",
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "dependsOn": [
        "build client",
        "build server"
      ]
    },
    {
      "taskName": "build client",
      "command": "tsc",
      "args": [
        "-w",
        "-p",
        "${workspaceRoot}/src/typescript/client"
      ]
    },
    {
      "taskName": "build server",
      "command": "tsc",
      "args": [
        "-w",
        "-p",
        "${workspaceRoot}/src/typescript/server"
      ]
    }
  ]

Q: I have multiple configurations, but want to run build task to run once before all the configurations, is it possible?

A: I have not personally set this up before, but compound launch configurations may be what you are looking for. The example from that page has two configurations, 'Server' and 'Client', which can be launched in parallel while following the prelaunchTask ('defaultBuildTask').

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Server",
      "program": "${workspaceFolder}/server.js"
    },
    {
      "type": "node",
      "request": "launch",
      "name": "Client",
      "program": "${workspaceFolder}/client.js"
    }
  ],
  "compounds": [
    {
      "name": "Server/Client",
      "configurations": ["Server", "Client"],
      "preLaunchTask": "${defaultBuildTask}"
    }
  ]
}
upe
  • 1,862
  • 1
  • 19
  • 33
Enthus3d
  • 1,727
  • 12
  • 26
  • nice answer! Can you maybe add how to stop the debug process if the build failed? – JoKing Jan 28 '21 at 14:57
  • @JoKing Thabks Jo! I have personally not encountered that particular issue, but if you are getting stuck in the build process on failure, you may need to clear the cache. This might help: https://stackoverflow.com/questions/50454523/how-can-i-fix-build-failed-do-you-want-to-continue-in-vscode – Enthus3d Jan 28 '21 at 15:25
  • 1
    It's a different problem: If the build fails and the launch process starts automatically it will launch with the old binary. It might happen that the console output vanishes so fast that you don't even realize you're launching the old binary. I solved this by adding a new task that deletes the binary and then execute this task before every build by requiring it in the build task with the "dependsOn" option. – JoKing Feb 05 '21 at 08:17
  • 1
    i have multiple configurations, but want to run build task to run once before all the configurations, is it possible? – Sunil Garg Feb 09 '21 at 07:31
  • 1
    @SunilGarg hi Sunil, I believe what you are looking for is the [compound launch configurations](https://code.visualstudio.com/docs/editor/debugging#_compound-launch-configurations). The compound launch configs will allow you to run many configs in parallel. There is also the ability to set the prelaunchtask to allow you to launch a build before you run all your configs: ```"preLaunchTask": "${defaultBuildTask}"```. I can add this to my answer sometime this weekend, but will keep it as a comment until then. Hope this helps! – Enthus3d Feb 09 '21 at 17:22
  • @JoKing that is an excellent idea, I had no idea this kind of thing could happen. I'll see if I can add a footnote this weekend referencing your solution so that others can benefit. Thanks for sharing! – Enthus3d Feb 09 '21 at 17:24
  • sorry for the late addition, had some things to do during the weekend, but have updated the appendix now. Hopefully the examples come in use :) – Enthus3d Feb 17 '21 at 17:35
9

It took me some time to understand the accepted answer. It was not clear to me from that explanation the exact way that would make my program build and debug with 1 click. Also I'm using Mingw-w64 in Windows. Following the instructions on this link and based on the accepted answer I created the following files:

launch.json:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "C:\\msys64\\mingw64\\bin\\gdb.exe",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build"
        }
    ]
}

tasks.json:

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cppbuild",
            "label": "build",
            "command": "C:\\msys64\\mingw64\\bin\\g++.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": "build",
            "detail": "compiler: C:\\msys64\\mingw64\\bin\\g++.exe"
        }
    ]
}

The key aspect is to rename the default "label": "C/C++: g++.exe build active file" in tasks.json, for something else, for instance I used the word "build" and later reference that same word (not the path or link to tasks.json) in "preLaunchTask": "build" inside launch.json.

Notice the renaming is not strictly necessary. You can also say "preLaunchTask": "C/C++: g++.exe build active file" inside launch.json and it will also work.

upe
  • 1,862
  • 1
  • 19
  • 33
VMMF
  • 906
  • 1
  • 17
  • 28