Page 1 of 1

Setting up Visual Studio Code for development.

Posted: Thu Aug 12, 2021 12:35 am
by bloodline
Hi all,

Are there any Visual Studio Code experts out there? I want to try and use it for two things:

1. It would be nice to create a development environment where I can use GitHub for version management, my i686-elf-gcc binutils for compilations and then qemu to execute the resulting output (perhaps linking to VSC’s serial terminal?). This would speed development of my OS.

2. I would like to setup Visual Studio Code so I can develop applications for my OS, as I use the same gcc binutils set up to compiler them, I imagine this should just be an easier version of the above (doesn’t need to run qemu).

I’ve being trying to create such a thing, but I can’t get VSC to do anything other than just be a fancy text editor.

Re: Setting up Visual Studio Code for development.

Posted: Thu Aug 12, 2021 8:11 am
by nexos
VSCode is extremely powerful, I hardly use for it all it could do. Here is how I use it:
First, VSCode by default is a fancy text editor. You need to download some extensions for it. Here are the ones I use:
- C/C++. Use the official Microsoft one. Also, the error squiggles are very annoying, and don't search very hard for include files. I would disable them by pressing Ctrl+Shift+P, and then search for "C/C++ - Disable error squiggles"
- CMake and CMake tools. VSCode has robust CMake support with these, where you can turn VSCode into an IDE. I don't really use the integration, as I have my own build script which wraps over CMake. The syntax feature is helpful, however
- EditorConfig. EditorConfig is an extremely helpful tool where you can set global editor settings (like tab width, end of line type, and so on). It can work in Emacs, Vim, and many other editors as well! It isn't as powerful as Clang Format, but works for what I need. It is super simple. Check out the link.
- GNU assembler and Intel assembler. I use GAS (long story why), and VSCode has robust ASM support with these extensions
- VSCodeCounter - I use this to count SLoC in my project. It isn't extremely powerful, but works great for me

As for GitHub integration, if you have git installed on your host system, just run "git init" in your source directory, or go to the version control tab of VSCode, and select "Initialize Repository". VSCode will then manage git stuff. To integrate wit GitHub, I typically set it up on the command line, for example:

Code: Select all

git remote add origin https://github.com/YourUser/YourRepo.git
git config --global user.email YourEmail (on your GitHub account)
git config --global user.name YourGitHubUserName
git push -u origin YourBranchName
Enter your GitHub password when prompted. From then on, you should see a refresh icon down near the bottom left corner of VSCode. After commiting something, select that, and it will push and pull. IIRC, you may have to enter your password the first time you select that. Its been a while sense I set up a repo

For build support, I typically use the command line. Note that VSCode has its own pane which contains your shell in it. Select "Terminal" then "New Terminal" in the menu bar to run it.

That all I can share for now, I'm trying to learn debugger integration and how I can run by build script with a keystroke form within VSCode. It's possible!

- Edit - One question, if you are using a build system (i.e., make) then building your OS and your apps should be done in one operation. If not, then using Make (or even better, CMake) would greatly simplify build - run cycles. Today, I created a tasks.json file in my VSCode configuration, it should be located in a subfolder called .vscode. Its contents for me are:

Code: Select all

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build-i686-pc",
            "type": "shell",
            "command": "cd NexNix; ./scripts/buildrun.sh i686-pc",
            "problemMatcher": [],
            "group": "build"
        },
        {
            "label": "build-x86_64-pc",
            "type": "shell",
            "command": "cd NexNix; ./scripts/buildrun.sh x86_64-pc",
            "problemMatcher": [],
            "group": "build"
        },
        {
            "label": "build-aarch64-virtio",
            "type": "shell",
            "command": "cd NexNix; ./scripts/buildrun.sh aarch64-virtio",
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "build-aarch64-raspi3",
            "type": "shell",
            "command": "cd NexNix; ./scripts/buildrun.sh aarch64-raspi3; sudo dd if=images-aarch64-raspi3/nndisk.img of=/dev/sdb bs=2G",
            "problemMatcher": [],
            "group": "build"
        }
    ]
}
Of course, this would be a lot more brief if you had less targets you were supporting. I'm sure you can imply that this is written in JSON :) .

You can then "Ctrl+Shift+B" to execute the default task. In this example, "aarch64-virtio" is the default task. Note that if your build and run operation aren't serialized, then you can add your emulator command line in there. Mine are, hence why there is no emulator command line :) If you have more then one task you want to support, then you create a keyboard binding for each one. This way, you don't have to change the default task each time. Press "Ctrl+Shift+P" to access the main settings menu, then type "Preferences: Open Keyboard Shortcuts (JSON)". The displayed file, enter something like this for each task:

Code: Select all

// Place your key bindings in this file to override the defaults
[
    {
        "key": "ctrl+shift+; a",
        "command": "workbench.action.tasks.runTask",
        "args": "build-x86_64-pc"
    },
    {
        "key": "ctrl+shift+; b",
        "command": "workbench.action.tasks.runTask",
        "args": "build-i686-pc"
    },
    {
        "key": "ctrl+shift+; c",
        "command": "workbench.action.tasks.runTask",
        "args": "build-aarch64-virtio"
    },
    {
        "key": "ctrl+shift+; d",
        "command": "workbench.action.tasks.runTask",
        "args": "build-aarch64-raspi3"
    }
]
Replace the "args" property with the value of the "label" property of the task. Note the way this is set up, you press Ctrl+Shift+semicolon, then you a, b, c, or d, and VSCode will run the right task for you automatically.

Of course, I haven't mentioned the debugging system, which I haven't played around with yet. My OS is not at that phase yet :)

Btw, thanks for starting this thread, as it inspired me to greatly simplify my workflow in VSCode!

- Edit - typos were fixed