diff --git a/README.md b/README.md index e29ee56a49..4719e2d55e 100644 --- a/README.md +++ b/README.md @@ -457,7 +457,7 @@ go_library( ## go\_binary ```bzl -go_binary(name, srcs, deps, data) +go_binary(name, srcs, deps, data, stamp) ``` @@ -499,6 +499,20 @@ go_binary(name, srcs, deps, data)

List of files needed by this rule at runtime.

+ + + +
stamp + Boolean; optional; default is False +

Whether build information should be included in the generated binary. + Add @io_bazel_rules_go//buildstamp:go_default_library to + deps to access the build information . Build with + --workspace_status_command=./status.sh to add custom + information (using your own script). + + tools/buildstamp/get_workspace_status in Bazel is a good template + for this that provides the Git revision and status. +

diff --git a/buildstamp/BUILD b/buildstamp/BUILD new file mode 100644 index 0000000000..4cea206c70 --- /dev/null +++ b/buildstamp/BUILD @@ -0,0 +1,9 @@ +load("//go:def.bzl", "go_library", "go_prefix") + +go_prefix("github.com/bazelbuild/rules_go") + +go_library( + name = "go_default_library", + srcs = glob(["*.go"]), + visibility = ["//visibility:public"], +) diff --git a/buildstamp/buildstamp.go b/buildstamp/buildstamp.go new file mode 100644 index 0000000000..04c7523359 --- /dev/null +++ b/buildstamp/buildstamp.go @@ -0,0 +1,53 @@ +package buildstamp + +import "strings" + +var rawStampData string +var stampData map[string]string + +func init() { + if len(rawStampData) > 0 { + stampData = make(map[string]string) + for _, line := range strings.Split(rawStampData, "\n") { + line = strings.TrimSpace(line) + if len(line) == 0 || strings.HasPrefix(line, "#") { + continue + } + var key, value string + if space := strings.IndexAny(line, " \t"); space == -1 { + key = line + } else { + key = line[:space] + value = strings.TrimSpace(line[space+1:]) + } + stampData[key] = value + } + } +} + +func HaveStampData() bool { + return stampData != nil +} + +func RawStampData() string { + return rawStampData +} + +func GetStampKeys() []string { + if stampData == nil { + return nil + } + keys := make([]string, 0, len(stampData)) + for k, _ := range stampData { + keys = append(keys, k) + } + return keys +} + +func GetStampValue(key string) (value string, ok bool) { + if stampData == nil { + return "", false + } + value, ok = stampData[key] + return +} diff --git a/go/def.bzl b/go/def.bzl index 48637e51ca..de1fdf7e57 100644 --- a/go/def.bzl +++ b/go/def.bzl @@ -352,7 +352,7 @@ def _short_path(f): return f.path[len(prefix):] def emit_go_link_action(ctx, importmap, transitive_libs, cgo_deps, lib, - executable, x_defs={}): + executable, x_defs={}, stamp=False): """Sets up a symlink tree to libraries to link together.""" out_dir = executable.path + ".dir" out_depth = out_dir.count('/') + 1 @@ -396,6 +396,15 @@ def emit_go_link_action(ctx, importmap, transitive_libs, cgo_deps, lib, if x_defs: link_cmd += [" -X %s='%s' " % (k, v) for k,v in x_defs.items()] + if stamp: + stamp_cmd = ("LINKSTAMP=$(cat '%s' '%s')" % + (ctx.version_file.path, ctx.info_file.path)) + link_cmd += ['-X github.com/bazelbuild/rules_go/buildstamp.rawStampData="$LINKSTAMP"'] + stamp_deps = [ctx.version_file, ctx.info_file] + else: + stamp_cmd = "" + stamp_deps = [] + # workaround for a bug in ld(1) on Mac OS X. # http://lists.apple.com/archives/Darwin-dev/2006/Sep/msg00084.html # TODO(yugui) Remove this workaround once rules_go stops supporting XCode 7.2 @@ -416,6 +425,7 @@ def emit_go_link_action(ctx, importmap, transitive_libs, cgo_deps, lib, cmds += ["export PATH=$PATH:/usr/bin"] cmds += [ "export GOROOT=$(pwd)/" + ctx.file.go_tool.dirname + "/..", + stamp_cmd, "cd " + out_dir, ' '.join(link_cmd), "mv -f " + _go_importpath(ctx) + " " + ("../" * out_depth) + executable.path, @@ -424,7 +434,7 @@ def emit_go_link_action(ctx, importmap, transitive_libs, cgo_deps, lib, f = _emit_generate_params_action(cmds, ctx, lib.path + ".GoLinkFile.params") ctx.action( - inputs = (list(transitive_libs) + [lib] + list(cgo_deps) + + inputs = (list(transitive_libs) + [lib] + list(cgo_deps) + stamp_deps + ctx.files.toolchain + ctx.files._crosstool), outputs = [executable], executable = f, @@ -438,12 +448,13 @@ def go_binary_impl(ctx): lib_out = ctx.outputs.lib emit_go_link_action( - ctx, - transitive_libs=lib_result.transitive_go_library_object, - importmap=lib_result.transitive_go_importmap, - cgo_deps=lib_result.transitive_cgo_deps, - lib=lib_out, executable=executable, - x_defs=ctx.attr.x_defs) + ctx, + transitive_libs=lib_result.transitive_go_library_object, + importmap=lib_result.transitive_go_importmap, + cgo_deps=lib_result.transitive_cgo_deps, + lib=lib_out, executable=executable, + x_defs=ctx.attr.x_defs, + stamp=ctx.attr.stamp) runfiles = ctx.runfiles(collect_data = True, files = ctx.files.data)