How to develop Golang in WSL2

Reasons

Recently, I have been working on a project that requires Golang development, and I found that developing Golang on Windows is… well, pathetic.

Initially, I tried to use go on Windows; the compilation speed was so slow. When a colleague used a Mac, which compiled in 2 seconds, mine took about half a minute or more; then, I wrote a Dockerfile to copy files to WSL and build the image with the Linux runtime, but it was not convenient to debug.

So, here comes the solution: using WSL2 to develop Golang.

Prerequisites

  • WSL2 installed, please refer to this for installation guide

Install Gvm

  • Before installing Golang, we need to install gvm (Go Version Manager) first

  • Install required packages

    sudo apt update
    sudo apt install curl git mercurial make binutils bison gcc build-essential -y
    
  • Install gvm

    bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
    
  • After installation, check the available versions

    gvm listall
    

    Output:

    gvm gos (available)
    
        go1
        go1.0.1
        .
        .
        .
        go1.22rc2
        go1.22.0
        go1.22.1
        release.r56
        release.r57
    
  • Install your version (recommended to install version grander than 1.18 for integration with dlv and gopls)

    gvm install go1.22.1 --binary
    
  • Set the default version

    gvm use go1.22.1 --default
    

Install Golang Tools

  • Install dlv for debugging
    go install github.com/go-delve/delve/cmd/dlv@latest
    

Windows VSCode Integration

  • Install WSL extension in VSCode
  • Install Go extension in VSCode
  • Add settings to F1 -> Preference: Open User Settings (JSON)
    {
      "go.useLanguageServer": true,
      "terminal.integrated.shellArgs.linux": ["-l"],
      "code-runner.saveAllFilesBeforeRun": true,
      "code-runner.ignoreSelection": true,
      "code-runner.runInTerminal": true
    }
    

Create a Hello World Project

WSL

  • Clone go-training/hello-world in WSL2
    cd ~
    mkdir repos
    cd repos
    git clone https://github.com/go-training/helloworld
    

Windows

  • Open the project by VSCode in Windows and command with F1 -> WSL: Connect to WSL (or click the bottom left corner of the VSCode)

    remote-dev-status-bar

  • Run command F1 -> File: Open Folder... to ~/repos/helloworld in VSCode

    open-folder

  • go mod init

    go mod init main.go
    go mod tidy 
    
  • .vscode/launch.json

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Launch",
                "type": "go",
                "request": "launch",
                "mode": "auto",
                "program": "${workspaceFolder}",
                "env": {},
                "args": []
            }
        ]
    }
    
  • Run the project by F5

    Starting: /home/<username>/.gvm/pkgsets/go1.22.1/global/bin/dlv dap --listen=127.0.0.1:43847 --log-dest=3 from /home/<username>/repos/helloworld
    DAP server listening at: 127.0.0.1:43847
    Type 'dlv help' for list of commands.
    Hello World!!
    Process 28762 has exited with status 0
    Detaching
    dlv dap (28549) exited with code: 0
    
  • Congratulations! You are now able to develop Golang in WSL2 with VSCode.

Bonus: SSH Key Sharing

Sharing SSH keys between Windows and WSL 2

  • Copy the SSH key from Windows to WSL2

    cp /mnt/c/Users/<username>/.ssh/* ~/.ssh/
    
  • Change the permission of the key

    chmod 600 ~/.ssh/id_ed25519
    
  • Add the key to the ssh-agent

    sudo apt install keychain
    eval `keychain --eval --agents ssh id_ed25519`
    

Using SSH instead of HTTPS

  • By default, go get uses HTTPS when cloning a repository, it will be a issue if we have repo references with SSH, when company’s policy is to use SSH for security reasons.
  • Add the following configuration to ~/.gitconfig to use SSH instead of HTTPS
    [url "ssh://git@github.com/"]
      insteadOf = https://github.com/
    

References

comments powered by Disqus