Add GoContext (#1140)
* Add GoContext
This collects up all dependancies that were on the toolchain, but shoudld be in
target configuration (rather than host) and migrates them to a common
go_context_data dependancy.
It then adds a GoContext object, that holds the toolchain, build mode, standard
library and all mode specific attributes. go_context(ctx) will build one of
these and prepare to use it.
This simplifies a lot of the logic in the rules, and helps enforce the isolation
of action methods from ctx attributes.
* Review feedback plus documentation
diff --git a/BUILD.bazel b/BUILD.bazel
index fc061a4..7ed2446 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -2,6 +2,17 @@
load("@io_bazel_rules_go//go/private:tools/lines_sorted_test.bzl", "lines_sorted_test")
load("@io_bazel_rules_go//go/private:rules/info.bzl", "go_info")
load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_google_protobuf")
+load("@io_bazel_rules_go//go/private:context.bzl", "go_context_data")
+
+go_context_data(
+ name = "go_context_data",
+ strip = select({
+ "@io_bazel_rules_go//go/private:strip-always": "always",
+ "@io_bazel_rules_go//go/private:strip-sometimes": "sometimes",
+ "@io_bazel_rules_go//go/private:strip-never": "never",
+ }),
+ visibility = ["//visibility:public"],
+)
# gazelle:prefix github.com/bazelbuild/rules_go
diff --git a/examples/bindata/BUILD.bazel b/examples/bindata/BUILD.bazel
index f80df5a..eab89b2 100644
--- a/examples/bindata/BUILD.bazel
+++ b/examples/bindata/BUILD.bazel
@@ -1,5 +1,5 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
-load("@io_bazel_rules_go//examples/bindata:bindata.bzl", "bindata")
+load("@io_bazel_rules_go//extras:bindata.bzl", "bindata")
bindata(
name = "data",
diff --git a/extras/BUILD.bazel b/extras/BUILD.bazel
new file mode 100644
index 0000000..6f3d971
--- /dev/null
+++ b/extras/BUILD.bazel
@@ -0,0 +1,5 @@
+filegroup(
+ name = "all_rules",
+ srcs = glob(["*.bzl"]) + ["//go/private:all_rules"],
+ visibility = ["//visibility:public"],
+)
diff --git a/examples/bindata/bindata.bzl b/extras/bindata.bzl
similarity index 78%
rename from examples/bindata/bindata.bzl
rename to extras/bindata.bzl
index b937525..e2116ba 100644
--- a/examples/bindata/bindata.bzl
+++ b/extras/bindata.bzl
@@ -1,8 +1,8 @@
-load("@io_bazel_rules_go//go/private:go_repository.bzl", "go_repository")
-load("@io_bazel_rules_go//go/private:common.bzl", "declare_file")
+load("@io_bazel_rules_go//go:def.bzl", "go_context")
def _bindata_impl(ctx):
- out = declare_file(ctx, ext=".go")
+ go = go_context(ctx)
+ out = go.declare_file(go, ext=".go")
arguments = ctx.actions.args()
arguments.add([
"-o", out.path,
@@ -35,5 +35,7 @@
"compress": attr.bool(default=True),
"metadata": attr.bool(default=False),
"_bindata": attr.label(allow_files=True, single_file=True, default=Label("@com_github_jteeuwen_go_bindata//go-bindata:go-bindata")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
+ toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
diff --git a/go/private/tools/embed_data.bzl b/extras/embed_data.bzl
similarity index 81%
rename from go/private/tools/embed_data.bzl
rename to extras/embed_data.bzl
index e1a542b..da2c3ff 100644
--- a/go/private/tools/embed_data.bzl
+++ b/extras/embed_data.bzl
@@ -12,18 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@io_bazel_rules_go//go/private:common.bzl",
- "declare_file",
-)
-load("@io_bazel_rules_go//go/private:rules/helpers.bzl",
- "new_go_library",
- "library_to_source",
-)
-load("@io_bazel_rules_go//go/private:mode.bzl",
- "get_mode",
+load("@io_bazel_rules_go//go/private:context.bzl", #TODO: This ought to be def
+ "go_context",
)
def _go_embed_data_impl(ctx):
+ go = go_context(ctx)
if ctx.attr.src and ctx.attr.srcs:
fail("%s: src and srcs attributes cannot both be specified" % ctx.label)
if ctx.attr.src and ctx.attr.flatten:
@@ -43,7 +37,7 @@
if package == "":
fail("%s: must provide package attribute for go_embed_data rules in the repository root directory" % ctx.label)
- out = declare_file(ctx, ext=".go")
+ out = go.declare_file(go, ext=".go")
args.add([
"-workspace", ctx.workspace_name,
"-label", str(ctx.label),
@@ -57,9 +51,8 @@
args.add("-string")
args.add(srcs)
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
- library = new_go_library(ctx, srcs=srcs)
- source = library_to_source(ctx, ctx.attr, library, mode)
+ library = go.new_library(go, srcs=srcs)
+ source = go.library_to_source(go, ctx.attr, library, ctx.coverage_instrumented())
ctx.actions.run(
outputs = [out],
@@ -87,7 +80,7 @@
executable = True,
cfg = "host",
),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
diff --git a/go/core.rst b/go/core.rst
index a756f0c..52d3462 100644
--- a/go/core.rst
+++ b/go/core.rst
@@ -6,7 +6,7 @@
.. _gazelle: tools/gazelle/README.rst
.. _build constraints: http://golang.org/pkg/go/build/
.. _GoLibrary: providers.rst#GoLibrary
-.. _GoSourceList: providers.rst#GoSourceList
+.. _GoSource: providers.rst#GoSource
.. _GoArchive: providers.rst#GoArchive
.. _cgo: http://golang.org/cmd/cgo/
.. _"Make variable": https://docs.bazel.build/versions/master/be/make-variables.html
@@ -15,6 +15,8 @@
.. _cc library deps: https://docs.bazel.build/versions/master/be/c-cpp.html#cc_library.deps
.. _pure: modes.rst#pure
.. _static: modes.rst#static
+.. _goos: modes.rst#goos
+.. _goarch: modes.rst#goarch
.. _mode attributes: modes.rst#mode-attributes
.. role:: param(kbd)
@@ -58,7 +60,7 @@
^^^^^^^^^
* GoLibrary_
-* GoSourceList_
+* GoSource_
* GoArchive_
Attributes
@@ -94,7 +96,7 @@
| :param:`embed` | :type:`label_list` | :value:`None` |
+----------------------------+-----------------------------+---------------------------------------+
| List of Go libraries this test library directly. |
-| These may be go_library rules or compatible rules with the GoSourceList_ provider. |
+| These may be go_library rules or compatible rules with the GoLibrary_ provider. |
| These can provide both :param:`srcs` and :param:`deps` to this library. |
| See Embedding_ for more information about how and when to use this. |
+----------------------------+-----------------------------+---------------------------------------+
@@ -167,7 +169,8 @@
^^^^^^^^^
* GoLibrary_
-* GoSourceList_
+* GoSource_
+* GoArchive_
Attributes
^^^^^^^^^^
@@ -202,7 +205,7 @@
| :param:`embed` | :type:`label_list` | :value:`None` |
+----------------------------+-----------------------------+---------------------------------------+
| List of Go libraries this binary embeds directly. |
-| These may be go_library rules or compatible rules with the GoSourceList_ provider. |
+| These may be go_library rules or compatible rules with the GoLibrary_ provider. |
| These can provide both :param:`srcs` and :param:`deps` to this binary. |
| See Embedding_ for more information about how and when to use this. |
+----------------------------+-----------------------------+---------------------------------------+
@@ -223,6 +226,26 @@
| This is one of the `mode attributes`_ that controls whether to link in static_ mode. |
| It should be one of :value:`on`, :value:`off` or :value:`auto`. |
+----------------------------+-----------------------------+---------------------------------------+
+| :param:`goos` | :type:`string` | :value:`auto` |
++----------------------------+-----------------------------+---------------------------------------+
+| This is one of the `mode attributes`_ that controls which goos_ to compile and link for. |
+| |
+| If set to anything other than :value:`auto` this overrideds the default as set by the current |
+| target platform, and allows for single builds to make binaries for multiple architectures. |
+| |
+| Because this has no control over the cc toolchain, it does not work for cgo, so if this |
+| attribute is set then :param:`pure` must be set to :value:`on`. |
++----------------------------+-----------------------------+---------------------------------------+
+| :param:`goarch` | :type:`string` | :value:`auto` |
++----------------------------+-----------------------------+---------------------------------------+
+| This is one of the `mode attributes`_ that controls which goarch_ to compile and link for. |
+| |
+| If set to anything other than :value:`auto` this overrideds the default as set by the current |
+| target platform, and allows for single builds to make binaries for multiple architectures. |
+| |
+| Because this has no control over the cc toolchain, it does not work for cgo, so if this |
+| attribute is set then :param:`pure` must be set to :value:`on`. |
++----------------------------+-----------------------------+---------------------------------------+
| :param:`gc_goopts` | :type:`string_list` | :value:`[]` |
+----------------------------+-----------------------------+---------------------------------------+
| List of flags to add to the Go compilation command when using the gc compiler. |
@@ -314,7 +337,7 @@
| :param:`embed` | :type:`label_list` | :value:`None` |
+----------------------------+-----------------------------+---------------------------------------+
| List of Go libraries this test embeds directly. |
-| These may be go_library rules or compatible rules with the GoSourceList_ provider. |
+| These may be go_library rules or compatible rules with the GoLibrary_ provider. |
| These can provide both :param:`srcs` and :param:`deps` to this test. |
| See Embedding_ for more information about how and when to use this. |
+----------------------------+-----------------------------+---------------------------------------+
@@ -438,7 +461,8 @@
Providers
^^^^^^^^^
-* GoSourceList_
+* GoLibrary_
+* GoSource_
Attributes
^^^^^^^^^^
@@ -464,7 +488,7 @@
| :param:`embed` | :type:`label_list` | :value:`None` |
+----------------------------+-----------------------------+---------------------------------------+
| List of sources to directly embed in this list. |
-| These may be go_library rules or compatible rules with the GoSourceList_ provider. |
+| These may be go_library rules or compatible rules with the GoSource_ provider. |
| These can provide both :param:`srcs` and :param:`deps` to this library. |
| See Embedding_ for more information about how and when to use this. |
+----------------------------+-----------------------------+---------------------------------------+
diff --git a/go/def.bzl b/go/def.bzl
index 1ea70f1..8e3b628 100644
--- a/go/def.bzl
+++ b/go/def.bzl
@@ -12,6 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+load("@io_bazel_rules_go//go/private:context.bzl",
+ go_context = "go_context",
+)
load("@io_bazel_rules_go//go/private:go_repository.bzl",
"go_repository",
)
@@ -22,7 +25,7 @@
"go_rules_dependencies",
"go_register_toolchains",
)
-load("@io_bazel_rules_go//go/private:toolchain.bzl",
+load("@io_bazel_rules_go//go/private:sdk.bzl",
go_host_sdk = "go_host_sdk",
go_download_sdk = "go_download_sdk",
go_local_sdk = "go_local_sdk",
@@ -42,7 +45,7 @@
load("@io_bazel_rules_go//go/private:rules/source.bzl",
_go_source = "go_source",
)
-load("@io_bazel_rules_go//go/private:tools/embed_data.bzl",
+load("@io_bazel_rules_go//extras:embed_data.bzl",
"go_embed_data",
)
load("@io_bazel_rules_go//go/private:tools/gazelle.bzl",
diff --git a/go/modes.rst b/go/modes.rst
index e7f31ae..93ae810 100644
--- a/go/modes.rst
+++ b/go/modes.rst
@@ -63,7 +63,7 @@
the binary rule. The compiled libraries are distinct and multiple modes can be built in a single pass,
but are shared between leaves building in the same mode.
-Currently only static_ and pure_ can be specified as attributes.
+Currently only static_, pure_, goos_ and goarch_ can be specified as attributes.
Both of these can take one of the values "on", "off" or "auto", and "auto" is the default.
+--------------+-------------------------------------------------------------------------+
@@ -88,6 +88,8 @@
* link_
* debug_
* strip_
+* goos_
+* goarch_
Build modes
-----------
@@ -148,6 +150,16 @@
Causes debugging information to be stripped from the binaries.
+goos
+~~~~
+
+This controls which operating system to target.
+
+goarch
+~~~~~~
+
+This controls which architecture to target.
+
Using build modes
-----------------
@@ -204,3 +216,15 @@
.. code::
bazel test --features=race //...
+
+but in general it is strongly recommended instead to turn it on for specific tests.
+
+.. code::
+
+ go_test(
+ name = "go_default_test",
+ srcs = ["lib_test.go"],
+ embed = [":go_default_library"],
+ race = "on",
+ )
+
diff --git a/go/private/BUILD.bazel b/go/private/BUILD.bazel
index 044bfa5..123e6da 100644
--- a/go/private/BUILD.bazel
+++ b/go/private/BUILD.bazel
@@ -1,5 +1,3 @@
-load("@io_bazel_rules_go//go/private:go_toolchain.bzl", "go_toolchain_flags")
-
filegroup(
name = "all_rules",
srcs = glob(["**/*.bzl"]),
@@ -21,12 +19,3 @@
values = {"strip": "never"},
)
-go_toolchain_flags(
- name = "go_toolchain_flags",
- strip = select({
- "@io_bazel_rules_go//go/private:strip-always": "always",
- "@io_bazel_rules_go//go/private:strip-sometimes": "sometimes",
- "@io_bazel_rules_go//go/private:strip-never": "never",
- }),
- visibility = ["//visibility:public"],
-)
diff --git a/go/private/actions/action.bzl b/go/private/actions/action.bzl
deleted file mode 100644
index 846d4c3..0000000
--- a/go/private/actions/action.bzl
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2014 The Bazel Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-def add_go_env(args, stdlib, mode):
- args.add([
- "-go", stdlib.go,
- "-root_file", stdlib.root_file,
- "-goos", stdlib.goos,
- "-goarch", stdlib.goarch,
- "-cgo=" + ("0" if mode.pure else "1"),
- ])
-
-def bootstrap_action(ctx, go_toolchain, mode, inputs, outputs, mnemonic, arguments):
- stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, mode)
- ctx.actions.run_shell(
- inputs = inputs + stdlib.files,
- outputs = outputs,
- mnemonic = mnemonic,
- command = "export GOROOT=$(pwd)/{} && {} {}".format(stdlib.root_file.dirname, stdlib.go.path, " ".join(arguments)),
- )
diff --git a/go/private/actions/archive.bzl b/go/private/actions/archive.bzl
index 47db97d..560fc49 100644
--- a/go/private/actions/archive.bzl
+++ b/go/private/actions/archive.bzl
@@ -13,71 +13,60 @@
# limitations under the License.
load("@io_bazel_rules_go//go/private:common.bzl",
- "declare_file",
"split_srcs",
"sets",
)
load("@io_bazel_rules_go//go/private:mode.bzl",
"mode_string",
)
-load("@io_bazel_rules_go//go/private:rules/helpers.bzl",
- "get_archive",
-)
load("@io_bazel_rules_go//go/private:providers.bzl",
"GoArchive",
"GoArchiveData",
+ "get_archive",
)
-def emit_archive(ctx, go_toolchain, source=None):
+def emit_archive(go, source=None):
"""See go/toolchains.rst#archive for full documentation."""
if source == None: fail("source is a required parameter")
cover_vars = []
- if ctx.configuration.coverage_enabled:
- source, cover_vars = go_toolchain.actions.cover(ctx, go_toolchain, source)
+ if go.cover:
+ source, cover_vars = go.cover(go, source)
split = split_srcs(source.srcs)
compilepath = source.library.importpath if source.library.importpath else source.library.name
lib_name = compilepath + ".a"
- out_lib = declare_file(ctx, path=lib_name, mode=source.mode)
+ out_lib = go.declare_file(go, path=lib_name)
searchpath = out_lib.path[:-len(lib_name)]
extra_objects = []
for src in split.asm:
- obj = declare_file(ctx, path=src.basename[:-2], ext=".o", mode=source.mode)
- go_toolchain.actions.asm(ctx, go_toolchain, mode=source.mode, source=src, hdrs=split.headers, out_obj=obj)
- extra_objects.append(obj)
+ extra_objects.append(go.asm(go, source=src, hdrs=split.headers))
direct = [get_archive(dep) for dep in source.deps]
runfiles = source.runfiles
for a in direct:
runfiles = runfiles.merge(a.runfiles)
- if a.source.mode != source.mode: fail("Archive mode does not match {} is {} expected {}".format(a.data.source.library.label, mode_string(a.source.mode), mode_string(source.mode)))
+ if a.source.mode != go.mode: fail("Archive mode does not match {} is {} expected {}".format(a.data.source.library.label, mode_string(a.source.mode), mode_string(go.mode)))
if len(extra_objects) == 0 and source.cgo_archive == None:
- go_toolchain.actions.compile(ctx,
- go_toolchain = go_toolchain,
+ go.compile(go,
sources = split.go,
importpath = compilepath,
archives = direct,
- mode = source.mode,
out_lib = out_lib,
gc_goopts = source.gc_goopts,
)
else:
- partial_lib = declare_file(ctx, path="partial", ext=".a", mode=source.mode)
- go_toolchain.actions.compile(ctx,
- go_toolchain = go_toolchain,
+ partial_lib = go.declare_file(go, path="partial", ext=".a")
+ go.compile(go,
sources = split.go,
importpath = compilepath,
archives = direct,
- mode = source.mode,
out_lib = partial_lib,
gc_goopts = source.gc_goopts,
)
- go_toolchain.actions.pack(ctx,
- go_toolchain = go_toolchain,
- mode = source.mode,
+ go.pack(go,
in_lib = partial_lib,
out_lib = out_lib,
objects = extra_objects,
diff --git a/go/private/actions/asm.bzl b/go/private/actions/asm.bzl
index 51083d1..1984874 100644
--- a/go/private/actions/asm.bzl
+++ b/go/private/actions/asm.bzl
@@ -12,39 +12,32 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@io_bazel_rules_go//go/private:actions/action.bzl",
- "add_go_env",
-)
load("@io_bazel_rules_go//go/private:common.bzl",
"to_set",
"sets",
)
-def emit_asm(ctx, go_toolchain,
+def emit_asm(go,
source = None,
- hdrs = [],
- out_obj = None,
- mode = None):
+ hdrs = []):
"""See go/toolchains.rst#asm for full documentation."""
if source == None: fail("source is a required parameter")
- if out_obj == None: fail("out_obj is a required parameter")
- if mode == None: fail("mode is a required parameter")
- stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, mode)
- includes = to_set([stdlib.root_file.dirname + "/pkg/include"])
+ out_obj = go.declare_file(go, path=source.basename[:-2], ext=".o")
+ includes = to_set([go.stdlib.root_file.dirname + "/pkg/include"])
includes = sets.union(includes, [f.dirname for f in hdrs])
- inputs = hdrs + stdlib.files + [source]
+ inputs = hdrs + go.stdlib.files + [source]
- asm_args = ctx.actions.args()
- add_go_env(asm_args, stdlib, mode)
+ asm_args = go.args(go)
asm_args.add(["-o", out_obj, "-trimpath", "."])
asm_args.add(includes, before_each="-I")
asm_args.add(source.path)
- ctx.actions.run(
+ go.actions.run(
inputs = inputs,
outputs = [out_obj],
mnemonic = "GoAsmCompile",
- executable = go_toolchain.tools.asm,
+ executable = go.toolchain.tools.asm,
arguments = [asm_args],
)
+ return out_obj
diff --git a/go/private/actions/binary.bzl b/go/private/actions/binary.bzl
index 86e6eea..f6dd1da 100644
--- a/go/private/actions/binary.bzl
+++ b/go/private/actions/binary.bzl
@@ -12,28 +12,28 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@io_bazel_rules_go//go/private:common.bzl",
- "declare_file",
-)
-
-def emit_binary(ctx, go_toolchain,
+def emit_binary(go,
name="",
source = None,
gc_linkopts = [],
x_defs = {},
- wrap = None):
+ linkstamp=None,
+ version_file=None,
+ info_file=None):
"""See go/toolchains.rst#binary for full documentation."""
if name == "": fail("name is a required parameter")
- archive = go_toolchain.actions.archive(ctx, go_toolchain, source)
- executable = declare_file(ctx, name=name, ext=go_toolchain.data.extension, mode=source.mode)
- go_toolchain.actions.link(ctx,
- go_toolchain = go_toolchain,
+ archive = go.archive(go, source)
+ executable = go.declare_file(go, name=name, ext=go.exe_extension)
+ go.link(go,
archive=archive,
executable=executable,
gc_linkopts=gc_linkopts,
x_defs=x_defs,
+ linkstamp=linkstamp,
+ version_file=version_file,
+ info_file=info_file,
)
return archive, executable
diff --git a/go/private/actions/compile.bzl b/go/private/actions/compile.bzl
index b1a07f8..c20d3b4 100644
--- a/go/private/actions/compile.bzl
+++ b/go/private/actions/compile.bzl
@@ -15,10 +15,6 @@
load("@io_bazel_rules_go//go/private:common.bzl",
"sets",
)
-load("@io_bazel_rules_go//go/private:actions/action.bzl",
- "add_go_env",
- "bootstrap_action",
-)
def _importpath(l):
return [v.data.importpath for v in l]
@@ -26,37 +22,35 @@
def _searchpath(l):
return [v.data.searchpath for v in l]
-def emit_compile(ctx, go_toolchain,
+def emit_compile(go,
sources = None,
importpath = "",
archives = [],
- mode = None,
out_lib = None,
gc_goopts = []):
"""See go/toolchains.rst#compile for full documentation."""
if sources == None: fail("sources is a required parameter")
if out_lib == None: fail("out_lib is a required parameter")
- if mode == None: fail("mode is a required parameter")
# Add in any mode specific behaviours
- if mode.race:
+ if go.mode.race:
gc_goopts = gc_goopts + ["-race"]
- if mode.msan:
+ if go.mode.msan:
gc_goopts = gc_goopts + ["-msan"]
- gc_goopts = [ctx.expand_make_variables("gc_goopts", f, {}) for f in gc_goopts]
- inputs = sets.union(sources, [go_toolchain.data.package_list])
+ #TODO: Check if we really need this expand make variables in here
+ #TODO: If we really do then it needs to be moved all the way back out to the rule
+ gc_goopts = [go._ctx.expand_make_variables("gc_goopts", f, {}) for f in gc_goopts]
+ inputs = sets.union(sources, [go.package_list])
go_sources = [s.path for s in sources if not s.basename.startswith("_cgo")]
cgo_sources = [s.path for s in sources if s.basename.startswith("_cgo")]
inputs = sets.union(inputs, [archive.data.file for archive in archives])
- stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, mode)
- inputs = sets.union(inputs, stdlib.files)
+ inputs = sets.union(inputs, go.stdlib.files)
- args = ctx.actions.args()
- add_go_env(args, stdlib, mode)
- args.add(["-package_list", go_toolchain.data.package_list])
+ args = go.args(go)
+ args.add(["-package_list", go.package_list])
args.add(go_sources, before_each="-src")
args.add(archives, before_each="-dep", map_fn=_importpath)
args.add(archives, before_each="-I", map_fn=_searchpath)
@@ -65,23 +59,22 @@
if importpath:
args.add(["-p", importpath])
args.add(gc_goopts)
- args.add(go_toolchain.flags.compile)
- if mode.debug:
+ args.add(go.toolchain.flags.compile)
+ if go.mode.debug:
args.add(["-N", "-l"])
args.add(cgo_sources)
- ctx.actions.run(
+ go.actions.run(
inputs = inputs,
outputs = [out_lib],
mnemonic = "GoCompile",
- executable = go_toolchain.tools.compile,
+ executable = go.toolchain.tools.compile,
arguments = [args],
)
-def bootstrap_compile(ctx, go_toolchain,
+def bootstrap_compile(go,
sources = None,
importpath = "",
archives = [],
- mode = None,
out_lib = None,
gc_goopts = []):
"""See go/toolchains.rst#compile for full documentation."""
@@ -89,14 +82,13 @@
if sources == None: fail("sources is a required parameter")
if out_lib == None: fail("out_lib is a required parameter")
if archives: fail("compile does not accept deps in bootstrap mode")
- if mode == None: fail("mode is a required parameter")
args = ["tool", "compile", "-o", out_lib.path]
args.extend(gc_goopts)
args.extend([s.path for s in sources])
- bootstrap_action(ctx, go_toolchain, mode,
- inputs = sources,
+ go.actions.run_shell(
+ inputs = sources + go.stdlib.files,
outputs = [out_lib],
mnemonic = "GoCompile",
- arguments = args,
+ command = "export GOROOT=$(pwd)/{} && {} {}".format(go.stdlib.root_file.dirname, go.stdlib.go.path, " ".join(args)),
)
diff --git a/go/private/actions/cover.bzl b/go/private/actions/cover.bzl
index 380f4a7..2129e11 100644
--- a/go/private/actions/cover.bzl
+++ b/go/private/actions/cover.bzl
@@ -12,26 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@io_bazel_rules_go//go/private:actions/action.bzl",
- "add_go_env",
-)
load("@io_bazel_rules_go//go/private:providers.bzl",
"GoSource",
)
load("@io_bazel_rules_go//go/private:common.bzl",
- "declare_file",
"structs",
)
-def emit_cover(ctx, go_toolchain, source):
+def emit_cover(go, source):
"""See go/toolchains.rst#cover for full documentation."""
if source == None: fail("source is a required parameter")
if not source.cover:
return source, []
- stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, source.mode)
-
covered = []
cover_vars = []
for src in source.srcs:
@@ -40,16 +34,15 @@
continue
cover_var = "Cover_" + src.basename[:-3].replace("-", "_").replace(".", "_")
cover_vars.append("{}={}={}".format(cover_var, src.short_path, source.library.importpath))
- out = declare_file(ctx, path=cover_var, ext='.cover.go')
+ out = go.declare_file(go, path=cover_var, ext='.cover.go')
covered.append(out)
- args = ctx.actions.args()
- add_go_env(args, stdlib, source.mode)
+ args = go.args(go)
args.add(["--", "--mode=set", "-var=%s" % cover_var, "-o", out, src])
- ctx.actions.run(
- inputs = [src] + stdlib.files,
+ go.actions.run(
+ inputs = [src] + go.stdlib.files,
outputs = [out],
mnemonic = "GoCover",
- executable = go_toolchain.tools.cover,
+ executable = go.toolchain.tools.cover,
arguments = [args],
)
members = structs.to_dict(source)
diff --git a/go/private/actions/link.bzl b/go/private/actions/link.bzl
index da7af06..90caa51 100644
--- a/go/private/actions/link.bzl
+++ b/go/private/actions/link.bzl
@@ -19,31 +19,29 @@
load("@io_bazel_rules_go//go/private:mode.bzl",
"LINKMODE_NORMAL",
)
-load("@io_bazel_rules_go//go/private:actions/action.bzl",
- "add_go_env",
- "bootstrap_action",
-)
-def emit_link(ctx, go_toolchain,
+def emit_link(go,
archive = None,
executable = None,
gc_linkopts = [],
- x_defs = {}):
+ x_defs = {},
+ linkstamp=None,
+ version_file=None,
+ info_file=None):
"""See go/toolchains.rst#link for full documentation."""
if archive == None: fail("archive is a required parameter")
if executable == None: fail("executable is a required parameter")
- stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, archive.source.mode)
-
- config_strip = len(ctx.configuration.bin_dir.path) + 1
+ #TODO: There has to be a better way to work out the rpath
+ config_strip = len(go._ctx.configuration.bin_dir.path) + 1
pkg_depth = executable.dirname[config_strip:].count('/') + 1
ld = None
extldflags = []
- if stdlib.cgo_tools:
- ld = stdlib.cgo_tools.compiler_executable
- extldflags.extend(stdlib.cgo_tools.options)
+ if go.stdlib.cgo_tools:
+ ld = go.stdlib.cgo_tools.compiler_executable
+ extldflags.extend(go.stdlib.cgo_tools.options)
extldflags.extend(["-Wl,-rpath,$ORIGIN/" + ("../" * pkg_depth)])
gc_linkopts, extldflags = _extract_extldflags(gc_linkopts, extldflags)
@@ -81,7 +79,7 @@
else:
link_opts.extend(["-X", "%s=%s" % (k, v)])
- link_opts.extend(go_toolchain.flags.link)
+ link_opts.extend(go.toolchain.flags.link)
if archive.source.mode.strip:
link_opts.extend(["-w"])
@@ -91,38 +89,40 @@
"-extldflags", " ".join(extldflags),
])
link_opts.append(archive.data.file.path)
- link_args = ctx.actions.args()
- add_go_env(link_args, stdlib, archive.source.mode)
+ link_args = go.args(go)
# Stamping support
stamp_inputs = []
- if stamp_x_defs or ctx.attr.linkstamp:
- stamp_inputs = [ctx.info_file, ctx.version_file]
+ if stamp_x_defs or linkstamp:
+ stamp_inputs = [info_file, version_file]
link_args.add(stamp_inputs, before_each="-stamp")
for k,v in stamp_x_defs.items():
link_args.add(["-X", "%s=%s" % (k, v)])
# linkstamp option support: read workspace status files,
# converting "KEY value" lines to "-X $linkstamp.KEY=value" arguments
# to the go linker.
- if ctx.attr.linkstamp:
- link_args.add(["-linkstamp", ctx.attr.linkstamp])
+ if linkstamp:
+ link_args.add(["-linkstamp", linkstamp])
link_args.add("--")
link_args.add(link_opts)
- ctx.actions.run(
+ go.actions.run(
inputs = sets.union(archive.libs, archive.cgo_deps,
- go_toolchain.data.crosstool, stamp_inputs, stdlib.files),
+ go.crosstool, stamp_inputs, go.stdlib.files),
outputs = [executable],
mnemonic = "GoLink",
- executable = go_toolchain.tools.link,
+ executable = go.toolchain.tools.link,
arguments = [link_args],
)
-def bootstrap_link(ctx, go_toolchain,
+def bootstrap_link(go,
archive = None,
executable = None,
gc_linkopts = [],
- x_defs = {}):
+ x_defs = {},
+ linkstamp=None,
+ version_file=None,
+ info_file=None):
"""See go/toolchains.rst#link for full documentation."""
if archive == None: fail("archive is a required parameter")
@@ -134,11 +134,11 @@
args = ["tool", "link", "-o", executable.path]
args.extend(gc_linkopts)
args.append(archive.data.file.path)
- bootstrap_action(ctx, go_toolchain, archive.source.mode,
- inputs = inputs,
+ go.actions.run_shell(
+ inputs = inputs + go.stdlib.files,
outputs = [executable],
- mnemonic = "GoCompile",
- arguments = args,
+ mnemonic = "GoLink",
+ command = "export GOROOT=$(pwd)/{} && {} {}".format(go.stdlib.root_file.dirname, go.stdlib.go.path, " ".join(args)),
)
def _extract_extldflags(gc_linkopts, extldflags):
diff --git a/go/private/actions/pack.bzl b/go/private/actions/pack.bzl
index a4f1340..1c9d904 100644
--- a/go/private/actions/pack.bzl
+++ b/go/private/actions/pack.bzl
@@ -12,27 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@io_bazel_rules_go//go/private:actions/action.bzl",
- "add_go_env",
-)
-
-def emit_pack(ctx, go_toolchain,
+def emit_pack(go,
in_lib = None,
out_lib = None,
objects = [],
- archive = None,
- mode = None):
+ archive = None):
"""See go/toolchains.rst#pack for full documentation."""
if in_lib == None: fail("in_lib is a required parameter")
if out_lib == None: fail("out_lib is a required parameter")
- if mode == None: fail("mode is a required parameter")
- stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, mode)
- inputs = [in_lib] + stdlib.files
+ inputs = [in_lib] + go.stdlib.files
- arguments = ctx.actions.args()
- add_go_env(arguments, stdlib, mode)
+ arguments = go.args(go)
arguments.add([
"-in", in_lib,
"-out", out_lib,
@@ -44,10 +36,10 @@
inputs.append(archive)
arguments.add(["-arc", archive])
- ctx.actions.run(
+ go.actions.run(
inputs = inputs,
outputs = [out_lib],
mnemonic = "GoPack",
- executable = go_toolchain.tools.pack,
+ executable = go.toolchain.tools.pack,
arguments = [arguments],
)
diff --git a/go/private/common.bzl b/go/private/common.bzl
index 25babb8..0b21c05 100644
--- a/go/private/common.bzl
+++ b/go/private/common.bzl
@@ -20,9 +20,6 @@
load("//go/private:skylib/lib/structs.bzl", "structs")
load("@io_bazel_rules_go//go/private:mode.bzl", "mode_string")
-DEFAULT_LIB = "go_default_library"
-VENDOR_PREFIX = "/vendor/"
-
go_exts = [
".go",
]
@@ -98,32 +95,6 @@
return source.go + source.headers + source.asm + source.c
-def go_importpath(ctx):
- """Returns the expected importpath of the go_library being built.
-
- Args:
- ctx: The skylark Context
-
- Returns:
- Go importpath of the library
- """
- path = getattr(ctx.attr, "importpath", None)
- if path != "":
- return path
- prefix = getattr(ctx.attr, "_go_prefix", None)
- path = prefix.go_prefix if prefix else ""
- if path.endswith("/"):
- path = path[:-1]
- if ctx.label.package:
- path += "/" + ctx.label.package
- if ctx.label.name != DEFAULT_LIB and not path.endswith(ctx.label.name):
- path += "/" + ctx.label.name
- if path.rfind(VENDOR_PREFIX) != -1:
- path = path[len(VENDOR_PREFIX) + path.rfind(VENDOR_PREFIX):]
- if path[0] == "/":
- path = path[1:]
- return path
-
def env_execute(ctx, arguments, environment = {}, **kwargs):
"""env_executes a command in a repository context. It prepends "env -i"
to "arguments" before calling "ctx.execute".
@@ -146,13 +117,3 @@
fail("Do not pass a depset to to_set")
return depset(v)
-def declare_file(ctx, path="", ext="", mode=None, name = ""):
- filename = ""
- if mode:
- filename += mode_string(mode) + "/"
- filename += name if name else ctx.label.name
- if path:
- filename += "~/" + path
- if ext:
- filename += ext
- return ctx.actions.declare_file(filename)
\ No newline at end of file
diff --git a/go/private/context.bzl b/go/private/context.bzl
new file mode 100644
index 0000000..e9acbe9
--- /dev/null
+++ b/go/private/context.bzl
@@ -0,0 +1,218 @@
+# Copyright 2017 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("@io_bazel_rules_go//go/private:providers.bzl",
+ "GoLibrary",
+ "GoSource",
+ "GoAspectProviders",
+ "GoStdLib",
+ "get_source",
+)
+load("@io_bazel_rules_go//go/platform:list.bzl",
+ "GOOS_GOARCH",
+)
+load("@io_bazel_rules_go//go/private:mode.bzl",
+ "get_mode",
+ "mode_string",
+)
+load("@io_bazel_rules_go//go/private:common.bzl",
+ "structs",
+)
+
+GoContext = provider()
+
+def executable_extension(ctx):
+ extension = ""
+ if ctx.os.name.startswith('windows'):
+ extension = ".exe"
+ return extension
+
+def _goos_to_extension(goos):
+ if goos == "windows":
+ return ".exe"
+ return ""
+
+def _declare_file(go, path="", ext="", name = ""):
+ filename = mode_string(go.mode) + "/"
+ filename += name if name else go._ctx.label.name
+ if path:
+ filename += "~/" + path
+ if ext:
+ filename += ext
+ return go.actions.declare_file(filename)
+
+def _new_args(go):
+ args = go.actions.args()
+ args.add([
+ "-go", go.stdlib.go,
+ "-root_file", go.stdlib.root_file,
+ "-goos", go.mode.goos,
+ "-goarch", go.mode.goarch,
+ "-cgo=" + ("0" if go.mode.pure else "1"),
+ ])
+ return args
+
+def _new_library(go, resolver=None, importable=True, **kwargs):
+ return GoLibrary(
+ name = go._ctx.label.name,
+ label = go._ctx.label,
+ importpath = go._inferredpath if importable else None, # The canonical import path for this library
+ exportpath = go._inferredpath, # The export source path for this library
+ resolve = resolver,
+ **kwargs
+ )
+
+def _merge_embed(source, embed):
+ s = get_source(embed)
+ source["srcs"] = s.srcs + source["srcs"]
+ source["cover"] = source["cover"] + s.cover
+ source["deps"] = source["deps"] + s.deps
+ source["gc_goopts"] = source["gc_goopts"] + s.gc_goopts
+ source["runfiles"] = source["runfiles"].merge(s.runfiles)
+ source["cgo_deps"] = source["cgo_deps"] + s.cgo_deps
+ source["cgo_exports"] = source["cgo_exports"] + s.cgo_exports
+ if s.cgo_archive:
+ if source["cgo_archive"]:
+ fail("multiple libraries with cgo_archive embedded")
+ source["cgo_archive"] = s.cgo_archive
+
+def _library_to_source(go, attr, library, coverage_instrumented):
+ attr_srcs = [f for t in getattr(attr, "srcs", []) for f in t.files]
+ generated_srcs = getattr(library, "srcs", [])
+ source = {
+ "library" : library,
+ "mode" : go.mode,
+ "srcs" : generated_srcs + attr_srcs,
+ "cover" : [],
+ "deps" : getattr(attr, "deps", []),
+ "gc_goopts" : getattr(attr, "gc_goopts", []),
+ "runfiles" : go._ctx.runfiles(collect_data = True),
+ "cgo_archive" : None,
+ "cgo_deps" : [],
+ "cgo_exports" : [],
+ }
+ if coverage_instrumented and not attr.testonly:
+ source["cover"] = attr_srcs
+ for e in getattr(attr, "embed", []):
+ _merge_embed(source, e)
+ if library.resolve:
+ library.resolve(go, attr, source, _merge_embed)
+ return GoSource(**source)
+
+
+def _infer_importpath(ctx):
+ DEFAULT_LIB = "go_default_library"
+ VENDOR_PREFIX = "/vendor/"
+ path = getattr(ctx.attr, "importpath", None)
+ if path != "":
+ return path
+ prefix = getattr(ctx.attr, "_go_prefix", None)
+ path = prefix.go_prefix if prefix else ""
+ if path.endswith("/"):
+ path = path[:-1]
+ if ctx.label.package:
+ path += "/" + ctx.label.package
+ if ctx.label.name != DEFAULT_LIB and not path.endswith(ctx.label.name):
+ path += "/" + ctx.label.name
+ if path.rfind(VENDOR_PREFIX) != -1:
+ path = path[len(VENDOR_PREFIX) + path.rfind(VENDOR_PREFIX):]
+ if path[0] == "/":
+ path = path[1:]
+ return path
+
+
+def go_context(ctx, attr=None):
+ if "@io_bazel_rules_go//go:toolchain" in ctx.toolchains:
+ toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
+ elif "@io_bazel_rules_go//go:bootstrap_toolchain" in ctx.toolchains:
+ toolchain = ctx.toolchains["@io_bazel_rules_go//go:bootstrap_toolchain"]
+ else:
+ fail('Rule {} does not have the go toolchain available\nAdd toolchains = ["@io_bazel_rules_go//go:toolchain"] to the rule definition.'.format(ctx.label))
+
+ if not attr:
+ attr = ctx.attr
+
+ context_data = attr._go_context_data
+ mode = get_mode(ctx, toolchain, context_data)
+
+ stdlib = None
+ for check in [s[GoStdLib] for s in context_data.stdlib_all]:
+ if (check.goos == mode.goos and
+ check.goarch == mode.goarch and
+ check.race == mode.race and
+ check.pure == mode.pure):
+ if stdlib:
+ fail("Multiple matching standard library for "+mode_string(mode))
+ stdlib = check
+ if not stdlib:
+ fail("No matching standard library for "+mode_string(mode))
+
+ return GoContext(
+ # Fields
+ toolchain = toolchain,
+ mode = mode,
+ stdlib = stdlib,
+ actions = ctx.actions,
+ exe_extension = _goos_to_extension(mode.goos),
+ crosstool = context_data.crosstool,
+ package_list = context_data.package_list,
+ # Action generators
+ archive = toolchain.actions.archive,
+ asm = toolchain.actions.asm,
+ binary = toolchain.actions.binary,
+ compile = toolchain.actions.compile,
+ cover = toolchain.actions.cover if ctx.configuration.coverage_enabled else None,
+ link = toolchain.actions.link,
+ pack = toolchain.actions.pack,
+
+ # Helpers
+ args = _new_args,
+ new_library = _new_library,
+ library_to_source = _library_to_source,
+ declare_file = _declare_file,
+
+ # Private
+ _ctx = ctx, # TODO: All uses of this should be removed
+ _inferredpath = _infer_importpath(ctx), # TODO: remove when go_prefix goes away
+ )
+
+def _stdlib_all():
+ stdlibs = []
+ for goos, goarch in GOOS_GOARCH:
+ stdlibs.extend([
+ Label("@go_stdlib_{}_{}_cgo".format(goos, goarch)),
+ Label("@go_stdlib_{}_{}_pure".format(goos, goarch)),
+ Label("@go_stdlib_{}_{}_cgo_race".format(goos, goarch)),
+ Label("@go_stdlib_{}_{}_pure_race".format(goos, goarch)),
+ ])
+ return stdlibs
+
+def _go_context_data(ctx):
+ return struct(
+ strip = ctx.attr.strip,
+ stdlib_all = ctx.attr._stdlib_all,
+ crosstool = ctx.files._crosstool,
+ package_list = ctx.file._package_list,
+ )
+
+go_context_data = rule(
+ _go_context_data,
+ attrs = {
+ "strip": attr.string(mandatory=True),
+ # Hidden internal attributes
+ "_stdlib_all": attr.label_list(default = _stdlib_all()),
+ "_crosstool": attr.label(default=Label("//tools/defaults:crosstool")),
+ "_package_list": attr.label(allow_files = True, single_file = True, default="@go_sdk//:packages.txt"),
+ },
+)
diff --git a/go/private/go_repository.bzl b/go/private/go_repository.bzl
index 80daba0..53dd8b7 100644
--- a/go/private/go_repository.bzl
+++ b/go/private/go_repository.bzl
@@ -13,7 +13,7 @@
# limitations under the License.
load("@io_bazel_rules_go//go/private:common.bzl", "env_execute")
-load("@io_bazel_rules_go//go/private:toolchain.bzl", "executable_extension")
+load("@io_bazel_rules_go//go/private:context.bzl", "executable_extension")
def _go_repository_impl(ctx):
if ctx.attr.urls:
diff --git a/go/private/go_toolchain.bzl b/go/private/go_toolchain.bzl
index 0dfb55a..722f02f 100644
--- a/go/private/go_toolchain.bzl
+++ b/go/private/go_toolchain.bzl
@@ -21,24 +21,7 @@
load("@io_bazel_rules_go//go/private:actions/cover.bzl", "emit_cover")
load("@io_bazel_rules_go//go/private:actions/link.bzl", "emit_link", "bootstrap_link")
load("@io_bazel_rules_go//go/private:actions/pack.bzl", "emit_pack")
-load("@io_bazel_rules_go//go/private:providers.bzl", "GoStdLib")
-load("@io_bazel_rules_go//go/platform:list.bzl", "GOOS_GOARCH")
-load("@io_bazel_rules_go//go/private:mode.bzl", "mode_string")
-def _get_stdlib(ctx, go_toolchain, mode):
- for stdlib in go_toolchain.stdlib.all:
- stdlib = stdlib[GoStdLib]
- if (stdlib.goos == mode.goos and
- stdlib.goarch == mode.goarch and
- stdlib.race == mode.race and
- stdlib.pure == mode.pure):
- return stdlib
- fail("No matching standard library for "+mode_string(mode))
-
-def _goos_to_extension(goos):
- if goos == "windows":
- return ".exe"
- return ""
def _go_toolchain_impl(ctx):
return [platform_common.ToolchainInfo(
@@ -47,10 +30,6 @@
bootstrap = ctx.attr.bootstrap,
default_goos = ctx.attr.goos,
default_goarch = ctx.attr.goarch,
- stdlib = struct(
- all = ctx.attr._stdlib_all,
- get = _get_stdlib,
- ),
actions = struct(
archive = emit_archive,
asm = emit_asm,
@@ -74,24 +53,8 @@
link = ctx.attr.link_flags,
link_cgo = ctx.attr.cgo_link_flags,
),
- data = struct(
- crosstool = ctx.files._crosstool,
- package_list = ctx.file._package_list,
- extension = _goos_to_extension(ctx.attr.goos),
- ),
)]
-def _stdlib_all():
- stdlibs = []
- for goos, goarch in GOOS_GOARCH:
- stdlibs.extend([
- Label("@go_stdlib_{}_{}_cgo".format(goos, goarch)),
- Label("@go_stdlib_{}_{}_pure".format(goos, goarch)),
- Label("@go_stdlib_{}_{}_cgo_race".format(goos, goarch)),
- Label("@go_stdlib_{}_{}_pure_race".format(goos, goarch)),
- ])
- return stdlibs
-
def _asm(bootstrap):
if bootstrap:
return None
@@ -146,10 +109,6 @@
"_cgo": attr.label(allow_files = True, single_file = True, executable = True, cfg = "host", default = _cgo),
"_test_generator": attr.label(allow_files = True, single_file = True, executable = True, cfg = "host", default = _test_generator),
"_cover": attr.label(allow_files = True, single_file = True, executable = True, cfg = "host", default = _cover),
- # Hidden internal attributes
- "_stdlib_all": attr.label_list(default = _stdlib_all()),
- "_crosstool": attr.label(default=Label("//tools/defaults:crosstool")),
- "_package_list": attr.label(allow_files = True, single_file = True, default="@go_sdk//:packages.txt"),
},
)
@@ -208,15 +167,3 @@
target_compatible_with = target_constraints,
toolchain = ":"+impl_name,
)
-
-def _go_toolchain_flags(ctx):
- return struct(
- strip = ctx.attr.strip,
- )
-
-go_toolchain_flags = rule(
- _go_toolchain_flags,
- attrs = {
- "strip": attr.string(mandatory=True),
- },
-)
diff --git a/go/private/mode.bzl b/go/private/mode.bzl
index 17a9c2b..b883fd9 100644
--- a/go/private/mode.bzl
+++ b/go/private/mode.bzl
@@ -49,13 +49,8 @@
fail("Invalid value {}".format(v))
fail("_ternary failed to produce a final result from {}".format(values))
-def get_mode(ctx, toolchain_flags):
- if "@io_bazel_rules_go//go:toolchain" in ctx.toolchains:
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
- else:
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:bootstrap_toolchain"]
-
- # We always have to use the pure stdlib in cross compilation mode
+def get_mode(ctx, go_toolchain, go_context_data):
+ # We always have to use the pure stdlib in cross compilation mode
force_pure = "on" if go_toolchain.cross_compile else "auto"
force_race = "off" if go_toolchain.bootstrap else "auto"
@@ -83,8 +78,8 @@
race = False
debug = ctx.var["COMPILATION_MODE"] == "debug"
strip_mode = "sometimes"
- if toolchain_flags:
- strip_mode = toolchain_flags.strip
+ if go_context_data:
+ strip_mode = go_context_data.strip
strip = True
if strip_mode == "always":
strip = True
diff --git a/go/private/providers.bzl b/go/private/providers.bzl
index 15811ce..dca4836 100644
--- a/go/private/providers.bzl
+++ b/go/private/providers.bzl
@@ -47,3 +47,20 @@
GoAspectProviders = provider()
GoPath = provider()
GoStdLib = provider()
+
+def new_aspect_provider(source = None, archive = None):
+ return GoAspectProviders(
+ source = source,
+ archive = archive,
+ )
+
+def get_source(dep):
+ if GoAspectProviders in dep:
+ return dep[GoAspectProviders].source
+ return dep[GoSource]
+
+def get_archive(dep):
+ if GoAspectProviders in dep:
+ return dep[GoAspectProviders].archive
+ return dep[GoArchive]
+
diff --git a/go/private/repository_tools.bzl b/go/private/repository_tools.bzl
index b01fa23..47ceee0 100644
--- a/go/private/repository_tools.bzl
+++ b/go/private/repository_tools.bzl
@@ -13,7 +13,7 @@
# limitations under the License.
load("@io_bazel_rules_go//go/private:go_repository.bzl", "go_repository", "env_execute")
-load("@io_bazel_rules_go//go/private:toolchain.bzl", "executable_extension")
+load("@io_bazel_rules_go//go/private:context.bzl", "executable_extension")
_GO_REPOSITORY_TOOLS_BUILD_FILE = """
package(default_visibility = ["//visibility:public"])
diff --git a/go/private/rules/aspect.bzl b/go/private/rules/aspect.bzl
index 21dfbd4..ab277aa 100644
--- a/go/private/rules/aspect.bzl
+++ b/go/private/rules/aspect.bzl
@@ -12,15 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+load("@io_bazel_rules_go//go/private:context.bzl",
+ "go_context",
+)
load("@io_bazel_rules_go//go/private:common.bzl",
"split_srcs",
"to_set",
"sets",
)
-load("@io_bazel_rules_go//go/private:rules/helpers.bzl",
- "library_to_source",
- "new_aspect_provider",
-)
load("@io_bazel_rules_go//go/private:mode.bzl",
"mode_string",
)
@@ -29,21 +28,19 @@
"GoArchive",
"GoArchiveData",
"GoSource",
+ "new_aspect_provider",
)
load("@io_bazel_rules_go//go/platform:list.bzl",
"GOOS",
"GOARCH",
)
-load("@io_bazel_rules_go//go/private:mode.bzl",
- "get_mode",
-)
def _go_archive_aspect_impl(target, ctx):
- mode = get_mode(ctx, ctx.rule.attr._go_toolchain_flags)
+ go = go_context(ctx, ctx.rule.attr)
source = target[GoSource] if GoSource in target else None
archive = target[GoArchive] if GoArchive in target else None
- if source and source.mode == mode:
+ if source and source.mode == go.mode:
# The base layer already built the right mode for us
return [new_aspect_provider(
source = source,
@@ -54,12 +51,9 @@
return []
# We have a library and we need to compile it in a new mode
library = target[GoLibrary]
- source = library_to_source(ctx, ctx.rule.attr, library, mode)
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
- archive = go_toolchain.actions.archive(ctx,
- go_toolchain = go_toolchain,
- source = source,
- )
+ source = go.library_to_source(go, ctx.rule.attr, library, ctx.coverage_instrumented())
+ if archive:
+ archive = go.archive(go, source = source)
return [new_aspect_provider(
source = source,
archive = archive,
diff --git a/go/private/rules/binary.bzl b/go/private/rules/binary.bzl
index d17f538..8aae244 100644
--- a/go/private/rules/binary.bzl
+++ b/go/private/rules/binary.bzl
@@ -12,6 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+load("@io_bazel_rules_go//go/private:context.bzl",
+ "go_context",
+)
load("@io_bazel_rules_go//go/private:common.bzl",
"go_filetype",
)
@@ -24,35 +27,27 @@
load("@io_bazel_rules_go//go/private:providers.bzl",
"GoLibrary",
)
-load("@io_bazel_rules_go//go/private:rules/helpers.bzl",
- "new_go_library",
- "library_to_source",
-)
load("@io_bazel_rules_go//go/platform:list.bzl",
"GOOS",
"GOARCH",
)
-load("@io_bazel_rules_go//go/private:mode.bzl",
- "get_mode",
-)
def _go_binary_impl(ctx):
"""go_binary_impl emits actions for compiling and linking a go executable."""
- if "@io_bazel_rules_go//go:toolchain" in ctx.toolchains:
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
- else:
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:bootstrap_toolchain"]
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
- library = new_go_library(ctx, importable=False)
- source = library_to_source(ctx, ctx.attr, library, mode)
+ go = go_context(ctx)
+ library = go.new_library(go, importable=False)
+ source = go.library_to_source(go, ctx.attr, library, ctx.coverage_instrumented())
name = ctx.attr.basename
if not name:
name = ctx.label.name
- archive, executable = go_toolchain.actions.binary(ctx, go_toolchain,
+ archive, executable = go.binary(go,
name = name,
source = source,
gc_linkopts = gc_linkopts(ctx),
x_defs = ctx.attr.x_defs,
+ linkstamp=ctx.attr.linkstamp,
+ version_file=ctx.version_file,
+ info_file=ctx.info_file,
)
return [
library, source, archive,
@@ -86,7 +81,7 @@
"linkstamp": attr.string(),
"x_defs": attr.string_dict(),
"_go_prefix": attr.label(default = go_prefix_default),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
executable = True,
toolchains = ["@io_bazel_rules_go//go:toolchain"],
@@ -110,7 +105,7 @@
"linkstamp": attr.string(),
"x_defs": attr.string_dict(),
"_go_prefix": attr.label(default = go_prefix_default),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
executable = True,
toolchains = ["@io_bazel_rules_go//go:bootstrap_toolchain"],
diff --git a/go/private/rules/cgo.bzl b/go/private/rules/cgo.bzl
index b81213e..5e95713 100644
--- a/go/private/rules/cgo.bzl
+++ b/go/private/rules/cgo.bzl
@@ -12,27 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+load("@io_bazel_rules_go//go/private:context.bzl",
+ "go_context",
+)
load("@io_bazel_rules_go//go/private:common.bzl",
- "declare_file",
"split_srcs",
"join_srcs",
"pkg_dir",
"sets",
"to_set",
)
-load("@io_bazel_rules_go//go/private:mode.bzl",
- "get_mode",
-)
load("@io_bazel_rules_go//go/private:providers.bzl",
"GoLibrary",
)
-load("@io_bazel_rules_go//go/private:actions/action.bzl",
- "add_go_env",
-)
-load("@io_bazel_rules_go//go/private:rules/helpers.bzl",
- "new_go_library",
- "library_to_source",
-)
_CgoCodegen = provider()
@@ -61,23 +53,20 @@
fail("cc_library did not produce any files")
def _cgo_codegen_impl(ctx):
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
- stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, mode)
- if not stdlib.cgo_tools:
+ go = go_context(ctx)
+ if not go.stdlib.cgo_tools:
fail("Go toolchain does not support cgo")
linkopts = ctx.attr.linkopts[:]
- copts = stdlib.cgo_tools.c_options + ctx.attr.copts
+ copts = go.stdlib.cgo_tools.c_options + ctx.attr.copts
deps = depset([], order="topological")
- cgo_export_h = declare_file(ctx, path="_cgo_export.h")
- cgo_export_c = declare_file(ctx, path="_cgo_export.c")
- cgo_main = declare_file(ctx, path="_cgo_main.c")
- cgo_types = declare_file(ctx, path="_cgo_gotypes.go")
+ cgo_export_h = go.declare_file(go, path="_cgo_export.h")
+ cgo_export_c = go.declare_file(go, path="_cgo_export.c")
+ cgo_main = go.declare_file(go, path="_cgo_main.c")
+ cgo_types = go.declare_file(go, path="_cgo_gotypes.go")
out_dir = cgo_main.dirname
- cc = stdlib.cgo_tools.compiler_executable
- args = ctx.actions.args()
- add_go_env(args, stdlib, mode)
+ cc = go.stdlib.cgo_tools.compiler_executable
+ args = go.args(go)
args.add(["-cc", str(cc), "-objdir", out_dir])
c_outs = [cgo_export_h, cgo_export_c]
@@ -88,23 +77,23 @@
copts.extend(['-iquote', src.dirname])
for src in source.go:
mangled_stem, src_ext = _mangle(src)
- gen_file = declare_file(ctx, path=mangled_stem + ".cgo1."+src_ext)
- gen_c_file = declare_file(ctx, path=mangled_stem + ".cgo2.c")
+ gen_file = go.declare_file(go, path=mangled_stem + ".cgo1."+src_ext)
+ gen_c_file = go.declare_file(go, path=mangled_stem + ".cgo2.c")
go_outs.append(gen_file)
c_outs.append(gen_c_file)
args.add(["-src", gen_file.path + "=" + src.path])
for src in source.asm:
mangled_stem, src_ext = _mangle(src)
- gen_file = declare_file(ctx, path=mangled_stem + ".cgo1."+src_ext)
+ gen_file = go.declare_file(go, path=mangled_stem + ".cgo1."+src_ext)
go_outs.append(gen_file)
args.add(["-src", gen_file.path + "=" + src.path])
for src in source.c:
mangled_stem, src_ext = _mangle(src)
- gen_file = declare_file(ctx, path=mangled_stem + ".cgo1."+src_ext)
+ gen_file = go.declare_file(go, path=mangled_stem + ".cgo1."+src_ext)
c_outs.append(gen_file)
args.add(["-src", gen_file.path + "=" + src.path])
- inputs = sets.union(ctx.files.srcs, go_toolchain.data.crosstool, stdlib.files,
+ inputs = sets.union(ctx.files.srcs, go.crosstool, go.stdlib.files,
*[d.cc.transitive_headers for d in ctx.attr.deps])
deps = sets.union(deps, *[d.cc.libs for d in ctx.attr.deps])
runfiles = ctx.runfiles(collect_data = True)
@@ -133,7 +122,7 @@
outputs = c_outs + go_outs + [cgo_main],
mnemonic = "CGoCodeGen",
progress_message = "CGoCodeGen %s" % ctx.label,
- executable = go_toolchain.tools.cgo,
+ executable = go.toolchain.tools.cgo,
arguments = [args],
env = {
"CGO_LDFLAGS": " ".join(linkopts),
@@ -169,18 +158,15 @@
),
"copts": attr.string_list(),
"linkopts": attr.string_list(),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
def _cgo_import_impl(ctx):
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
- stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, mode)
- out = declare_file(ctx, ext=".go")
- args = ctx.actions.args()
- add_go_env(args, stdlib, mode)
+ go = go_context(ctx)
+ out = go.declare_file(go, ext=".go")
+ args = go.args(go)
args.add([
"-dynout", out,
"-dynimport", ctx.file.cgo_o,
@@ -190,9 +176,9 @@
inputs = [
ctx.file.cgo_o,
ctx.files.sample_go_srcs[0],
- ] + stdlib.files,
+ ] + go.stdlib.files,
outputs = [out],
- executable = go_toolchain.tools.cgo,
+ executable = go.toolchain.tools.cgo,
arguments = [args],
mnemonic = "CGoImportGen",
)
@@ -208,7 +194,7 @@
single_file = True,
),
"sample_go_srcs": attr.label_list(allow_files = True),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
@@ -227,7 +213,7 @@
def _not_pure(ctx, mode):
return not mode.pure
-def _cgo_library_to_source(ctx, attr, source):
+def _cgo_library_to_source(go, attr, source, merge):
library = source["library"]
if source["mode"].pure:
source["srcs"] = library.input_go_srcs + source["srcs"]
@@ -240,11 +226,12 @@
def _cgo_collect_info_impl(ctx):
+ go = go_context(ctx)
codegen = ctx.attr.codegen[_CgoCodegen]
runfiles = ctx.runfiles(collect_data = True)
runfiles = runfiles.merge(ctx.attr.codegen.data_runfiles)
- library = new_go_library(ctx,
+ library = go.new_library(go,
resolver=_cgo_library_to_source,
input_go_srcs = ctx.files.input_go_srcs,
gen_go_srcs = ctx.files.gen_go_srcs,
@@ -252,8 +239,7 @@
cgo_exports = ctx.attr.codegen[_CgoCodegen].exports,
cgo_archive = _select_archive(ctx.files.lib),
)
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
- source = library_to_source(ctx, ctx.attr, library, mode)
+ source = go.library_to_source(go, ctx.attr, library, ctx.coverage_instrumented())
return [
source, library,
@@ -267,7 +253,7 @@
"input_go_srcs": attr.label_list(mandatory = True, allow_files = [".go"]),
"gen_go_srcs": attr.label_list(mandatory = True, allow_files = [".go"]),
"lib": attr.label(mandatory = True, providers = ["cc"]),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
diff --git a/go/private/rules/helpers.bzl b/go/private/rules/helpers.bzl
deleted file mode 100644
index 7ac54d9..0000000
--- a/go/private/rules/helpers.bzl
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2017 The Bazel Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-load("@io_bazel_rules_go//go/private:common.bzl",
- "go_importpath",
- "sets",
-)
-load("@io_bazel_rules_go//go/private:providers.bzl",
- "GoLibrary",
- "GoSource",
- "GoArchive",
- "GoAspectProviders",
-)
-
-def new_go_library(ctx, resolver=None, importable=True, **kwargs):
- inferredpath = go_importpath(ctx)
- return GoLibrary(
- name = ctx.label.name,
- label = ctx.label,
- importpath = inferredpath if importable else None, # The canonical import path for this library
- exportpath = inferredpath, # The export source path for this library
- resolve = resolver,
- **kwargs
- )
-
-def new_aspect_provider(source = None, archive = None):
- return GoAspectProviders(
- source = source,
- archive = archive,
- )
-
-def get_source(dep):
- if GoAspectProviders in dep:
- return dep[GoAspectProviders].source
- return dep[GoSource]
-
-def get_archive(dep):
- if GoAspectProviders in dep:
- return dep[GoAspectProviders].archive
- return dep[GoArchive]
-
-def merge_embed(source, embed):
- s = get_source(embed)
- source["srcs"] = s.srcs + source["srcs"]
- source["cover"] = source["cover"] + s.cover
- source["deps"] = source["deps"] + s.deps
- source["gc_goopts"] = source["gc_goopts"] + s.gc_goopts
- source["runfiles"] = source["runfiles"].merge(s.runfiles)
- source["cgo_deps"] = source["cgo_deps"] + s.cgo_deps
- source["cgo_exports"] = source["cgo_exports"] + s.cgo_exports
- if s.cgo_archive:
- if source["cgo_archive"]:
- fail("multiple libraries with cgo_archive embedded")
- source["cgo_archive"] = s.cgo_archive
-
-def library_to_source(ctx, attr, library, mode):
- attr_srcs = [f for t in getattr(attr, "srcs", []) for f in t.files]
- generated_srcs = getattr(library, "srcs", [])
- source = {
- "library" : library,
- "mode" : mode,
- "srcs" : generated_srcs + attr_srcs,
- "cover" : [],
- "deps" : getattr(attr, "deps", []),
- "gc_goopts" : getattr(attr, "gc_goopts", []),
- "runfiles" : ctx.runfiles(collect_data = True),
- "cgo_archive" : None,
- "cgo_deps" : [],
- "cgo_exports" : [],
- }
- if ctx.coverage_instrumented() and not attr.testonly:
- source["cover"] = attr_srcs
- for e in getattr(attr, "embed", []):
- merge_embed(source, e)
- if library.resolve:
- library.resolve(ctx, attr, source)
- return GoSource(**source)
-
diff --git a/go/private/rules/info.bzl b/go/private/rules/info.bzl
index 7a3da0b..78f8b40 100644
--- a/go/private/rules/info.bzl
+++ b/go/private/rules/info.bzl
@@ -12,23 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@io_bazel_rules_go//go/private:mode.bzl",
- "get_mode",
-)
-load("@io_bazel_rules_go//go/private:actions/action.bzl",
- "add_go_env",
-)
-load("@io_bazel_rules_go//go/private:common.bzl",
- "declare_file",
+load("@io_bazel_rules_go//go/private:context.bzl",
+ "go_context",
)
def _go_info_script_impl(ctx):
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
- stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, mode)
- out = declare_file(ctx, ext=".bash")
- args = ctx.actions.args()
- add_go_env(args, stdlib, mode)
+ go = go_context(ctx)
+ out = go.declare_file(go, ext=".bash")
+ args = go.args(go)
args.add(["-script", "-out", out])
ctx.actions.run(
inputs = [],
@@ -52,7 +43,7 @@
executable = True,
cfg = "host",
default="@io_bazel_rules_go//go/tools/builders:info"),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
diff --git a/go/private/rules/library.bzl b/go/private/rules/library.bzl
index e9656b9..520e0b2 100644
--- a/go/private/rules/library.bzl
+++ b/go/private/rules/library.bzl
@@ -12,27 +12,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+load("@io_bazel_rules_go//go/private:context.bzl",
+ "go_context",
+)
load("@io_bazel_rules_go//go/private:providers.bzl",
"GoLibrary",
)
-load("@io_bazel_rules_go//go/private:rules/helpers.bzl",
- "new_go_library",
- "library_to_source",
-)
load("@io_bazel_rules_go//go/private:rules/prefix.bzl",
"go_prefix_default",
)
-load("@io_bazel_rules_go//go/private:mode.bzl",
- "get_mode",
-)
def _go_library_impl(ctx):
"""Implements the go_library() rule."""
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
- library = new_go_library(ctx)
- source = library_to_source(ctx, ctx.attr, library, mode)
- archive = go_toolchain.actions.archive(ctx, go_toolchain, source)
+ go = go_context(ctx)
+ library = go.new_library(go)
+ source = go.library_to_source(go, ctx.attr, library, ctx.coverage_instrumented())
+ archive = go.archive(go, source)
return [
library, source, archive,
@@ -54,7 +49,7 @@
"embed": attr.label_list(providers = [GoLibrary]),
"gc_goopts": attr.string_list(),
"_go_prefix": attr.label(default = go_prefix_default),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
diff --git a/go/private/rules/source.bzl b/go/private/rules/source.bzl
index 443560b..50b3ab8 100644
--- a/go/private/rules/source.bzl
+++ b/go/private/rules/source.bzl
@@ -20,22 +20,18 @@
# depend on a globally unique target that has a "go_prefix" transitive
# info provider.
+load("@io_bazel_rules_go//go/private:context.bzl",
+ "go_context",
+)
load("@io_bazel_rules_go//go/private:providers.bzl",
"GoLibrary",
)
-load("@io_bazel_rules_go//go/private:rules/helpers.bzl",
- "new_go_library",
- "library_to_source",
-)
-load("@io_bazel_rules_go//go/private:mode.bzl",
- "get_mode",
-)
def _go_source_impl(ctx):
"""Implements the go_source() rule."""
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
- library = new_go_library(ctx)
- source = library_to_source(ctx, ctx.attr, library, mode)
+ go = go_context(ctx)
+ library = go.new_library(go)
+ source = go.library_to_source(go, ctx.attr, library, ctx.coverage_instrumented())
return [library, source]
go_source = rule(
@@ -46,7 +42,7 @@
"deps": attr.label_list(providers = [GoLibrary]),
"embed": attr.label_list(providers = [GoLibrary]),
"gc_goopts": attr.string_list(),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
diff --git a/go/private/rules/test.bzl b/go/private/rules/test.bzl
index 1a41825..5f01964 100644
--- a/go/private/rules/test.bzl
+++ b/go/private/rules/test.bzl
@@ -12,11 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+load("@io_bazel_rules_go//go/private:context.bzl",
+ "go_context",
+)
load("@io_bazel_rules_go//go/private:common.bzl",
"go_filetype",
"split_srcs",
"pkg_dir",
- "declare_file",
)
load("@io_bazel_rules_go//go/private:rules/prefix.bzl",
"go_prefix_default",
@@ -24,23 +26,13 @@
load("@io_bazel_rules_go//go/private:rules/binary.bzl", "gc_linkopts")
load("@io_bazel_rules_go//go/private:providers.bzl",
"GoLibrary",
-)
-load("@io_bazel_rules_go//go/private:rules/helpers.bzl",
"get_archive",
- "new_go_library",
- "library_to_source",
-)
-load("@io_bazel_rules_go//go/private:actions/action.bzl",
- "add_go_env",
)
load("@io_bazel_rules_go//go/private:rules/aspect.bzl",
"go_archive_aspect",
)
-load("@io_bazel_rules_go//go/private:mode.bzl",
- "get_mode",
-)
-def _testmain_library_to_source(ctx, attr, source):
+def _testmain_library_to_source(go, attr, source, merge):
source["deps"] = source["deps"] + [attr.library]
def _go_test_impl(ctx):
@@ -49,10 +41,8 @@
It emits an action to run the test generator, and then compiles the
test into a binary."""
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
+ go = go_context(ctx)
archive = get_archive(ctx.attr.library)
- stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, archive.source.mode)
# now generate the main function
if ctx.attr.rundir:
@@ -63,9 +53,8 @@
else:
run_dir = pkg_dir(ctx.label.workspace_root, ctx.label.package)
- main_go = declare_file(ctx, "testmain.go")
- arguments = ctx.actions.args()
- add_go_env(arguments, stdlib, archive.source.mode)
+ main_go = go.declare_file(go, "testmain.go")
+ arguments = go.args(go)
arguments.add([
'--package',
archive.source.library.importpath,
@@ -82,7 +71,7 @@
inputs = go_srcs,
outputs = [main_go],
mnemonic = "GoTestGenTest",
- executable = go_toolchain.tools.test_generator,
+ executable = go.toolchain.tools.test_generator,
arguments = [arguments],
env = {
"RUNDIR" : ctx.label.package,
@@ -90,17 +79,20 @@
)
# Now compile the test binary itself
- test_library = new_go_library(ctx,
+ test_library = go.new_library(go,
resolver=_testmain_library_to_source,
srcs=[main_go],
importable=False,
)
- test_source = library_to_source(ctx, ctx.attr, test_library, mode)
- test_archive, executable = go_toolchain.actions.binary(ctx, go_toolchain,
+ test_source = go.library_to_source(go, ctx.attr, test_library, False)
+ test_archive, executable = go.binary(go,
name = ctx.label.name,
source = test_source,
gc_linkopts = gc_linkopts(ctx),
x_defs=ctx.attr.x_defs,
+ linkstamp=ctx.attr.linkstamp,
+ version_file=ctx.version_file,
+ info_file=ctx.info_file,
)
runfiles = ctx.runfiles(files = [executable])
@@ -135,7 +127,7 @@
"rundir": attr.string(),
"x_defs": attr.string_dict(),
"_go_prefix": attr.label(default = go_prefix_default),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
executable = True,
test = True,
diff --git a/go/private/toolchain.bzl b/go/private/sdk.bzl
similarity index 96%
rename from go/private/toolchain.bzl
rename to go/private/sdk.bzl
index 2e74f02..62cee75 100644
--- a/go/private/toolchain.bzl
+++ b/go/private/sdk.bzl
@@ -13,12 +13,7 @@
# limitations under the License.
load("@io_bazel_rules_go//go/private:common.bzl", "env_execute")
-
-def executable_extension(ctx):
- extension = ""
- if ctx.os.name.startswith('windows'):
- extension = ".exe"
- return extension
+load("@io_bazel_rules_go//go/private:context.bzl", "executable_extension")
def _go_host_sdk_impl(ctx):
path = _detect_host_sdk(ctx)
diff --git a/go/private/tools/gazelle.bzl b/go/private/tools/gazelle.bzl
index c20edb3..b6c39a4 100644
--- a/go/private/tools/gazelle.bzl
+++ b/go/private/tools/gazelle.bzl
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@io_bazel_rules_go//go/private:common.bzl",
- "declare_file",
+load("@io_bazel_rules_go//go/private:context.bzl",
+ "go_context",
)
_script_content = """
@@ -26,6 +26,7 @@
def _gazelle_script_impl(ctx):
# TODO(jayconrod): add a fix to Gazelle to replace invocations of this rule
# with the new one in @bazel_gazelle. Once in place, fail here.
+ go = go_context(ctx)
prefix = ctx.attr.prefix if ctx.attr.prefix else ctx.attr._go_prefix.go_prefix
args = [ctx.attr.command]
args += [
@@ -38,7 +39,7 @@
args += ["-build_tags", ",".join(ctx.attr.build_tags)]
args += ctx.attr.args
script_content = _script_content.format(gazelle=ctx.file._gazelle.short_path, args=" ".join(args))
- script_file = declare_file(ctx, ext=".bash")
+ script_file = go.declare_file(go, ext=".bash")
ctx.actions.write(output=script_file, is_executable=True, content=script_content)
return struct(
files = depset([script_file]),
diff --git a/go/private/tools/path.bzl b/go/private/tools/path.bzl
index 646e7b1..311ce23 100644
--- a/go/private/tools/path.bzl
+++ b/go/private/tools/path.bzl
@@ -12,16 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@io_bazel_rules_go//go/private:providers.bzl", "GoLibrary", "GoPath")
-load("@io_bazel_rules_go//go/private:common.bzl", "declare_file")
-load("@io_bazel_rules_go//go/private:rules/helpers.bzl", "get_archive")
+load("@io_bazel_rules_go//go/private:context.bzl",
+ "go_context",
+)
+load("@io_bazel_rules_go//go/private:providers.bzl",
+ "GoLibrary",
+ "GoPath",
+ "get_archive",
+)
-
-def _tag(ctx, path, outputs):
+def _tag(go, path, outputs):
"""this generates a existance tag file for dependencies, and returns the path to the tag file"""
- tag = declare_file(ctx, path=path+".tag")
+ tag = go.declare_file(go, path=path+".tag")
path, _, _ = tag.short_path.rpartition("/")
- ctx.actions.write(tag, content="")
+ go.actions.write(tag, content="")
outputs.append(tag)
return path
@@ -30,7 +34,7 @@
EXPERIMENTAL: the go_path rule is still very experimental
Please do not rely on it for production use, but feel free to use it and file issues
""")
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
+ go = go_context(ctx)
#TODO: non specific mode?
# First gather all the library rules
golibs = depset()
@@ -64,7 +68,7 @@
# If we see the same path twice, it's a fatal error
fail("Duplicate path {}".format(outpath))
seen_paths[outpath] = True
- out = declare_file(ctx, path=outpath)
+ out = go.declare_file(go, path=outpath)
package_files += [out]
outputs += [out]
if ctx.attr.mode == "copy":
@@ -81,10 +85,10 @@
fail("Invalid go path mode '{}'".format(ctx.attr.mode))
packages += [struct(
golib = golib,
- dir = _tag(ctx, prefix, outputs),
+ dir = _tag(go, prefix, outputs),
files = package_files,
)]
- gopath = _tag(ctx, "", outputs)
+ gopath = _tag(go, "", outputs)
return [
DefaultInfo(
files = depset(outputs),
@@ -101,6 +105,7 @@
attrs = {
"deps": attr.label_list(providers=[GoLibrary]),
"mode": attr.string(default="copy", values=["link", "copy"]),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
diff --git a/go/private/tools/vet.bzl b/go/private/tools/vet.bzl
index 7170c68..783fb78 100644
--- a/go/private/tools/vet.bzl
+++ b/go/private/tools/vet.bzl
@@ -12,26 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+load("@io_bazel_rules_go//go/private:context.bzl",
+ "go_context",
+)
load("@io_bazel_rules_go//go/private:providers.bzl", "GoPath")
-load("@io_bazel_rules_go//go/private:mode.bzl",
- "get_mode",
-)
-load("@io_bazel_rules_go//go/private:common.bzl",
- "declare_file",
-)
-
def _go_vet_generate_impl(ctx):
print("""
EXPERIMENTAL: the go_vet_test rule is still very experimental
Please do not rely on it for production use, but feel free to use it and file issues
""")
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
- stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, mode)
- script_file = declare_file(ctx, ext=".bash")
+ go = go_context(ctx)
+ script_file = go.declare_file(go, ext=".bash")
gopath = []
- files = ctx.files.data + stdlib.files
+ files = ctx.files.data + go.stdlib.files
gopath = []
packages = []
for data in ctx.attr.data:
@@ -42,7 +36,7 @@
export GOPATH="{gopath}"
{go} tool vet {packages}
""".format(
- go=stdlib.go.short_path,
+ go=go.stdlib.go.short_path,
gopath=":".join(['$(pwd)/{})'.format(entry) for entry in gopath]),
packages=" ".join(packages),
))
@@ -55,7 +49,7 @@
_go_vet_generate_impl,
attrs = {
"data": attr.label_list(providers=[GoPath], cfg = "data"),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
diff --git a/go/toolchain/toolchains.bzl b/go/toolchain/toolchains.bzl
index 6e6f9d6..3530792 100644
--- a/go/toolchain/toolchains.bzl
+++ b/go/toolchain/toolchains.bzl
@@ -1,7 +1,7 @@
load("//go/private:go_toolchain.bzl",
"go_toolchain",
)
-load("//go/private:toolchain.bzl",
+load("//go/private:sdk.bzl",
"go_download_sdk",
"go_host_sdk",
)
diff --git a/go/toolchains.rst b/go/toolchains.rst
index 8c11f9f..fe7a2ad 100644
--- a/go/toolchains.rst
+++ b/go/toolchains.rst
@@ -12,6 +12,9 @@
.. _register_toolchains: https://docs.bazel.build/versions/master/skylark/lib/globals.html#register_toolchains
.. _compilation modes: modes.rst#compilation-modes
.. _go assembly: https://golang.org/doc/asm
+.. _GoLibrary: providers.rst#GoLibrary
+.. _GoSource: providers.rst#GoSource
+.. _GoArchive: providers.rst#GoArchive
.. role:: param(kbd)
.. role:: type(emphasis)
@@ -28,7 +31,7 @@
Design
------
-The Go toolchain consists of two main layers, `the sdk`_ and `the toolchain`_.
+The Go toolchain consists of three main layers, `the sdk`_ and `the toolchain`_ and `the context`_.
The SDK
~~~~~~~
@@ -56,6 +59,9 @@
The toolchain
~~~~~~~~~~~~~
+This a wrapper over the sdk that provides enough extras to match, target and work on a specific
+platforms. It should be considered an opaqute type, you only ever use it through `the context`_.
+
Declaration
^^^^^^^^^^^
@@ -97,6 +103,13 @@
It is important to note that you **must** also register the boostrap toolchain for any other
toolchain that you register, otherwise the tools for that toolchain cannot be built.
+
+
+The context
+~~~~~~~~~~~
+
+This is the type you use if you are writing custom rules that need
+
Use
^^^
@@ -109,6 +122,7 @@
_my_rule_impl,
attrs = {
...
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
@@ -227,6 +241,7 @@
"@io_bazel_rules_go//go/toolchain:1.8.3_darwin_amd64-bootstrap",
)
+
API
---
@@ -386,54 +401,139 @@
| should apply when using this toolchain. |
+--------------------------------+-----------------------------+-----------------------------------+
-The toolchain object
-~~~~~~~~~~~~~~~~~~~~
+go_context
+~~~~~~~~~~
-When you get a Go toolchain from a context (see use_) it exposes a number of fields, of those
-the stable public interface is
+This collects the information needed to form and return a :type:`GoContext` from a rule ctx.
+It uses the attrbutes and the toolchains.
+It can only be used in the implementation of a rule that has the go toolchain attached and
+the go context data as an attribute.
-* go_toolchain
+.. code:: bzl
- * actions
+ my_rule = rule(
+ _my_rule_impl,
+ attrs = {
+ ...
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
+ },
+ toolchains = ["@io_bazel_rules_go//go:toolchain"],
+ )
+
++--------------------------------+-----------------------------+-----------------------------------+
+| **Name** | **Type** | **Default value** |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`ctx` | :type:`ctx` | |mandatory| |
++--------------------------------+-----------------------------+-----------------------------------+
+| The Bazel ctx object for the current rule. |
++--------------------------------+-----------------------------+-----------------------------------+
+
+The context object
+~~~~~~~~~~~~~~~~~~
+
+GoContext is never returned by a rule, instead you build one using go_context(ctx) in the top of
+any custom skylark rule that wants to interact with the go rules.
+It provides all the information needed to create go actions, and create or interact with the other
+go providers.
+
+When you get a GoContext from a context (see use_) it exposes a number of fields and methods.
+
+All methods take the GoContext as the only positional argument, all other arguments even if
+mandatory must be specified by name, to allow us to re-order and deprecate individual parameters
+over time.
+
+
+Methods
+*******
+
+ * Action generators
+ * archive_
* asm_
* binary_
* compile_
* cover_
- * library_
* link_
* pack_
+ * Helpers
+ * args_
+ * declare_file_
+ * library_to_source_
+ * new_library_
-The only stable public interface is the actions member.
-This holds a collection of functions for generating the standard actions the toolchain knows
-about, compiling and linking for instance.
-All the other members are there to provide information to those action functions, and the api of
-any other part is subject to arbritary breaking changes at any time.
+Fields
+******
-All action functions take the ctx and the go_toolchain as the only positional arguments, all
-other arguments even if mandator must be specified by name, to allow us to re-order and
-deprecate individual parameters over time.
++--------------------------------+-----------------------------------------------------------------+
+| **Name** | **Type** |
++--------------------------------+-----------------------------------------------------------------+
+| :param:`toolchain` | :type:`GoToolchain` |
++--------------------------------+-----------------------------------------------------------------+
+| The underlying toolchain. This should be considered an opaque type subject to change. |
++--------------------------------+-----------------------------------------------------------------+
+| :param:`mode` | :type:`Mode` |
++--------------------------------+-----------------------------------------------------------------+
+| Controls the compilation setup affecting things like enabling profilers and sanitizers. |
+| See `compilation modes`_ for more information about the allowed values. |
++--------------------------------+-----------------------------------------------------------------+
+| :param:`stdlib` | :type:`GoStdlib` |
++--------------------------------+-----------------------------------------------------------------+
+| The standard library and tools to use in this build mode. |
++--------------------------------+-----------------------------------------------------------------+
+| :param:`actions` | :type:`ctx.actions` |
++--------------------------------+-----------------------------------------------------------------+
+| The actions structure from the Bazel context, which has all the methods for building new |
+| bazel actions. |
++--------------------------------+-----------------------------------------------------------------+
+| :param:`exe_extension` | :type:`String` |
++--------------------------------+-----------------------------------------------------------------+
+| The suffix to use for all executables in this build mode. Mostly used when generating the output |
+| filenames of binary rules. |
++--------------------------------+-----------------------------------------------------------------+
+| :param:`crosstool` | :type:`list of File` |
++--------------------------------+-----------------------------------------------------------------+
+| The files you need to add to the inputs of an action in order to use the cc toolchain. |
++--------------------------------+-----------------------------------------------------------------+
+| :param:`package_list` | :type:`File` |
++--------------------------------+-----------------------------------------------------------------+
+| A file that contains the package list of the standard library. |
++--------------------------------+-----------------------------------------------------------------+
+
+
+archive
+~~~~~~~
+
+This emits actions to compile Go code into an archive.
+It supports embedding, cgo dependencies, coverage, and assembling and packing .s files.
+
+It returns a GoArchive_.
+
++--------------------------------+-----------------------------+-----------------------------------+
+| **Name** | **Type** | **Default value** |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`go` | :type:`GoContext` | |mandatory| |
++--------------------------------+-----------------------------+-----------------------------------+
+| This must be the same GoContext object you got this function from. |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`source` | :type:`GoSource` | |mandatory| |
++--------------------------------+-----------------------------+-----------------------------------+
+| The GoSource_ that should be compiled into an archive. |
++--------------------------------+-----------------------------+-----------------------------------+
asm
~~~
The asm function adds an action that runs ``go tool asm`` on a source file
-to produce an object.
-
-It does not return anything.
+to produce an object, and returns the File of that object.
+--------------------------------+-----------------------------+-----------------------------------+
| **Name** | **Type** | **Default value** |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`ctx` | :type:`string` | |mandatory| |
+| :param:`go` | :type:`GoContext` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
-| The current rule context, used to generate the actions. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`go_toolchain` | :type:`the Go toolchain` | |mandatory| |
-+--------------------------------+-----------------------------+-----------------------------------+
-| This must be the same Go toolchain object you got this function from. |
+| This must be the same GoContext object you got this function from. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`source` | :type:`File` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
@@ -444,10 +544,6 @@
+--------------------------------+-----------------------------+-----------------------------------+
| The list of .h files that may be included by the source. |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`out_obj` | :type:`File` | |mandatory| |
-+--------------------------------+-----------------------------+-----------------------------------+
-| The output object file that should be built by the generated action. |
-+--------------------------------+-----------------------------+-----------------------------------+
binary
@@ -461,44 +557,17 @@
+--------------------------------+-----------------------------+-----------------------------------+
| **Name** | **Type** | **Default value** |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`ctx` | :type:`string` | |mandatory| |
+| :param:`go` | :type:`GoContext` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
-| The current rule context, used to generate the actions. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`go_toolchain` | :type:`the Go toolchain` | |mandatory| |
-+--------------------------------+-----------------------------+-----------------------------------+
-| This must be the same Go toolchain object you got this function from. |
+| This must be the same GoContext object you got this function from. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`name` | :type:`string` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
| The base name of the generated binaries. |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`executable` | :type:`File` | |mandatory| |
+| :param:`source` | :type:`GoSource` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
-| The binary to produce. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`srcs` | :type:`File iterable` | :value:`[]` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| An iterable of Go source Files to be compiled. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`deps` | :type:`GoLibrary iterable` | :value:`[]` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| The list of direct dependencies of this package. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`cgo_info` | :type:`CgoInfo` | :value:`None` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| An optional CgoInfo provider for this library. |
-| There may be at most one of these among the library and its embeds. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`embed` | :type:`GoSourceList list` | :value:`[]` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| Sources, dependencies, and other information from these are combined with the package |
-| being compiled. |
-| Used to build internal test packages. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`importpath` | :type:`string` | :value:`""` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| The import path this package represents. |
+| The GoSource_ that should be compiled and linked. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`gc_linkopts` | :type:`string_list` | :value:`[]` |
+--------------------------------+-----------------------------+-----------------------------------+
@@ -521,13 +590,9 @@
+--------------------------------+-----------------------------+-----------------------------------+
| **Name** | **Type** | **Default value** |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`ctx` | :type:`string` | |mandatory| |
+| :param:`go` | :type:`GoContext` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
-| The current rule context, used to generate the actions. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`go_toolchain` | :type:`the Go toolchain` | |mandatory| |
-+--------------------------------+-----------------------------+-----------------------------------+
-| This must be the same Go toolchain object you got this function from. |
+| This must be the same GoContext object you got this function from. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`sources` | :type:`File iterable` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
@@ -538,18 +603,13 @@
+--------------------------------+-----------------------------+-----------------------------------+
| The import path this package represents. This is passed to the -p flag. |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`golibs` | :type:`GoLibrary iterable` | :value:`[]` |
+| :param:`archives` | :type:`GoArchive iterable` | :value:`[]` |
+--------------------------------+-----------------------------+-----------------------------------+
| An iterable of all directly imported libraries. |
| The action will verify that all directly imported libraries were supplied, not allowing |
| transitive dependencies to satisfy imports. It will not check that all supplied libraries were |
| used though. |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`mode` | :type:`string` | :value:`NORMAL_MODE` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| Controls the compilation setup affecting things like enabling profilers and sanitizers. |
-| See `compilation modes`_ for more information about the allowed values. |
-+--------------------------------+-----------------------------+-----------------------------------+
| :param:`out_lib` | :type:`File` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
| The archive file that should be produced. |
@@ -566,78 +626,22 @@
The cover function adds an action that runs ``go tool cover`` on a set of source files
to produce copies with cover instrumentation.
-Returns a tuple of the covered source list and the cover vars.
+Returns a tuple of a covered GoSource with the required source files processed for cover and
+the cover vars that were added.
Note that this removes most comments, including cgo comments.
+--------------------------------+-----------------------------+-----------------------------------+
| **Name** | **Type** | **Default value** |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`ctx` | :type:`string` | |mandatory| |
+| :param:`go` | :type:`GoContext` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
-| The current rule context, used to generate the actions. |
+| This must be the same GoContext object you got this function from. |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`go_toolchain` | :type:`the Go toolchain` | |mandatory| |
+| :param:`source` | :type:`GoSource` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
-| This must be the same Go toolchain object you got this function from. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`sources` | :type:`File iterable` | :value:`[]` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| An iterable of Go source files. |
-| These Must be pure .go files that are ready to be passed to compile_, no assembly or cgo is |
-| allowed. |
-+--------------------------------+-----------------------------+-----------------------------------+
-
-
-library
-~~~~~~~
-
-This emits actions to compile Go code into an archive.
-It supports embedding, cgo dependencies, coverage, and assembling and packing .s files.
-
-It returns a tuple of GoLibrary_ and GoSourceList_.
-
-+--------------------------------+-----------------------------+-----------------------------------+
-| **Name** | **Type** | **Default value** |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`ctx` | :type:`string` | |mandatory| |
-+--------------------------------+-----------------------------+-----------------------------------+
-| The current rule context, used to generate the actions. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`go_toolchain` | :type:`the Go toolchain` | |mandatory| |
-+--------------------------------+-----------------------------+-----------------------------------+
-| This must be the same Go toolchain object you got this function from. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`srcs` | :type:`File iterable` | :value:`[]` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| An iterable of Go source Files to be compiled. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`deps` | :type:`GoLibrary iterable` | :value:`[]` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| The list of direct dependencies of this package. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`cgo_info` | :type:`CgoInfo` | :value:`None` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| An optional CgoInfo provider for this library. |
-| There may be at most one of these among the library and its embeds. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`embed` | :type:`GoSourceList list` | :value:`[]` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| Sources, dependencies, and other information from these are combined with the package |
-| being compiled. |
-| Used to build internal test packages. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`want_coverage` | :type:`boolean` | :value:`False` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| A bool indicating whether sources should be instrumented for coverage. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`importpath` | :type:`string` | :value:`""` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| The import path this package represents. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`importable` | :type:`boolean` | :value:`True` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| A bool indicating whether the package can be imported by other libraries. |
+| The source object to process. Any source files in the object that have been marked as needing |
+| coverage will be processed and substiuted in the returned GoSource. |
+--------------------------------+-----------------------------+-----------------------------------+
@@ -651,23 +655,14 @@
+--------------------------------+-----------------------------+-----------------------------------+
| **Name** | **Type** | **Default value** |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`ctx` | :type:`string` | |mandatory| |
+| :param:`go` | :type:`GoContext` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
-| The current rule context, used to generate the actions. |
+| This must be the same GoContext object you got this function from. |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`go_toolchain` | :type:`the Go toolchain` | |mandatory| |
-+--------------------------------+-----------------------------+-----------------------------------+
-| This must be the same Go toolchain object you got this function from. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`library` | :type:`GoLibrary` | |mandatory| |
+| :param:`archive` | :type:`GoArchive` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
| The library to link. |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`mode` | :type:`string` | :value:`NORMAL_MODE` |
-+--------------------------------+-----------------------------+-----------------------------------+
-| Controls the compilation setup affecting things like enabling profilers and sanitizers. |
-| See `compilation modes`_ for more information about the allowed values. |
-+--------------------------------+-----------------------------+-----------------------------------+
| :param:`executable` | :type:`File` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
| The binary to produce. |
@@ -692,13 +687,9 @@
+--------------------------------+-----------------------------+-----------------------------------+
| **Name** | **Type** | **Default value** |
+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`ctx` | :type:`string` | |mandatory| |
+| :param:`go` | :type:`GoContext` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
-| The current rule context, used to generate the actions. |
-+--------------------------------+-----------------------------+-----------------------------------+
-| :param:`go_toolchain` | :type:`the Go toolchain` | |mandatory| |
-+--------------------------------+-----------------------------+-----------------------------------+
-| This must be the same Go toolchain object you got this function from. |
+| This must be the same GoContext object you got this function from. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`in_lib` | :type:`File` | |mandatory| |
+--------------------------------+-----------------------------+-----------------------------------+
@@ -719,3 +710,107 @@
| An additional archive whose objects will be appended to the output. |
| This can be an ar file in either common form or either the bsd or sysv variations. |
+--------------------------------+-----------------------------+-----------------------------------+
+
+
+
+args
+~~~~
+
+This creates a new args object, using the ctx.args method, and the populates it with the standard
+arguments used by all the go toolchain builders.
+
++--------------------------------+-----------------------------+-----------------------------------+
+| **Name** | **Type** | **Default value** |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`go` | :type:`GoContext` | |mandatory| |
++--------------------------------+-----------------------------+-----------------------------------+
+| This must be the same GoContext object you got this function from. |
++--------------------------------+-----------------------------+-----------------------------------+
+
+declare_file
+~~~~~~~~~~~~
+
+This is the equivalent of ctx.actions.declare_file except it uses the current build mode to make
+the filename unique between configurations.
+
++--------------------------------+-----------------------------+-----------------------------------+
+| **Name** | **Type** | **Default value** |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`go` | :type:`GoContext` | |mandatory| |
++--------------------------------+-----------------------------+-----------------------------------+
+| This must be the same GoContext object you got this function from. |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`path` | :type:`string` | :value:`""` |
++--------------------------------+-----------------------------+-----------------------------------+
+| A path for this file, including the basename of the file. |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`ext` | :type:`string` | :value:`""` |
++--------------------------------+-----------------------------+-----------------------------------+
+| The extension to use for the file. |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`name` | :type:`string` | :value:`""` |
++--------------------------------+-----------------------------+-----------------------------------+
+| A name to use for this file. If path is not present, this becomes a prefix to the path. |
+| If this is not set, the current rule name is used in it's place. |
++--------------------------------+-----------------------------+-----------------------------------+
+
+library_to_source
+~~~~~~~~~~~~~~~~~
+
+This is used to build a GoSource object for a given GoLibrary in the current build mode.
+
++--------------------------------+-----------------------------+-----------------------------------+
+| **Name** | **Type** | **Default value** |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`go` | :type:`GoContext` | |mandatory| |
++--------------------------------+-----------------------------+-----------------------------------+
+| This must be the same GoContext object you got this function from. |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`attr` | :type:`ctx.attr` | |mandatory| |
++--------------------------------+-----------------------------+-----------------------------------+
+| The attributes of the rule being processed, in a normal rule implementation this would be |
+| ctx.attr. |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`library` | :type:`GoLibrary` | |mandatory| |
++--------------------------------+-----------------------------+-----------------------------------+
+| The GoLibrary_ that you want to build a GoSource_ object for in the current build mode. |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`coverage_instrumented` | :type:`bool` | |mandatory| |
++--------------------------------+-----------------------------+-----------------------------------+
+| This controls whether cover is enabled for this specific library in this mode. |
+| This should generally be the value of ctx.coverage_instrumented() |
++--------------------------------+-----------------------------+-----------------------------------+
+
+new_library
+~~~~~~~~~~~
+
+This creates a new GoLibrary.
+You can add extra fields to the go library by providing extra named parameters to this function,
+they will be visible to the resolver when it is invoked.
+
++--------------------------------+-----------------------------+-----------------------------------+
+| **Name** | **Type** | **Default value** |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`go` | :type:`GoContext` | |mandatory| |
++--------------------------------+-----------------------------+-----------------------------------+
+| This must be the same GoContext object you got this function from. |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`resolver` | :type:`function` | :value:`None` |
++--------------------------------+-----------------------------+-----------------------------------+
+| This is the function that gets invoked when converting from a GoLibrary to a GoSource. |
+| See resolver_ for a |
+| The function's signature must be |
+| |
+| .. code:: bzl |
+| |
+| def _testmain_library_to_source(go, attr, source, merge) |
+| |
+| attr is the attributes of the rule being processed |
+| source is the dictionary of GoSource fields being generated |
+| merge is a helper you can call to merge |
++--------------------------------+-----------------------------+-----------------------------------+
+| :param:`importable` | :type:`bool` | |mandatory| |
++--------------------------------+-----------------------------+-----------------------------------+
+| This controls whether the GoLibrary_ is supposed to be importable. This is generally only false |
+| for the "main" libraries that are built just before linking. |
++--------------------------------+-----------------------------+-----------------------------------+
diff --git a/proto/compiler.bzl b/proto/compiler.bzl
index e0c2ea4..be6fb3d 100644
--- a/proto/compiler.bzl
+++ b/proto/compiler.bzl
@@ -12,33 +12,25 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@io_bazel_rules_go//go/private:common.bzl",
- "declare_file",
- "sets",
-)
-load("@io_bazel_rules_go//go/private:providers.bzl",
+load("@io_bazel_rules_go//go:def.bzl",
+ "go_context",
"GoLibrary",
)
-load("@io_bazel_rules_go//go/private:rules/helpers.bzl",
- "new_go_library",
- "library_to_source",
-)
-
-load("@io_bazel_rules_go//go/private:mode.bzl",
- "get_mode",
+load("@io_bazel_rules_go//go/private:common.bzl", # TODO: @skylib?
+ "sets",
)
GoProtoCompiler = provider()
-def go_proto_compile(ctx, compiler, proto, imports, importpath):
+def go_proto_compile(go, compiler, proto, imports, importpath):
go_srcs = []
outpath = None
for src in proto.direct_sources:
- out = declare_file(ctx, path=importpath+"/"+src.basename[:-len(".proto")], ext=compiler.suffix)
+ out = go.declare_file(go, path=importpath+"/"+src.basename[:-len(".proto")], ext=compiler.suffix)
go_srcs.append(out)
if outpath == None:
outpath = out.dirname[:-len(importpath)]
- args = ctx.actions.args()
+ args = go.actions.args()
args.add([
"--protoc", compiler.protoc,
"--importpath", importpath,
@@ -50,7 +42,7 @@
args.add(go_srcs, before_each = "--expected")
args.add(imports, before_each = "--import")
args.add(proto.direct_sources, map_fn=_all_proto_paths)
- ctx.actions.run(
+ go.actions.run(
inputs = sets.union([
compiler.go_protoc,
compiler.protoc,
@@ -83,9 +75,9 @@
def _go_proto_compiler_impl(ctx):
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
- library = new_go_library(ctx)
- source = library_to_source(ctx, ctx.attr, library, mode)
+ go = go_context(ctx)
+ library = go.new_library(go)
+ source = go.library_to_source(go, ctx.attr, library, ctx.coverage_instrumented())
return [
GoProtoCompiler(
deps = ctx.attr.deps,
@@ -126,7 +118,7 @@
cfg = "host",
default = Label("@com_github_google_protobuf//:protoc"),
),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = [
"@io_bazel_rules_go//go:toolchain",
diff --git a/proto/def.bzl b/proto/def.bzl
index 7f8ae10..b0704d6 100644
--- a/proto/def.bzl
+++ b/proto/def.bzl
@@ -12,18 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("@io_bazel_rules_go//go/private:common.bzl",
- "go_importpath",
- "sets",
-)
-load("@io_bazel_rules_go//go/private:providers.bzl",
+load("@io_bazel_rules_go//go:def.bzl",
+ "go_context",
"GoLibrary",
)
-load("@io_bazel_rules_go//go/private:rules/helpers.bzl",
- "new_go_library",
- "library_to_source",
- "get_source",
- "merge_embed",
+load("@io_bazel_rules_go//go/private:common.bzl",
+ "sets",
)
load("@io_bazel_rules_go//go/private:rules/prefix.bzl",
"go_prefix_default",
@@ -31,9 +25,6 @@
load("@io_bazel_rules_go//proto:compiler.bzl",
"GoProtoCompiler",
)
-load("@io_bazel_rules_go//go/private:mode.bzl",
- "get_mode",
-)
GoProtoImports = provider()
@@ -53,28 +44,25 @@
attr_aspects = ["deps", "embed"],
)
-def _proto_library_to_source(ctx, attr, source):
- compiler = attr.compiler[GoProtoCompiler]
- merge_embed(source, attr.compiler)
+def _proto_library_to_source(go, attr, source, merge):
+ merge(source, attr.compiler)
def _go_proto_library_impl(ctx):
- mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
+ go = go_context(ctx)
compiler = ctx.attr.compiler[GoProtoCompiler]
- importpath = go_importpath(ctx)
- go_srcs = compiler.compile(ctx,
+ importpath = go._inferredpath #TODO: Drop this as soon as the attribute is mandatory
+ go_srcs = compiler.compile(go,
compiler = compiler,
proto = ctx.attr.proto.proto,
imports = get_imports(ctx.attr),
importpath = importpath,
)
- go_toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"]
- library = new_go_library(ctx,
+ library = go.new_library(go,
resolver=_proto_library_to_source,
srcs=go_srcs,
)
- source = library_to_source(ctx, ctx.attr, library, mode)
- archive = go_toolchain.actions.archive(ctx, go_toolchain, source)
-
+ source = go.library_to_source(go, ctx.attr, library, False)
+ archive = go.archive(go, source)
return [
library, source, archive,
DefaultInfo(
@@ -93,7 +81,7 @@
"gc_goopts": attr.string_list(),
"compiler": attr.label(providers = [GoProtoCompiler], default = "@io_bazel_rules_go//proto:go_proto"),
"_go_prefix": attr.label(default = go_prefix_default),
- "_go_toolchain_flags": attr.label(default=Label("@io_bazel_rules_go//go/private:go_toolchain_flags")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
toolchains = [
"@io_bazel_rules_go//go:toolchain",
diff --git a/tests/bazel_tests.bzl b/tests/bazel_tests.bzl
index a7f4ce7..14fb75e 100644
--- a/tests/bazel_tests.bzl
+++ b/tests/bazel_tests.bzl
@@ -1,5 +1,9 @@
-load("@io_bazel_rules_go//go/private:go_repository.bzl", "env_execute")
-load("@io_bazel_rules_go//go/private:common.bzl", "declare_file")
+load("@io_bazel_rules_go//go/private:context.bzl",
+ "go_context",
+)
+load("@io_bazel_rules_go//go/private:go_repository.bzl",
+ "env_execute"
+)
# _bazelrc is the bazel.rc file that sets the default options for tests
_bazelrc = """
@@ -64,7 +68,8 @@
CURRENT_VERSION = "current"
def _bazel_test_script_impl(ctx):
- script_file = declare_file(ctx, ext=".bash")
+ go = go_context(ctx)
+ script_file = go.declare_file(go, ext=".bash")
if ctx.attr.go_version == CURRENT_VERSION:
register = 'go_register_toolchains()\n'
@@ -86,9 +91,9 @@
workspace_content += _basic_workspace.format()
workspace_content += register
- workspace_file = declare_file(ctx, path="WORKSPACE.in")
+ workspace_file = go.declare_file(go, path="WORKSPACE.in")
ctx.actions.write(workspace_file, workspace_content)
- build_file = declare_file(ctx, path="BUILD.in")
+ build_file = go.declare_file(go, path="BUILD.in")
ctx.actions.write(build_file, ctx.attr.build)
targets = ["@" + ctx.workspace_name + "//" + ctx.label.package + t if t.startswith(":") else t for t in ctx.attr.targets]
@@ -128,7 +133,9 @@
"config": attr.string(default="isolate"),
"_bazelrc": attr.label(allow_files=True, single_file=True, default="@bazel_test//:bazelrc"),
"_settings": attr.label(default = Label("@bazel_test//:settings")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
+ toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
def bazel_test(name, command = None, args=None, targets = None, go_version = None, tags=[], externals=[], workspace="", build="", check="", config=None):
@@ -166,7 +173,8 @@
)
def _md5_sum_impl(ctx):
- out = declare_file(ctx, ext=".md5")
+ go = go_context(ctx)
+ out = go.declare_file(go, ext=".md5")
arguments = ctx.actions.args()
arguments.add(["-output", out.path])
arguments.add(ctx.files.srcs)
@@ -184,7 +192,9 @@
attrs = {
"srcs": attr.label_list(allow_files=True),
"_md5sum": attr.label(allow_files=True, single_file=True, default=Label("@io_bazel_rules_go//go/tools/builders:md5sum")),
+ "_go_context_data": attr.label(default=Label("@io_bazel_rules_go//:go_context_data")),
},
+ toolchains = ["@io_bazel_rules_go//go:toolchain"],
)
def _test_environment_impl(ctx):
diff --git a/tests/cross/cross_test.go b/tests/cross/cross_test.go
index b0c155b..4280202 100644
--- a/tests/cross/cross_test.go
+++ b/tests/cross/cross_test.go
@@ -41,7 +41,7 @@
"executable",
"x86-64",
}},
- {"windows_amd64_pure_stripped/cross", []string{
+ {"windows_amd64_pure_stripped/cross.exe", []string{
"PE32+",
"Windows",
"executable",
diff --git a/tests/custom_go_toolchain/BUILD.bazel b/tests/custom_go_toolchain/BUILD.bazel
index 20587d2..234afcf 100644
--- a/tests/custom_go_toolchain/BUILD.bazel
+++ b/tests/custom_go_toolchain/BUILD.bazel
@@ -24,7 +24,7 @@
targets = [":go_default_test"],
workspace = """
-load("@io_bazel_rules_go//go/private:toolchain.bzl", "go_download_sdk")
+load("@io_bazel_rules_go//go:def.bzl", "go_download_sdk")
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies")
go_download_sdk(