Core Go rules

These are the core go rules, required for basic operation. The intent is that these rules are sufficient to match the capabilities of the normal go tools.

Additional resources


Introduction

Three core rules may be used to build most projects: go_library, go_binary, and go_test. These rules reimplement the low level plumping commands of a normal ‘go build’ invocation: compiling package's source files to archives, then linking archives into go binary.

go_library builds a single package. It has a list of source files (specified with srcs) and may depend on other packages (with deps). Each go_library has an importpath, which is the name used to import it in Go source files.

go_binary also builds a single main package and links it into an executable. It may embed the content of a go_library using the embed attribute. Embedded sources are compiled together in the same package. Binaries can be built for alternative platforms and configurations by setting goos, goarch, and other attributes.

go_test builds a test executable. Like tests produced by go test, this consists of three packages: an internal test package compiled together with the library being tested (specified with embed), an external test package compiled separately, and a generated test main package.

Here is an example of a Bazel build graph for a project using these core rules:

By instrumenting the lower level go tooling, we can cache smaller, finer artifacts with Bazel and thus, speed up incremental builds.

Rules

go_binary

This builds an executable from a set of source files, which must all be in the main package. You can run the binary with bazel run, or you can build it with bazel build and run it directly.

Note: name should be the same as the desired name of the generated binary.

Providers: GoLibrary GoSource GoArchive

Attributes

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
basenameThe basename of this binary. The binary basename may also be platform-dependent: on Windows, we add an .exe extension.Stringoptional""
cdepsThe list of other libraries that the c code depends on. This can be anything that would be allowed in cc_library deps Only valid if cgo = True.List of labelsoptional[]
cgoIf True, the package may contain cgo code, and srcs may contain C, C++, Objective-C, and Objective-C++ files and non-Go assembly files. When cgo is enabled, these files will be compiled with the C/C++ toolchain and included in the package. Note that this attribute does not force cgo to be enabled. Cgo is enabled for non-cross-compiling builds when a C/C++ toolchain is configured.BooleanoptionalFalse
clinkoptsList of flags to add to the C link command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
coptsList of flags to add to the C compilation command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
cppoptsList of flags to add to the C/C++ preprocessor command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
cxxoptsList of flags to add to the C++ compilation command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
dataList of files needed by this rule at run-time. This may include data files needed or other programs that may be executed. The bazel package may be used to locate run files; they may appear in different places depending on the operating system and environment. See data dependencies for more information on data files.List of labelsoptional[]
depsList of Go libraries this package imports directly. These may be go_library rules or compatible rules with the GoLibrary provider.List of labelsoptional[]
embedList of Go libraries whose sources should be compiled together with this binary's sources. Labels listed here must name go_library, go_proto_library, or other compatible targets with the GoLibrary and GoSource providers. Embedded libraries must all have the same importpath, which must match the importpath for this go_binary if one is specified. At most one embedded library may have cgo = True, and the embedding binary may not also have cgo = True. See Embedding for more information.List of labelsoptional[]
embedsrcsThe list of files that may be embedded into the compiled package using //go:embed directives. All files must be in the same logical directory or a subdirectory as source files. All source files containing //go:embed directives must be in the same logical directory. It's okay to mix static and generated source files and static and generated embeddable files.List of labelsoptional[]
envEnvironment variables to set when the binary is executed with bazel run. The values (but not keys) are subject to location expansion but not full make variable expansion.Dictionary: String -> Stringoptional{}
gc_gooptsList of flags to add to the Go compilation command when using the gc compiler. Subject to “Make variable” substitution and Bourne shell tokenization.List of stringsoptional[]
gc_linkoptsList of flags to add to the Go link command when using the gc compiler. Subject to “Make variable” substitution and Bourne shell tokenization.List of stringsoptional[]
goarchForces a binary to be cross-compiled for a specific architecture. It's usually better to control this on the command line with --platforms.

This disables cgo by default, since a cross-compiling C/C++ toolchain is rarely available. To force cgo, set pure = off.

See Cross compilation for more information.
Stringoptional“auto”
goosForces a binary to be cross-compiled for a specific operating system. It's usually better to control this on the command line with --platforms.

This disables cgo by default, since a cross-compiling C/C++ toolchain is rarely available. To force cgo, set pure = off.

