diff options
Diffstat (limited to 'docs/go/core/defines_and_stamping.md')
-rw-r--r-- | docs/go/core/defines_and_stamping.md | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/docs/go/core/defines_and_stamping.md b/docs/go/core/defines_and_stamping.md new file mode 100644 index 00000000..9d616c5f --- /dev/null +++ b/docs/go/core/defines_and_stamping.md @@ -0,0 +1,94 @@ +## Defines and stamping + +In order to provide build time information to go code without data files, we +support the concept of stamping. + +Stamping asks the linker to substitute the value of a global variable with a +string determined at link time. Stamping only happens when linking a binary, not +when compiling a package. This means that changing a value results only in +re-linking, not re-compilation and thus does not cause cascading changes. + +Link values are set in the `x_defs` attribute of any Go rule. This is a +map of string to string, where keys are the names of variables to substitute, +and values are the string to use. Keys may be names of variables in the package +being compiled, or they may be fully qualified names of variables in another +package. + +These mappings are collected up across the entire transitive dependencies of a +binary. This means you can set a value using `x_defs` in a +`go_library`, and any binary that links that library will be stamped with that +value. You can also override stamp values from libraries using `x_defs` +on the `go_binary` rule if needed. The `--[no]stamp` option controls whether +stamping of workspace variables is enabled. + +The values of the `x_defs` dictionary are subject to +[location expansion](https://bazel.build/reference/be/make-variables#predefined_label_variables). + +**Example** + +Suppose we have a small library that contains the current version. + +``` go +package version + +var Version = "redacted" +``` + +We can set the version in the `go_library` rule for this library. + +``` bzl +go_library( + name = "version", + srcs = ["version.go"], + importpath = "example.com/repo/version", + x_defs = {"Version": "0.9"}, +) +``` + +Binaries that depend on this library may also set this value. + +``` bzl +go_binary( + name = "cmd", + srcs = ["main.go"], + deps = ["//version"], + x_defs = {"example.com/repo/version.Version": "0.9"}, +) +``` + +### Stamping with the workspace status script + +You can use values produced by the workspace status command in your link stamp. +To use this functionality, write a script that prints key-value pairs, separated +by spaces, one per line. For example: + +``` bash +#!/usr/bin/env bash + +echo STABLE_GIT_COMMIT $(git rev-parse HEAD) +``` + +***Note:*** stamping with keys that bazel designates as "stable" will trigger a +re-link when any stable key changes. Currently, in bazel, stable keys are +`BUILD_EMBED_LABEL`, `BUILD_USER`, `BUILD_HOST` and keys whose names start with +`STABLE_`. Stamping only with keys that are not stable keys will not trigger a +relink. + +You can reference these in `x_defs` using curly braces. + +``` bzl +go_binary( + name = "cmd", + srcs = ["main.go"], + deps = ["//version"], + x_defs = {"example.com/repo/version.Version": "{STABLE_GIT_COMMIT}"}, +) +``` + +You can build using the status script using the `--workspace_status_command` +argument on the command line: + +``` bash +$ bazel build --stamp --workspace_status_command=./status.sh //:cmd +``` + |