Features GoLand Tutorials

Compile and run Go code using WSL 2 and GoLand

Today, I’m happy to introduce our latest feature to you to use Windows Subsystem for Linux version 2 (WSL 2, or simply WSL) to run or test Go applications seamlessly.

This feature is called Run Targets and supports WSL 2, Docker, and SSH remotes.

If you’d like to learn more about these, the overview article of this feature, explaining it in more detail, should come in handy.

In this article, I’ll focus on the WSL 2 side of this feature. If you wish to use other targets, you can check the article covering the Docker target.

If you’d prefer a video version of this article, then please head to YouTube:

Run Targets for WSL 2 in action

For this article, I’ll reuse most of the code that we’ve seen in the Docker tutorial – with the change that we are now checking for the WSL instead of a Docker environment.

package main

import (
	"fmt"
	"log"
	"net/http"
	"os/exec"
	"runtime"
	"strings"
)

func homeHandler(w http.ResponseWriter, r *http.Request) {
	myOS, myArch := runtime.GOOS, runtime.GOARCH
	inWSL := "outside"
	cmd := exec.Command("uname", "-a")
	if output, err := cmd.Output(); err == nil {
		if strings.Contains(strings.ToLower(string(output)), "microsoft") {
			inWSL = "inside"
		}
	}

	w.Header().Set("Content-Type", "text/plain")
	w.WriteHeader(http.StatusOK)

	_, _ = fmt.Fprintf(w, "Hello, %s!\n", r.UserAgent())
	_, _ = fmt.Fprintf(w, "I'm running on %s/%s.\n", myOS, myArch)
	_, _ = fmt.Fprintf(w, "I'm running %s of WSL.\n", inWSL)
}

func main() {
	http.HandleFunc("/", homeHandler)

	err := http.ListenAndServe(":38000", nil)
	if err != nil {
		log.Fatalln(err)
	}
}

Enter the WSL 2 environment

With the WSL becoming more popular among developers, let’s see how we can use it for our applications.

We first need to create a new run target.

Head over to Run | Manage Targets... | + | WSL.

If you have different Linux distributions installed, you can choose which one to use. Creating multiple targets is possible, which means you can create one for each of these Linux distributions.

After the IDE performs the environment’s introspection, you can review the settings it detected and, if needed, adjust where the go binary is, what the GOPATH is, and what version of Go is in use.

Create WSL Run Target

We can either edit the existing run configuration or create a new one to use the newly created target.

Let’s reuse our existing run configuration and change the Run on field from the Local machine to the new WSL target.

We can also change the working directory, if needed, to ensure that our application will start from the expected place.

All that’s left to do is confirm our changes with the OK button and rerun the configuration.

Use the WSL Run Target in the Run Configuration

That’s it! Our application now works inside our WSL 2 environment.

Debugging a Go application using WSL

Running is not the only option. We can also use the debugger to investigate what our application is doing at runtime.

Debug under WSL

Running Go tests and benchmarks in WSL

Besides applications, you can run tests and benchmarks configurations using this feature.

As an example, let’s create a new Go Test configuration and set the Run on field to the same WSL configuration as our application.

Then, we need to launch our test, and it will run against the WSL environment.

Tests with coverage or profiling with benchmarks work similarly.

Launch Test with Run Target and Coverage

Limitations:

There are a couple of limitations that you need to consider before using this feature.

The source code has to be inside the Windows native side of the OS rather than under WSL 2. Otherwise, the IDE won’t be able to process any dependencies present in the code correctly.
The Go SDK must be installed on Windows too, not just inside WSL 2, as the IDE cannot use the WSL 2 Go SDK.

And that’s for today. We learned how to use WSL transparently to run our applications, tests, and benchmarks.

Please keep in mind that this feature is still in its early days. We’d like to hear from you about any improvements we can make to transform this feature into another tool in your toolbelt.

You can reach out to us by commenting below this post, raise an issue on our tracker, ping us on Gophers Slack in the #goland channel, or via @GoLandIDE on Twitter.

Discover more