Skip to content

VSCode setup

This is a minimal setup for the popular VSCode IDE for the muon collider software.

WARNING: A lot of this information is still work-in-progress, but it's enough to get you started.

VSCode extensions

You will need to install the following extension to work with containers:

  • Remote Development (mandatory)

In additiona, a few more extensions are very helpful when developing code:

  • ROOT Viewer (more info)
  • C/C++ Extension Pack (includes C/C++, CMake, ...)
  • Python
  • VSCode will also suggest new extension based on the specific files you open

Since we'll be using VSCode to develop inside a container (local or remote), it is important that once you open your project inside the container you install the extensions above (apart from "Remote Development") inside the container. To do this, just go into the Extensions tab on the sidebar and locate those extensions; you will find a Install on Dev Container button to do the job.

Configuration

The following example fits the use-case of running VSCode locally and developing using a local docker container. It allows IntelliSense auto-completion, compiling, running and interactive debugging of your development in VSCode. Change the various paths and options as appropriate for your system.

If the docker engine (container) and the code are on a remote machine is also possible to use a local VSCode client; see the documentation here on how to set it up via SSH.

In the following we give some example of configuration files. Please read them and customize them according to you system (e.g. many paths are just examples, etc..).

Workspace (your-project-name.code-workspace)

This file is optional, but can be handy to keep some settings. For instance at some point an example could be:

{
        "folders": [
                {
                        "path": "."
                }
        ],
        "settings": {
                "cmake.configureSettings": {
                        "BOOST_INCLUDEDIR":"/usr/include/boost173",
                        "BOOST_LIBRARYDIR":"/usr/lib64/boost173",
                        "CMAKE_CXX_STANDARD":"17"
                },
                "files.associations": {
                        "ostream": "cpp",
                        "ClusterAnalysis.C": "cpp"
                }
        }
}

in which we were adding some custom CMake options, definint a couple of useful CMake variables and manually associating some files to a given language. All of this can also be done in different ways.

Dev Container (.devcontainer.json)

This is the file that the Remote Containers extension latches onto. This will allow the extension to run the Docker container as well as launch VSCode inside of it for development.

Here is an example of how one may look.

{
    "image": "infnpd/mucoll-ilc-framework:1.6-centos8",

    "containerEnv": { "DISPLAY":"${DISPLAY}",
                      "USER":"${localEnv:USER}",
                      "HOME":"/home/${localEnv:USER}",
                      "MUC_CONTAINER_VER":"1.6-centos8"                   
                    },
    "mounts": [
        "source=${localEnv:HOME}/.Xauthority,target=/home/${localEnv:USER}/.Xauthority,type=bind,consistency=cached",
    ],
    "workspaceMount": "source=path/to/working/directory,target=/home/${localEnv:USER},type=bind,consistency=delegated",
    "workspaceFolder": "/home/${localEnv:USER}/LBLMuC-SiDigiDev",

    "runArgs": ["--net=host"]
}

where path/to/working/directory is replaced with your working directory.

For more information and customization, see its documentation and reference.

CPP Properties (.vscode/c_cpp_properties.json)

This file instructs VSCode on how to handle C/C++ code and make use of advanced features as auto-completion and more.

Make sure to include libraries that you want to use in this file so VSCode IntelliSense functions properly. Most notably, ROOT libraries are typically stored in: /usr/include/root/

A minimal example follows:

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "/usr/include/root/"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu17",
            "cppStandard": "gnu++14",
            "intelliSenseMode": "linux-gcc-x64",
            "configurationProvider": "ms-vscode.cmake-tools",
            "compileCommands": "${workspaceFolder}/build/compile_commands.json"
        }
    ],
    "version": 4
}

For more information, see its documentation.

Settings (.vscode/settings.json)

This file can contain additional settings. for instance, to disable CMake from running as soon as you open the folder/files, you can have:

{
    "cmake.configureOnOpen": false
}

Tasks and Launch configuration (.vscode/tasks.json, .vscode/launch.json)

These configuration files define how VSCode will execute the program(s) inside your project. A simple example should be sufficient to be able to create yours and additional documentation is also referenced inside the example files below.

The .vscode/tasks.json file defines some common tasks/actions, for instance:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Local Setup",
            "type": "shell",
            "command": "source ${workspaceFolder}/setup.sh; printenv > ${workspaceFolder}/.env"
        },
        {
            "label": "Prepare Debug Folder",
            "type": "shell",
            "command": "source ${workspaceFolder}/setup.sh; printenv > ${workspaceFolder}/.env; cd ${workspaceFolder}/run/000-dbg/; rm -f *.root; rm -f Output_*.slcio"
        }
    ]
}

The code above defines two actions, one that just setups the environment using the setup.sh script in your project folder, and one that simply prepares a clean folder for debugging. For both, the environment is saved into a file, to be loaded by the launch configuration specified in the next file below.

The .vscode/launch.json instructs VSCode on how to run the actual program:

    // 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 Reco",
            "type": "cppdbg",
            "request": "launch",
            "program": "/opt/ilcsoft/muonc/Marlin/v01-17-01/bin/Marlin",
            "args": [ "${workspaceFolder}/config/reco_steer.xml" ],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}/run/000-dbg/",
            "envFile": "${workspaceFolder}/.env",
            "externalConsole": false,
            "MIMode": "gdb",
            "preLaunchTask": "Prepare Debug Folder",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

In the example above we defined a new configuration names "(gdb) Launch Reco". This configuration uses the defined tasks to prepare a debug folder and launch a test reconstruction job using a pre-defined steering file. Note that you want to create the folder used to run these tests (cwd in the configuration above) beforehand (VSCode will complain if it does not exist). Also note that we load the environment that was saved by the preLaunchTask task. You can create several different configurations, depending on what you're developing.

Post-Configuration setup

Whenever setting up a project for development inside a container, remember to create a build folder yourself before launching VSCode. This is mostly important in case you're using docker containers, otherwise the folder will be created with root as user.

Running VSCode

The easiest is that you start VSCode from the folder containing the .devcontainer.json file. You can open any file, e.g. opening the workspace file by doing code your-project.code-workspace. Note that at this stage it might invoke cmake and fail, but that's ok. VSCode will also ask you to re-open the file/folder inside the container with a pop-up at the bottom-right corner. Do so to have VSCode loading the container and running/connecting to a VSCode server instance inside it.

The first time VSCode might ask you to select the "kit" to use for compiling. You can also select that yourself at any point from the bottom bar (if you hover the mouse over it, it will say "Click to change active kit"). Select the one it finds automatically inside the container (GCC 8.3.1 x86_64-redhat-linux at the time of this writing).

You can also select and change the target (default: all), as well as the type of build (the latter will say "click to select the build variant" when your mouse hovers over it). The latter can be useful to alternate Debug and Release builds depending if you want to run a debugging session or just go full-speed with optimized code.

At this point you should be all set. To run cmake, just open the command palette of VSCode (e.g. Ctrl+Shift+P) and call CMake: configure to run cmake. Call CMake: Build to compile everything.

At this point you can use intelliSense (auto-completion, suggestions, etc..) when writing the code, compile using cmake, and run or debug your code as define in your tasks.

If you've setup correctly the configurations in the .vscode/tasks.json file as explained above, you can now test for instance that a job runs invoking that configuration. This can be done simply bring up the "Run and Debug" right side-panel or click Ctrl+Shift+D. You will need to select the configuration you created in launch.json. For more information on how to debug in VSCode, see also its official documentation.