See Cross compilation for more information.
Stringoptional“auto”
gotagsEnables a list of build tags when evaluating build constraints. Useful for conditional compilation.List of stringsoptional[]
importpathThe import path of this binary. Binaries can't actually be imported, but this may be used by go_path and other tools to report the location of source files. This may be inferred from embedded libraries.Stringoptional""
linkmodeDetermines how the binary should be built and linked. This accepts some of the same values as go build -buildmode and works the same way.

auto (default): Controlled by //go/config:linkmode, which defaults to normal. normal: Builds a normal executable with position-dependent code. pie: Builds a position-independent executable. plugin: Builds a shared library that can be loaded as a Go plugin. Only supported on platforms that support plugins. c-shared: Builds a shared library that can be linked into a C program. c-archive: Builds an archive that can be linked into a C program.
Stringoptional“auto”
msanControls whether code is instrumented for memory sanitization. May be one of on, off, or auto. Not available when cgo is disabled. In most cases, it's better to control this on the command line with --@io_bazel_rules_go//go/config:msan. See mode attributes, specifically msan.Stringoptional“auto”
outSets the output filename for the generated executable. When set, go_binary will write this file without mode-specific directory prefixes, without linkmode-specific prefixes like “lib”, and without platform-specific suffixes like “.exe”. Note that without a mode-specific directory prefix, the output file (but not its dependencies) will be invalidated in Bazel's cache when changing configurations.Stringoptional""
pgoprofileProvides a pprof file to be used for profile guided optimization when compiling go targets. A pprof file can also be provided via --@io_bazel_rules_go//go/config:pgoprofile=<label of a pprof file>. Profile guided optimization is only supported on go 1.20+. See https://go.dev/doc/pgo for more information.Labeloptional//go/config:empty
pureControls whether cgo source code and dependencies are compiled and linked, similar to setting CGO_ENABLED. May be one of on, off, or auto. If auto, pure mode is enabled when no C/C++ toolchain is configured or when cross-compiling. It's usually better to control this on the command line with --@io_bazel_rules_go//go/config:pure. See mode attributes, specifically pure.Stringoptional“auto”
raceControls whether code is instrumented for race detection. May be one of on, off, or auto. Not available when cgo is disabled. In most cases, it's better to control this on the command line with --@io_bazel_rules_go//go/config:race. See mode attributes, specifically race.Stringoptional“auto”
srcsThe list of Go source files that are compiled to create the package. Only .go, .s, and .syso files are permitted, unless the cgo attribute is set, in which case, .c .cc .cpp .cxx .h .hh .hpp .hxx .inc .m .mm files are also permitted. Files may be filtered at build time using Go build constraints.List of labelsoptional[]
staticControls whether a binary is statically linked. May be one of on, off, or auto. Not available on all platforms or in all modes. It's usually better to control this on the command line with --@io_bazel_rules_go//go/config:static. See mode attributes, specifically static.Stringoptional“auto”
x_defsMap of defines to add to the go link command. See Defines and stamping for examples of how to use these.Dictionary: String -> Stringoptional{}

go_cross_binary

This wraps an executable built by go_binary to cross compile it for a different platform, and/or compile it using a different version of the golang SDK.

Providers: GoLibrary GoSource GoArchive

Attributes

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
platformThe platform to cross compile the target for. If unspecified, the target will be compiled with the same platform as it would've with the original go_binary rule.LabeloptionalNone
sdk_versionThe golang SDK version to use for compiling the target. Supports specifying major, minor, and/or patch versions, eg. “1”, “1.17”, or “1.17.1”. The first Go SDK provider installed in the repo‘s workspace (via go_download_sdk, go_wrap_sdk, etc) that matches the specified version will be used for compiling the given target. If unspecified, the target will be compiled with the same SDK as it would’ve with the original go_binary rule. Transitions target by changing the --@io_bazel_rules_go//go/toolchain:sdk_version build flag to the value provided for sdk_version here.Stringoptional""
targetGo binary target to transition to the given platform and/or sdk_version.Labelrequired

go_library

This builds a Go library from a set of source files that are all part of the same package.

Note: For targets generated by Gazelle, name is typically the last component of the path, or go_default_library, with the old naming convention.

Providers: GoLibrary GoSource GoArchive

