Tinygo + Helix + Gopls for the RPI Pico (my setup for embedded dev with Tinygo)

Hi,
Later updated: added a repo for all the below GitHub - TinHead/tinygo-shells: Nix dev shells for Tinygo
Just wanted to share my setup in case anyone struggles as I did :slight_smile:
Note this only works for Raspberry Pi Pico if you need another target you will need to change things

Flake:

{
  description = "TinyGo shell";
  inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem
      (system:
        let pkgs = nixpkgs.legacyPackages.${system}; in
        {
          devShells.default = import ./shell.nix { inherit pkgs; };
        }
      );
}

And the Shell.nix (don’t copy paste it just yet!):

{ pkgs ? import <unstable> {} }:
with pkgs;
mkShell {
  buildInputs = [
    tinygo go gopls delve
  ];

  shellHook = ''
    export GOROOT=/home/me/.cache/tinygo/goroot-b6be8da3b691185bffc16eb52547919fca1fd770fb8d5abe25acf380364687a5
    export GOFLAGS=-tags=cortexm,baremetal,linux,arm,rp2040,rp,pico,tinygo,math_big_pure_go,gc.conservative,scheduler.tasks,serial.usb
    export GOPATH=/home/me/go:${tinygo}/share/tinygo
  '';
}                                                                                                        

Explanation:

These environment variables are populated from the output of:

tinygo info pico

Which in my case shows:

❯ tinygo info pico
LLVM triple:       thumbv6m-unknown-unknown-eabi
GOOS:              linux
GOARCH:            arm
build tags:        cortexm baremetal linux arm rp2040 rp pico tinygo math_big_pure_go gc.conservative scheduler.tasks serial.usb
garbage collector: conservative
scheduler:         tasks
cached GOROOT:     /home/me/.cache/tinygo/goroot-b6be8da3b691185bffc16eb52547919fca1fd770fb8d5abe25acf380364687a5

Out the above I have populated my own, yes not reproductible, no I don’t know how to magically derive them.

The GOPATH has to include the standard gopath which in NixOS is /home/<user>/go.

With those all set Helix (the editor) will do all the magik, completion and all.

Finally it’s a flake + shell because I could not get it to work with a pure flake :nix_parrot:

Enjoy,
Razvan

PS:
Turns out I’m too lazy this will do some magik

{ pkgs ? import <unstable> {} }:
with pkgs;
mkShell {
  buildInputs = [
    tinygo go gopls delve
  ];

  shellHook = ''
     export GOROOT=$(tinygo info pico|grep GOROOT|awk '{print $3}')
     export GOFLAGS=-tags=cortexm,baremetal,linux,arm,rp2040,rp,pico,tinygo,math_big_pure_go,gc.conservative,scheduler.tasks,serial.usb
     export GOPATH=/home/$(whoami)/go:${tinygo}/share/tinygo
  '';
}

I’ll deal with the flags some other day. :slight_smile:

PS2:
Yeah awk rulez

{ pkgs ? import <unstable> {} }:
with pkgs;
mkShell {
  buildInputs = [
    tinygo go gopls delve
  ];

  shellHook = ''
     export GOROOT=$(tinygo info pico|grep GOROOT|awk '{print $3}')
     export GOFLAGS=-tags=$(tinygo info pico|grep "build tags"|awk -F" {1,}" '{for(i=3;i<NF;i++) printf $i","; print $NF}')
     export GOPATH=/home/$(whoami)/go:${tinygo}/share/tinygo
  '';
}

There fully magik driven and reproductible :nix_parrot:

1 Like