Easy set-up: Automate building and debugging a currently active C++ source file with VS Code on Linux
Tags: cpp, vscode, debugging, beginners
Published: 2019-12-06 23:32:05

## First build, then debug
In order to properly debug a C++ program, it needs to be built with debugging information first (-g flag with g++ compiler).

### Set-up the development environment
1. If you're on a Linux, so you should have **build-essential** installed. To install or upgrade though, here's the command: `$ sudo apt install build-essential` This will install the necessary C/C++ development environment (compilers, libraries, linkers, etc.). `$ g++ –version` or `$ g++ –v` will print the version of the compiler on your system.
2. **Get the VS Code** (snap version available—you'll get it in "Ubuntu Software") and **install "*C/C++*" extension *(ms-vscode.cpptools)* from Microsoft** inside of VS Code -> extensions. The extension provides you with C/C++ IntelliSense and debugging.
3. **Configure a build system for building a single file**. Assuming you've created a directory for your C/C++ project and opened it inside the VS Code (you can do it from bash using `code .` while in the project directory). This is easy to set up as long as you haven't played with configuring build tasks inside the VS Code in your project yet. If you did though, and the `tasks.json` file was created inside the `.vscode` directory of your project, you can leverage getting great suggestions for detected tasks for C++ programs by removing the `tasks.json` file and choosing from the menu bar `Terminal -> Configure Default Build Task...`. If there's no configuration file yet, the `Select environment` window pops up and you get the option `C++ (GDB/LLDB)` which you shall choose. Now you probably want to choose "g++ build active file" from the suggestion list (creates `tasks.json` in the result).
![g++ build active file](https://thepracticaldev.s3.amazonaws.com/i/lkozi3pqiwi670pvdh85.png)

4. **Configure the interactive debugger inside the VS Code.** You can't use the interactive debugger right away—it needs to set up its configuration file. If you created the "g++ build active file" and you don't have the `launch.json` configuration file yet inside the `.vscode` (you can try to delete it if you have one), then you should get the automatic suggestion for creating a "g++ build and debug active file". To get them, head to `Debug`, and now either: `Open Configuration`, `Add configuration...` or `Start debugging`—all options will let you configure the debugger settings if there's no configuration file yet. The `Select environment` window pops up and you get the option `C++ (GDB/LLDB)` which you shall choose. If you've messed up with the configuration inside the `launch.json`, you can delete the file from the `.vscode` directory and perform the steps above—for configuring the debugger from 0—to get the suggested configuration, which usually sets most of the things necessary. Once the set up is performed, the file named `launch.json` indeed is created inside the `.vscode` directory.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/ym1bzpf73l5r2vf7d5ft.png)

5. **Content of the debugger configuration file** `launch.json`—some of the arguments:
    - **"preLaunchTask"—the automatic building of source files just before debugging.** The `"preLaunchTask"` argument's value serves as a link to the build task (specified inside `tasks.json` file in project's `.vscode` directory) with the  `"label"` argument of the same value, e.g. `"preLaunchTask": "g++ build active file",` specified in `launch.json` links to `"label": "g++ build active file"` specified in `tasks.json`. "preLaunchTask" argument sets up the task of building the file first (compiling and linking), just before running the debugger. This is because the debugger needs to operate on files that are already built with the debugging information attached to them (`-g` option to `g++` compiling command adds this information). 
    - **"program"—compiled file's naming convention.** `"program": "${fileDirname}/${fileBasenameNoExtension}",`. With this setup the debugger will look for the compiled file which has the same name as the source file, just w/o the `.cpp` ending and debug it as long as it was compiled with the `-g` option, which provides debugging information for later use by the debugger. The value of the `"program"` should correspond to how the file which is now taken as a subject for debugging was built by the mini build system that we established in `.vscode/tasks.json`: 
    ```
    "args": [
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
    ```

6. **Possible problem with permissions on Linux while debugging C++ with GDB for the first time**. When you run the debugger and then try to `Step Over` or `Step Into` while running it, the GDB debugger needs to store or access some temporary files inside the `/build` directory in the root of your system. The problem here is that the `/build` directory inside your system root `/` directory may not exist yet. So once it tries to put the files inside such a path it needs to create a `/build` directory inside a `/` root first, which it doesn't have permissions to do so. What you can do in such a situation would be that you create a `/build` directory yourself with sudo/su (`[]:/$ sudo mkdir build`) and then make the `/build/` directory that you've just created permissible. In this step you can either try `[]:/$ sudo chown -R $USER:$GROUP /build` or if it doesn't work, all permissions may be necessary to be given `[]:/$ sudo chmod 777 /build`. It's difficult for me to reproduce the error as I deleted the `/build` folder on my machine and debugger doesn't look for any file in a path involving `/build` directory anymore. I'm bringing this issue up though since it existed for me once and creating the directory manually and giving it all permissions worked for me. The important thing here is not to get an idea of giving all permissions to the root directory as you'll break your entire filesystem's permissions and make it vulnerable, you'll also lose access to sudo.


### Summary
What we've just done is that we automated the building and debugging operations inside of VS Code IDE. Every time we press the Debug button or F5, we get the currently active file built and performed debugging on instantaneously.