Attributes

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
cdepsList of other libraries that the c code depends on. This can be anything that would be allowed in cc_library deps Only valid if cgo = True.List of labelsoptional[]
cgoIf True, the package may contain cgo code, and srcs may contain C, C++, Objective-C, and Objective-C++ files and non-Go assembly files. When cgo is enabled, these files will be compiled with the C/C++ toolchain and included in the package. Note that this attribute does not force cgo to be enabled. Cgo is enabled for non-cross-compiling builds when a C/C++ toolchain is configured.BooleanoptionalFalse
clinkoptsList of flags to add to the C link command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
coptsList of flags to add to the C compilation command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
cppoptsList of flags to add to the C/C++ preprocessor command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
cxxoptsList of flags to add to the C++ compilation command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
dataList of files needed by this rule at run-time. This may include data files needed or other programs that may be executed. The bazel package may be used to locate run files; they may appear in different places depending on the operating system and environment. See data dependencies for more information on data files.List of labelsoptional[]
depsList of Go libraries this package imports directly. These may be go_library rules or compatible rules with the GoLibrary provider.List of labelsoptional[]
embedList of Go libraries whose sources should be compiled together with this package's sources. Labels listed here must name go_library, go_proto_library, or other compatible targets with the GoLibrary and GoSource providers. Embedded libraries must have the same importpath as the embedding library. At most one embedded library may have cgo = True, and the embedding library may not also have cgo = True. See Embedding for more information.List of labelsoptional[]
embedsrcsThe list of files that may be embedded into the compiled package using //go:embed directives. All files must be in the same logical directory or a subdirectory as source files. All source files containing //go:embed directives must be in the same logical directory. It's okay to mix static and generated source files and static and generated embeddable files.List of labelsoptional[]
gc_gooptsList of flags to add to the Go compilation command when using the gc compiler. Subject to “Make variable” substitution and Bourne shell tokenization.List of stringsoptional[]
importmapThe actual import path of this library. By default, this is importpath. This is mostly only visible to the compiler and linker, but it may also be seen in stack traces. This must be unique among packages passed to the linker. It may be set to something different than importpath to prevent conflicts between multiple packages with the same path (for example, from different vendor directories).Stringoptional""
importpathThe source import path of this library. Other libraries can import this library using this path. This must either be specified in go_library or inherited from one of the libraries in embed.Stringoptional""
importpath_aliases-List of stringsoptional[]
srcsThe list of Go source files that are compiled to create the package. Only .go and .s files are permitted, unless the cgo attribute is set, in which case, .c .cc .cpp .cxx .h .hh .hpp .hxx .inc .m .mm files are also permitted. Files may be filtered at build time using Go build constraints.List of labelsoptional[]
x_defsMap of defines to add to the go link command. See Defines and stamping for examples of how to use these.Dictionary: String -> Stringoptional{}

go_path

go_path builds a directory structure that can be used with tools that understand the GOPATH directory layout. This directory structure can be built by zipping, copying, or linking files. go_path can depend on one or more Go targets (i.e., go_library, go_binary, or go_test). It will include packages from those targets, as well as their transitive dependencies. Packages will be in subdirectories named after their importpath or importmap attributes under a src/ directory.

Attributes

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
dataA list of targets producing data files that will be stored next to the src/ directory. Useful for including things like licenses and readmes.List of labelsoptional[]
depsA list of targets that build Go packages. A directory will be generated from files in these targets and their transitive dependencies. All targets must provide GoArchive (go_library, go_binary, go_test, and similar rules have this).

Only targets with explicit importpath attributes will be included in the generated directory. Synthetic packages (like the main package produced by go_test) and packages with inferred import paths will not be included. The values of importmap attributes may influence the placement of packages within the generated directory (for example, in vendor directories).

The generated directory will contain original source files, including .go, .s, .h, and .c files compiled by cgo. It will not contain files generated by tools like cover and cgo, but it will contain generated files passed in srcs attributes like .pb.go files. The generated directory will also contain runfiles found in data attributes.
List of labelsoptional[]
include_dataWhen true, data files referenced by libraries, binaries, and tests will be included in the output directory. Files listed in the data attribute for this rule will be included regardless of this attribute.BooleanoptionalTrue
include_pkgWhen true, a pkg subdirectory containing the compiled libraries will be created in the generated GOPATH containing compiled libraries.BooleanoptionalFalse
include_transitiveWhen true, the transitive dependency graph will be included in the generated GOPATH. This is the default behaviour. When false, only the direct dependencies will be included in the generated GOPATH.BooleanoptionalTrue
modeDetermines how the generated directory is provided. May be one of: “archive”: The generated directory is packaged as a single .zip file. “copy”: The generated directory is a single tree artifact. Source files are copied into the tree. “link”: Unmaintained due to correctness issues. Source files are symlinked into the tree. All of the symlink files are provided as separate output files. Note: In “copy” mode, when a GoPath is consumed as a set of input files or run files, Bazel may provide symbolic links instead of regular files. Any program that consumes these files should dereference links, e.g., if you run tar, use the --dereference flag.Stringoptional“copy”

