Skip to content

Commit

Permalink
Fix aspect based proto builds (#1131)
Browse files Browse the repository at this point in the history
* Fix aspect based proto builds

This changes the structure of our providers.
It is now much more principled about configuration specific and transitive
providers, separating them cleanly.
It also allows the GoLibray provider to supply a function that can be used to
produce the configuration specific version (GoSource). This allows us to fix the
proto library dependancies when built in aspect mode.

* Make it a little easier to write simple code generation rules

* Review fixes
  • Loading branch information
ianthehat authored Dec 14, 2017
1 parent 737df20 commit 1c4f6fd
Show file tree
Hide file tree
Showing 25 changed files with 531 additions and 484 deletions.
13 changes: 13 additions & 0 deletions examples/proto/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ go_library(
go_test(
name = "proto_test",
size = "small",
pure = "off",
srcs = ["proto_test.go"],
importpath = "github.com/bazelbuild/rules_go/examples/proto",
deps = [
"//examples/proto/embed:go_default_library",
"//examples/proto/lib:lib_go_proto",
],
)

go_test(
name = "proto_pure_test",
size = "small",
pure = "on",
srcs = ["proto_test.go"],
importpath = "github.com/bazelbuild/rules_go/examples/proto",
deps = [
Expand Down
4 changes: 0 additions & 4 deletions go/def.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ load("@io_bazel_rules_go//go/private:go_repository.bzl",
)
load("@io_bazel_rules_go//go/private:providers.bzl",
_GoLibrary = "GoLibrary",
_GoSourceList = "GoSourceList",
)
load("@io_bazel_rules_go//go/private:repositories.bzl",
"go_rules_dependencies",
Expand Down Expand Up @@ -63,9 +62,6 @@ RULES_GO_VERSION = "0.8.1"
GoLibrary = _GoLibrary
"""See go/providers.rst#GoLibrary for full documentation."""

GoSourceList = _GoSourceList
"""See go/providers.rst#GoSourceList for full documentation."""

go_library = _go_library_macro
"""See go/core.rst#go_library for full documentation."""

Expand Down
2 changes: 1 addition & 1 deletion go/modes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ following fields that control the bevhaviour of those actions:
Build modes
-----------

The following is a description of the build modes. Not all build modes are truly independant, but
The following is a description of the build modes. Not all build modes are truly independent, but
most combinations are valid.

static
Expand Down
61 changes: 29 additions & 32 deletions go/private/actions/archive.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -20,90 +20,87 @@ load("@io_bazel_rules_go//go/private:common.bzl",
load("@io_bazel_rules_go//go/private:mode.bzl",
"mode_string",
)
load("@io_bazel_rules_go//go/private:rules/aspect.bzl",
load("@io_bazel_rules_go//go/private:rules/helpers.bzl",
"get_archive",
)
load("@io_bazel_rules_go//go/private:providers.bzl",
"GoArchive",
"GoArchiveData",
"sources",
)

def emit_archive(ctx, go_toolchain, mode=None, importpath=None, source=None, importable=True):
def emit_archive(ctx, go_toolchain, source=None):
"""See go/toolchains.rst#archive for full documentation."""

if not importpath: fail("golib is a required parameter")
if source == None: fail("source is a required parameter")
if mode == None: fail("mode is a required parameter")

source = sources.filter(ctx, source, mode)

cover_vars = []
if ctx.configuration.coverage_enabled:
source, cover_vars = go_toolchain.actions.cover(ctx, go_toolchain, source=source, mode=mode, importpath=importpath)

flat = sources.flatten(ctx, source)
split = split_srcs(flat.srcs)
lib_name = importpath + ".a"
compilepath = importpath if importable else None
out_lib = declare_file(ctx, path=lib_name, mode=mode)
source, cover_vars = go_toolchain.actions.cover(ctx, go_toolchain, 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)
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=mode)
go_toolchain.actions.asm(ctx, go_toolchain, mode=mode, source=src, hdrs=split.headers, out_obj=obj)
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)

direct = [get_archive(dep) for dep in flat.deps]
runfiles = flat.runfiles
direct = [get_archive(dep) for dep in source.deps]
runfiles = source.runfiles
for a in direct:
runfiles = runfiles.merge(a.runfiles)
if a.mode != mode: fail("Archive mode does not match {} is {} expected {}".format(a.data.importpath, mode_string(a.mode), mode_string(mode)))
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 len(extra_objects) == 0 and flat.cgo_archive == None:
if len(extra_objects) == 0 and source.cgo_archive == None:
go_toolchain.actions.compile(ctx,
go_toolchain = go_toolchain,
sources = split.go,
importpath = compilepath,
archives = direct,
mode = mode,
mode = source.mode,
out_lib = out_lib,
gc_goopts = flat.gc_goopts,
gc_goopts = source.gc_goopts,
)
else:
partial_lib = declare_file(ctx, path="partial", ext=".a", mode=mode)
partial_lib = declare_file(ctx, path="partial", ext=".a", mode=source.mode)
go_toolchain.actions.compile(ctx,
go_toolchain = go_toolchain,
sources = split.go,
importpath = compilepath,
archives = direct,
mode = mode,
mode = source.mode,
out_lib = partial_lib,
gc_goopts = flat.gc_goopts,
gc_goopts = source.gc_goopts,
)
go_toolchain.actions.pack(ctx,
go_toolchain = go_toolchain,
mode = mode,
mode = source.mode,
in_lib = partial_lib,
out_lib = out_lib,
objects = extra_objects,
archive = flat.cgo_archive,
archive = source.cgo_archive,
)
data = GoArchiveData(
name = source.library.name,
label = source.library.label,
importpath = source.library.importpath,
exportpath = source.library.exportpath,
file = out_lib,
importpath = importpath,
srcs = tuple(source.srcs),
searchpath = searchpath,
)
return GoArchive(
mode = mode,
source = source,
data = data,
go_srcs = split.go,
direct = direct,
searchpaths = sets.union([searchpath], *[a.searchpaths for a in direct]),
libs = sets.union([out_lib], *[a.libs for a in direct]),
cgo_deps = sets.union(flat.cgo_deps, *[a.cgo_deps for a in direct]),
cgo_exports = sets.union(flat.cgo_exports, *[a.cgo_exports for a in direct]),
transitive = sets.union([data], *[a.transitive for a in direct]),
cgo_deps = sets.union(source.cgo_deps, *[a.cgo_deps for a in direct]),
cgo_exports = sets.union(source.cgo_exports, *[a.cgo_exports for a in direct]),
cover_vars = sets.union(cover_vars, *[a.cover_vars for a in direct]),
runfiles = runfiles,
)
21 changes: 4 additions & 17 deletions go/private/actions/binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@io_bazel_rules_go//go/private:mode.bzl",
"mode_string",
"get_mode",
)
load("@io_bazel_rules_go//go/private:common.bzl",
"declare_file",
)

def emit_binary(ctx, go_toolchain,
name="",
importpath = "",
source = None,
gc_linkopts = [],
x_defs = {},
Expand All @@ -31,22 +26,14 @@ def emit_binary(ctx, go_toolchain,

if name == "": fail("name is a required parameter")

mode = get_mode(ctx, ctx.attr._go_toolchain_flags)
golib, goarchive = go_toolchain.actions.library(ctx,
go_toolchain = go_toolchain,
mode = mode,
source = source,
importpath = importpath,
importable = False,
)
executable = declare_file(ctx, name=name, ext=go_toolchain.data.extension, mode=mode)
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=goarchive,
mode=mode,
archive=archive,
executable=executable,
gc_linkopts=gc_linkopts,
x_defs=x_defs,
)

return golib, goarchive, executable
return archive, executable
1 change: 0 additions & 1 deletion go/private/actions/compile.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ def emit_compile(ctx, go_toolchain,
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)

Expand Down
59 changes: 24 additions & 35 deletions go/private/actions/cover.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,52 +17,41 @@ load("@io_bazel_rules_go//go/private:actions/action.bzl",
)
load("@io_bazel_rules_go//go/private:providers.bzl",
"GoSource",
"GoSourceList",
)
load("@io_bazel_rules_go//go/private:common.bzl",
"declare_file",
"structs",
)

def emit_cover(ctx, go_toolchain,
source = None,
mode = None,
importpath = ""):
def emit_cover(ctx, go_toolchain, source):
"""See go/toolchains.rst#cover for full documentation."""

if source == None: fail("source is a required parameter")
if mode == None: fail("mode is a required parameter")
if not importpath: fail("importpath is a required parameter")
if not source.cover:
return source, []

stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, mode)
stdlib = go_toolchain.stdlib.get(ctx, go_toolchain, source.mode)

covered = []
cover_vars = []
for s in source.entries:
if not s.want_coverage:
covered.append(s)
for src in source.srcs:
if not src.basename.endswith(".go") or src not in source.cover:
covered.append(src)
continue
outputs = []
for src in s.srcs:
if not src.basename.endswith(".go"):
outputs.append(src)
continue
cover_var = "Cover_" + src.basename[:-3].replace("-", "_").replace(".", "_")
cover_vars.append("{}={}={}".format(cover_var, src.short_path, importpath))
out = declare_file(ctx, path=cover_var, ext='.cover.go')
outputs.append(out)
args = ctx.actions.args()
add_go_env(args, stdlib, mode)
args.add(["--", "--mode=set", "-var=%s" % cover_var, "-o", out, src])
ctx.actions.run(
inputs = [src] + stdlib.files,
outputs = [out],
mnemonic = "GoCover",
executable = go_toolchain.tools.cover,
arguments = [args],
)

members = structs.to_dict(s)
members["srcs"] = outputs
covered.append(GoSource(**members))
return GoSourceList(entries=covered), cover_vars
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')
covered.append(out)
args = ctx.actions.args()
add_go_env(args, stdlib, source.mode)
args.add(["--", "--mode=set", "-var=%s" % cover_var, "-o", out, src])
ctx.actions.run(
inputs = [src] + stdlib.files,
outputs = [out],
mnemonic = "GoCover",
executable = go_toolchain.tools.cover,
arguments = [args],
)
members = structs.to_dict(source)
members["srcs"] = covered
return GoSource(**members), cover_vars
62 changes: 0 additions & 62 deletions go/private/actions/library.bzl

This file was deleted.

Loading

0 comments on commit 1c4f6fd

Please sign in to comment.