Skip to content

Commit cf78385

Browse files
authored
Add env attribute to go_binary (#3428)
Using the new `RunEnvironmentInfo` provider in Bazel 5.3.0, `go_binary` targets can now specify environment variables to be set when they are executed with `bazel run`. Since `RunEnvironmentInfo` generalizes the `testing.TestEnvironment` provider, the existing usage is updated.
1 parent a58935a commit cf78385

File tree

8 files changed

+94
-22
lines changed

8 files changed

+94
-22
lines changed

.bazelci/presubmit.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
tasks:
33
ubuntu1804_bazel400:
44
platform: ubuntu1804
5-
bazel: 5.2.0 # test minimum supported version of bazel
5+
bazel: 5.3.0 # test minimum supported version of bazel
66
shell_commands:
77
- tests/core/cgo/generate_imported_dylib.sh
88
build_targets:

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ The Go rules are tested and supported on the following host platforms:
193193
Users have reported success on several other platforms, but the rules are
194194
only tested on those listed above.
195195

196-
Note: Since version v0.38.0, rules_go requires Bazel ≥ 5.2.0 to work.
196+
Note: Since version v0.38.0, rules_go requires Bazel ≥ 5.3.0 to work.
197197

198198
The ``master`` branch is only guaranteed to work with the latest version of Bazel.
199199

docs/go/core/rules.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ Rules
125125

126126
<pre>
127127
go_binary(<a href="#go_binary-name">name</a>, <a href="#go_binary-basename">basename</a>, <a href="#go_binary-cdeps">cdeps</a>, <a href="#go_binary-cgo">cgo</a>, <a href="#go_binary-clinkopts">clinkopts</a>, <a href="#go_binary-copts">copts</a>, <a href="#go_binary-cppopts">cppopts</a>, <a href="#go_binary-cxxopts">cxxopts</a>, <a href="#go_binary-data">data</a>, <a href="#go_binary-deps">deps</a>, <a href="#go_binary-embed">embed</a>,
128-
<a href="#go_binary-embedsrcs">embedsrcs</a>, <a href="#go_binary-gc_goopts">gc_goopts</a>, <a href="#go_binary-gc_linkopts">gc_linkopts</a>, <a href="#go_binary-goarch">goarch</a>, <a href="#go_binary-goos">goos</a>, <a href="#go_binary-gotags">gotags</a>, <a href="#go_binary-importpath">importpath</a>, <a href="#go_binary-linkmode">linkmode</a>, <a href="#go_binary-msan">msan</a>, <a href="#go_binary-out">out</a>,
129-
<a href="#go_binary-pure">pure</a>, <a href="#go_binary-race">race</a>, <a href="#go_binary-srcs">srcs</a>, <a href="#go_binary-static">static</a>, <a href="#go_binary-x_defs">x_defs</a>)
128+
<a href="#go_binary-embedsrcs">embedsrcs</a>, <a href="#go_binary-env">env</a>, <a href="#go_binary-gc_goopts">gc_goopts</a>, <a href="#go_binary-gc_linkopts">gc_linkopts</a>, <a href="#go_binary-goarch">goarch</a>, <a href="#go_binary-goos">goos</a>, <a href="#go_binary-gotags">gotags</a>, <a href="#go_binary-importpath">importpath</a>, <a href="#go_binary-linkmode">linkmode</a>, <a href="#go_binary-msan">msan</a>,
129+
<a href="#go_binary-out">out</a>, <a href="#go_binary-pure">pure</a>, <a href="#go_binary-race">race</a>, <a href="#go_binary-srcs">srcs</a>, <a href="#go_binary-static">static</a>, <a href="#go_binary-x_defs">x_defs</a>)
130130
</pre>
131131

132132
This builds an executable from a set of source files,
@@ -158,6 +158,7 @@ This builds an executable from a set of source files,
158158
| <a id="go_binary-deps"></a>deps | List of Go libraries this package imports directly. These may be <code>go_library</code> rules or compatible rules with the [GoLibrary] provider. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | [] |
159159
| <a id="go_binary-embed"></a>embed | List of Go libraries whose sources should be compiled together with this binary's sources. Labels listed here must name <code>go_library</code>, <code>go_proto_library</code>, or other compatible targets with the [GoLibrary] and [GoSource] providers. Embedded libraries must all have the same <code>importpath</code>, which must match the <code>importpath</code> for this <code>go_binary</code> if one is specified. At most one embedded library may have <code>cgo = True</code>, and the embedding binary may not also have <code>cgo = True</code>. See [Embedding] for more information. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | [] |
160160
| <a id="go_binary-embedsrcs"></a>embedsrcs | The list of files that may be embedded into the compiled package using <code>//go:embed</code> directives. All files must be in the same logical directory or a subdirectory as source files. All source files containing <code>//go:embed</code> directives must be in the same logical directory. It's okay to mix static and generated source files and static and generated embeddable files. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | [] |
161+
| <a id="go_binary-env"></a>env | Environment variables to set when the binary is executed with bazel run. The values (but not keys) are subject to [location expansion](https://docs.bazel.build/versions/main/skylark/macros.html) but not full [make variable expansion](https://docs.bazel.build/versions/main/be/make-variables.html). | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | {} |
161162
| <a id="go_binary-gc_goopts"></a>gc_goopts | List 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 strings | optional | [] |
162163
| <a id="go_binary-gc_linkopts"></a>gc_linkopts | List 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 strings | optional | [] |
163164
| <a id="go_binary-goarch"></a>goarch | Forces a binary to be cross-compiled for a specific architecture. It's usually better to control this on the command line with <code>--platforms</code>.<br><br> This disables cgo by default, since a cross-compiling C/C++ toolchain is rarely available. To force cgo, set <code>pure</code> = <code>off</code>.<br><br> See [Cross compilation] for more information. | String | optional | "auto" |

go/private/common.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def get_versioned_shared_lib_extension(path):
169169
# something like 1.2.3, or so.1.2, or dylib.1.2, or foo.1.2
170170
return ""
171171

172-
MINIMUM_BAZEL_VERSION = "5.2.0"
172+
MINIMUM_BAZEL_VERSION = "5.3.0"
173173

174174
def as_list(v):
175175
"""Returns a list, tuple, or depset as a list."""

go/private/rules/binary.bzl

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -122,36 +122,40 @@ def _go_binary_impl(ctx):
122122
executable = executable,
123123
)
124124