go_source

This declares a set of source files and related dependencies that can be embedded into one of the other rules. This is used as a way of easily declaring a common set of sources re-used in multiple rules.

Providers: GoLibrary GoSource

Attributes

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
dataList of files needed by this rule at run-time. This may include data files needed or other programs that may be executed. The bazel package may be used to locate run files; they may appear in different places depending on the operating system and environment. See data dependencies for more information on data files.List of labelsoptional[]
depsList of Go libraries this source list imports directly. These may be go_library rules or compatible rules with the GoLibrary provider.List of labelsoptional[]
embedList of Go libraries whose sources should be compiled together with this package's sources. Labels listed here must name go_library, go_proto_library, or other compatible targets with the GoLibrary and GoSource providers. Embedded libraries must have the same importpath as the embedding library. At most one embedded library may have cgo = True, and the embedding library may not also have cgo = True. See Embedding for more information.List of labelsoptional[]
gc_gooptsList of flags to add to the Go compilation command when using the gc compiler. Subject to “Make variable” substitution and Bourne shell tokenization.List of stringsoptional[]
srcsThe list of Go source files that are compiled to create the package. The following file types are permitted: .go, .c, .s, .S .h. The files may contain Go-style build constraints.List of labelsoptional[]

go_test

This builds a set of tests that can be run with bazel test.

To run all tests in the workspace, and print output on failure (the equivalent of go test ./...), run
bazel test --test_output=errors //...

To run a Go benchmark test, run
bazel run //path/to:test -- -test.bench=.

You can run specific tests by passing the --test_filter=pattern <test_filter_> argument to Bazel. You can pass arguments to tests by passing --test_arg=arg <test_arg_> arguments to Bazel, and you can set environment variables in the test environment by passing --test_env=VAR=value <test_env_>. You can terminate test execution after the first failure by passing the --test_runner_fail_fast <test_runner_fail_fast_> argument to Bazel. This is equivalent to passing --test_arg=-failfast <test_arg_>.

To write structured testlog information to Bazel's XML_OUTPUT_FILE, tests ran with bazel test execute using a wrapper. This functionality can be disabled by setting GO_TEST_WRAP=0 in the test environment. Additionally, the testbinary can be invoked with -test.v by setting GO_TEST_WRAP_TESTV=1 in the test environment; this will result in the XML_OUTPUT_FILE containing more granular data.

Note: To interoperate cleanly with old targets generated by Gazelle, name should be go_default_test for internal tests and go_default_xtest for external tests. Gazelle now generates the name based on the last component of the path. For example, a test in //foo/bar is named bar_test, and uses internal and external sources.

Attributes

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
cdepsThe list of other libraries that the c code depends on. This can be anything that would be allowed in cc_library deps Only valid if cgo = True.List of labelsoptional[]
cgoIf True, the package may contain cgo code, and srcs may contain C, C++, Objective-C, and Objective-C++ files and non-Go assembly files. When cgo is enabled, these files will be compiled with the C/C++ toolchain and included in the package. Note that this attribute does not force cgo to be enabled. Cgo is enabled for non-cross-compiling builds when a C/C++ toolchain is configured.BooleanoptionalFalse
clinkoptsList of flags to add to the C link command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
coptsList of flags to add to the C compilation command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
cppoptsList of flags to add to the C/C++ preprocessor command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
cxxoptsList of flags to add to the C++ compilation command. Subject to “Make variable” substitution and Bourne shell tokenization. Only valid if cgo = True.List of stringsoptional[]
dataList of files needed by this rule at run-time. This may include data files needed or other programs that may be executed. The bazel package may be used to locate run files; they may appear in different places depending on the operating system and environment. See data dependencies for more information on data files.List of labelsoptional[]
depsList of Go libraries this test imports directly. These may be go_library rules or compatible rules with the GoLibrary provider.List of labelsoptional[]
embedList of Go libraries whose sources should be compiled together with this package's sources. Labels listed here must name go_library, go_proto_library, or other compatible targets with the GoLibrary and GoSource providers. Embedded libraries must have the same importpath as the embedding library. At most one embedded library may have cgo = True, and the embedding library may not also have cgo = True. See Embedding for more information.List of labelsoptional[]
embedsrcsThe list of files that may be embedded into the compiled package using //go:embed directives. All files must be in the same logical directory or a subdirectory as source files. All source files containing //go:embed directives must be in the same logical directory. It's okay to mix static and generated source files and static and generated embeddable files.List of labelsoptional[]
envEnvironment variables to set for the test execution. The values (but not keys) are subject to location expansion but not full make variable expansion.Dictionary: String -> Stringoptional{}
env_inheritEnvironment variables to inherit from the external environment.List of stringsoptional[]
gc_gooptsList of flags to add to the Go compilation command when using the gc compiler. Subject to “Make variable” substitution and Bourne shell tokenization.List of stringsoptional[]
gc_linkoptsList of flags to add to the Go link command when using the gc compiler. Subject to “Make variable” substitution and Bourne shell tokenization.List of stringsoptional[]
goarchForces a binary to be cross-compiled for a specific architecture. It's usually better to control this on the command line with --platforms.

