Skip to content

Instantly share code, notes, and snippets.

@kennwhite
Last active February 9, 2024 21:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kennwhite/26a99bd82fed8cb426992ac1e2fc0212 to your computer and use it in GitHub Desktop.
Save kennwhite/26a99bd82fed8cb426992ac1e2fc0212 to your computer and use it in GitHub Desktop.
Setting up VS Code and Golang with debug & build flag (-tags foo) support

Setting up VS Code and Golang with debug & build flag (-tags foo) support

This is the setup that worked for me after half a day of hacking around and chasing rabbit holes down old forum posts and open & closed Github issues.

Problem: While Go integration with VS Code is pretty slick in general, I needed to pass compile-time build flags, e.g., -tags foo1 to go build and go run directives, and I wanted to be able to properly debug with breakpoints etc. While there are some promising tutorials out there like this on Digital Ocean and on Log Rocket it turned out that one of the first things they both say to do is add the Delve extension to VS Code, which is no longer necessary and in fact adds needless complexity and more configuration surface to sort out.

Here's what worked for me on my M1/Apple Silicon Mac, but the config should work on other OS's. These files would go in the same top level directory as your Go project (or location of a single standalone file).

.vscode/launch.json

{
    // 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": "Launch Package",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${fileDirname}",
            "buildFlags": "-tags=cse"
        }
    ]
}

.vscode/settings.json

{
    "go.useLanguageServer": false,
    "go.buildOnSave": "off",
}

I'd prefer to use the built-in go language server (gopls), but whenever it's enabled (the default) in VS Code, on every file load or run I get:

"message": "err: exit status 2: stderr: flag provided but not defined: -tags cse usage: go list [-f format] [-json] [-m] [list flags] [build flags] [packages] Run 'go help list' for details.

I've not yet been able to find a way to pass flags only to go build and go run but not go list et al. If anyone has any ideas, please let me know. Update: thanks to Kevin Albertson for the tip, I can use the language server via this configuration in settings.json:

{
   "gopls": {
        "build.buildFlags": [
            "-tags=cse"
        ]
    },
    "go.useLanguageServer": true,
    "go.buildOnSave": "off",
}

Some useful resources which may or may not still be current/relevant:

https://github.com/golang/vscode-go/wiki/settings

https://github.com/golang/vscode-go/blob/master/docs/settings.md

https://github.com/golang/vscode-go/blob/master/docs/debugging.md

https://go.googlesource.com/vscode-go/+/HEAD/docs/settings.md#detailed-list

Other possibly useful pages (though some are outdated, but link to current state):

https://www.ryanchapin.com/configuring-vscode-to-use-build-tags-in-golang-to-separate-integration-and-unit-test-code/

microsoft/vscode-go#3185 (comment)

microsoft/vscode-go#3185 (comment)

golang/vscode-go#128 (still open as of this writeup, Sep 2022)

https://stackoverflow.com/questions/60497980/golang-vscode-configuration-best-setup

Footnotes

  1. Specifically in my case — for the benefit of internet searchers arriving here — looking to use mongodb client-side field level encryption or queryable encryption with Go which needs go build and go run to pass in -tags cse (e.g., go build -tags cse [myproject]). Initially I was getting fatal VS Code debug errors around libmongocrypt and thought I needed to add pkg-config with Brew to make everything work, but it turned out VS just wasn't picking up the -tags cse directive. When I used Kevin's suggestion (above) I did need to do a brew install pkg-config when using the built-in VS Code language server. Also, no need for a special manual libmongocrypt compile/binary at the project level either, just brew install mongodb/brew/libmongocrypt (for Brew itself, I opted for the non-root user-level simple tar install method to /opt/homebrew and then added the environment eval script call to my .bash_profile ) and no other special packages were required. As far as Go itself, I just pulled the latest ARM64 package from the official download site and let the installer update the path and target to /usr/local/go. I opted out of using Brew's go cask (wtf?) or whatever, and also set my environment variable to HOMEBREW_NO_AUTO_UPDATE=1 because personally, I prefer a routine tiny package install to not make me wait 20 minutes while half an internet of crap is downloaded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment