Skip to main content

Toolchains

Go toolchains in Buck2 come in two types: "regular" and "bootstrap".

  • Regular toolchains are used to build Go code.
  • Bootstrap toolchains are used to build the tools required to build Go code.

A minimal setup requires :go, :go_bootstrap, and :python_bootstrap in your toolchains// cell.

Additionally, a :cxx toolchain is required:

  • If you use CGo, you need a fully configured CXX toolchain
  • If you don't use CGo, you can define it with a stub no_toolchain rule

Each type of Go toolchain has two implementations: "system" and "hermetic".

Hermetic toolchains are the recommended way to build Go code because they:

  • Make builds reproducible
  • Support all features of the Go rules

Hermetic toolchains consist of two rules: go*_distr and go*_toolchain.

The *_distr rules wrap Go distributions produced by go tool dist, such as those available at go.dev/dl.

You can use either local or http_archive Go distributions.

Toolchain Locations

  • @prelude//toolchains/go:go_toolchain.bzl
  • @prelude//toolchains/go:go_bootstrap_toolchain.bzl

Example Configuration

Here's an example of go_toolchain using local Go distributions (go_bootstrap_toolchain is defined similarly):

load("@prelude//toolchains/go:go_toolchain.bzl", "go_distr", "go_toolchain")

# Note: selects are resolved against execution-platform
go_distr(
name = "go_distr",
go_os_arch = select({
"config//os:linux": select({"config//cpu:x86_64": ("linux", "amd64")}),
"config//os:macos": select({"config//cpu:arm64": ("darwin", "arm64")}),
}),
go_root = select({
"config//os:linux": select({"config//cpu:x86_64": "path/to/go-linux-amd64"}),
"config//os:macos": select({"config//cpu:arm64": "path/to/go-darwin-arm64"}),
}),
)

# Note: selects are resolved against target-platform
go_toolchain(
name = "go",
env_go_arch = select({
"config//cpu:arm64": "arm64",
"config//cpu:x86_64": "amd64",
}),
env_go_os = select({
"config//os:linux": "linux",
"config//os:macos": "darwin",
"config//os:windows": "windows",
}),
go_distr = ":go_distr",
visibility = ["PUBLIC"],
)

For a complete example using http_archive, see examples/toolchains/go_toolchain.

Advanced: Multi-platform Toolchains

If you support multiple execution platforms using standard Go distributions (produced by go tool dist), you may encounter a situation where you have multiple copies of the Go distribution with almost identical content.

The go_distr rule supports a non-standard layout of the Go distribution, allowing you to maintain a single copy of the source code with bin and pkg/tool directories containing binaries for all execution platforms you support.

Set multiplatform = True on go_distr to enable this behavior. In this case, the bin and pkg/tool directories must contain binaries in goos_goarch subdirectories (built for the corresponding platforms).

See the example for a Go distribution supporting two execution platforms: linux/amd64 and darwin/arm64.

third-party/go/1.25.1
├── api
├── bin
│   ├── darwin_arm64
│   │   ├── go
│   │   └── gofmt
│   └── linux_amd64
│   └── ...
├── ...
├── pkg
│ ├── include
│ └── tool
│   ├── darwin_arm64
│   │   ├── asm
│   │   ├── cgo
│   │   └── ...
│   └── linux_amd64
│   └── ...
└── ...

You can produce it by downloading the src distribution from https://go.dev/dl/ and running the following commands (assuming you are running on linux/amd64 and have Go installed on your system).

$ cd distr_dir/src
$ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 ./make.bash
$ CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 ./make.bash
$ mkdir ../bin/linux_amd64
$ mv ../bin/go ../bin/linux_amd64
$ mv ../bin/gofmt ../bin/linux_amd64

System Toolchains

System toolchains are not intended for production builds but can be used for examples and simple projects. Note that some features of Go rules might not work with system toolchains, such as building ASM files.

Toolchain Locations

  • @prelude//toolchains/go:system_go_toolchain.bzl
  • @prelude//toolchains/go:system_go_bootstrap_toolchain.bzl

Example Configuration

load("@prelude///toolchains/go:system_go_bootstrap_toolchain.bzl", "system_go_bootstrap_toolchain")
load("@prelude///toolchains/go:system_go_toolchain.bzl", "system_go_toolchain")

system_go_toolchain(
name = "go",
visibility = ["PUBLIC"],
)

system_go_bootstrap_toolchain(
name = "go_bootstrap",
visibility = ["PUBLIC"],
)