This disables cgo by default, since a cross-compiling C/C++ toolchain is rarely available. To force cgo, set pure = off.

See Cross compilation for more information.
Stringoptional“auto”
goosForces a binary to be cross-compiled for a specific operating system. It's usually better to control this on the command line with --platforms.

This disables cgo by default, since a cross-compiling C/C++ toolchain is rarely available. To force cgo, set pure = off.

See Cross compilation for more information.
Stringoptional“auto”
gotagsEnables a list of build tags when evaluating build constraints. Useful for conditional compilation.List of stringsoptional[]
importpathThe import path of this test. Tests can't actually be imported, but this may be used by go_path and other tools to report the location of source files. This may be inferred from embedded libraries.Stringoptional""
linkmodeDetermines how the binary should be built and linked. This accepts some of the same values as go build -buildmode and works the same way.

auto (default): Controlled by //go/config:linkmode, which defaults to normal. normal: Builds a normal executable with position-dependent code. pie: Builds a position-independent executable. plugin: Builds a shared library that can be loaded as a Go plugin. Only supported on platforms that support plugins. c-shared: Builds a shared library that can be linked into a C program. c-archive: Builds an archive that can be linked into a C program.
Stringoptional“auto”
msanControls whether code is instrumented for memory sanitization. May be one of on, off, or auto. Not available when cgo is disabled. In most cases, it's better to control this on the command line with --@io_bazel_rules_go//go/config:msan. See mode attributes, specifically msan.Stringoptional“auto”
pureControls whether cgo source code and dependencies are compiled and linked, similar to setting CGO_ENABLED. May be one of on, off, or auto. If auto, pure mode is enabled when no C/C++ toolchain is configured or when cross-compiling. It's usually better to control this on the command line with --@io_bazel_rules_go//go/config:pure. See mode attributes, specifically pure.Stringoptional“auto”
raceControls whether code is instrumented for race detection. May be one of on, off, or auto. Not available when cgo is disabled. In most cases, it's better to control this on the command line with --@io_bazel_rules_go//go/config:race. See mode attributes, specifically race.Stringoptional“auto”
rundirA directory to cd to before the test is run. This should be a path relative to the root directory of the repository in which the test is defined, which can be the main or an external repository.

The default behaviour is to change to the relative path corresponding to the test‘s package, which replicates the normal behaviour of go test so it is easy to write compatible tests.

Setting it to . makes the test behave the normal way for a bazel test, except that the working directory is always that of the test’s repository, which is not necessarily the main repository.

Note: If runfile symlinks are disabled (such as on Windows by default), the test will run in the working directory set by Bazel, which is the subdirectory of the runfiles directory corresponding to the main repository.
Stringoptional""
srcsThe list of Go source files that are compiled to create the package. Only .go and .s files are permitted, unless the cgo attribute is set, in which case, .c .cc .cpp .cxx .h .hh .hpp .hxx .inc .m .mm files are also permitted. Files may be filtered at build time using Go build constraints.List of labelsoptional[]
staticControls whether a binary is statically linked. May be one of on, off, or auto. Not available on all platforms or in all modes. It's usually better to control this on the command line with --@io_bazel_rules_go//go/config:static. See mode attributes, specifically static.Stringoptional“auto”
x_defsMap of defines to add to the go link command. See Defines and stamping for examples of how to use these.Dictionary: String -> Stringoptional{}