125+
providers = [
126+
library,
127+
source,
128+
archive,
129+
OutputGroupInfo(
130+
cgo_exports = archive.cgo_exports,
131+
compilation_outputs = [archive.data.file],
132+
),
133+
]
134+
125135
if go.mode.link in LINKMODES_EXECUTABLE:
136+
env = {}
137+
for k, v in ctx.attr.env.items():
138+
env[k] = ctx.expand_location(v, ctx.attr.data)
139+
providers.append(RunEnvironmentInfo(environment = env))
140+
126141
# The executable is automatically added to the runfiles.
127-
default_info = DefaultInfo(
142+
providers.append(DefaultInfo(
128143
files = depset([executable]),
129144
runfiles = runfiles,
130145
executable = executable,
131-
)
146+
))
132147
else:
133148
# Workaround for https://github.com/bazelbuild/bazel/issues/15043
134149
# As of Bazel 5.1.1, native rules do not pick up the "files" of a data
135150
# dependency's DefaultInfo, only the "data_runfiles". Since transitive
136151
# non-data dependents should not pick up the executable as a runfile
137152
# implicitly, the deprecated "default_runfiles" and "data_runfiles"
138153
# constructor parameters have to be used.
139-
default_info = DefaultInfo(
154+
providers.append(DefaultInfo(
140155
files = depset([executable]),
141156
default_runfiles = runfiles,
142157
data_runfiles = runfiles.merge(ctx.runfiles([executable])),
143-
)
144-
145-
providers = [
146-
library,
147-
source,
148-
archive,
149-
default_info,
150-
OutputGroupInfo(
151-
cgo_exports = archive.cgo_exports,
152-
compilation_outputs = [archive.data.file],
153-
),
154-
]
158+
))
155159

156160
# If the binary's linkmode is c-archive or c-shared, expose CcInfo
157161
if go.cgo_tools and go.mode.link in (LINKMODE_C_ARCHIVE, LINKMODE_C_SHARED):
@@ -234,6 +238,13 @@ _go_binary_kwargs = {
234238
generated source files and static and generated embeddable files.
235239
""",
236240
),
241+
"env": attr.string_dict(
242+
doc = """Environment variables to set when the binary is executed with bazel run.
243+
The values (but not keys) are subject to
244+
[location expansion](https://docs.bazel.build/versions/main/skylark/macros.html) but not full
245+
[make variable expansion](https://docs.bazel.build/versions/main/be/make-variables.html).
246+
""",
247+
),
237248
"importpath": attr.string(
238249
doc = """The import path of this binary. Binaries can't actually be imported, but this
239250
may be used by [go_path] and other tools to report the location of source

go/private/rules/test.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ def _go_test_impl(ctx):
163163
for k, v in ctx.attr.env.items():
164164
env[k] = ctx.expand_location(v, ctx.attr.data)
165165

166-
test_environment = testing.TestEnvironment(env, ctx.attr.env_inherit)
166+
run_environment_info = RunEnvironmentInfo(env, ctx.attr.env_inherit)
167167

168168
# Bazel only looks for coverage data if the test target has an
169169
# InstrumentedFilesProvider. If the provider is found and at least one
@@ -186,7 +186,7 @@ def _go_test_impl(ctx):
186186
dependency_attributes = ["data", "deps", "embed", "embedsrcs"],
187187
extensions = ["go"],
188188
),
189-
test_environment,
189+
run_environment_info,
190190
]
191191

192192
_go_test_kwargs = {

tests/core/go_test/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,8 @@ go_bazel_test(
248248
name = "env_inherit_test",
249249
srcs = ["env_inherit_test.go"],
250250
)
251+
252+
go_bazel_test(
253+
name = "binary_env_test",
254+
srcs = ["binary_env_test.go"],
255+
)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2023 The Bazel Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package binary_env_test
16+
17+
import (
18+
"testing"
19+
20+
"github.com/bazelbuild/rules_go/go/tools/bazel_testing"
21+
)
22+
23+
func TestMain(m *testing.M) {
24+
bazel_testing.TestMain(m, bazel_testing.Args{
25+
Main: `
26+
-- src/BUILD.bazel --
27+
load("@io_bazel_rules_go//go:def.bzl", "go_binary")
28+
go_binary(
29+
name = "main",
30+
srcs = ["env.go"],
31+
env = {"FOO": "bar"},
32+
)
33+
-- src/env.go --
34+
package main
35+
36+
import (
37+
"log"
38+
"os"
39+
)
40+
41+
func main() {
42+
v := os.Getenv("FOO")
43+
if v != "bar" {
44+
log.Fatalf("FOO was not equal to bar")
45+
}
46+
}
47+
`,
48+
})
49+
}
50+
51+
func TestBinaryEnv(t *testing.T) {
52+
if err := bazel_testing.RunBazel("run", "//src:main"); err != nil {
53+
t.Fatal(err)
54+
}
55+
}

0 commit comments

Comments
 (0)