Skip to content

Commit

Permalink
Build stdlib from inside the aspect (#1295)
Browse files Browse the repository at this point in the history
* Build stdlib from inside the aspect

This removes the hard coded list of standard libraries, and builds it per aspect
being propagated.
This is both cleaner and a pre-requisite for the additional link modes to work.

Related to #1264 and #54 and #539

* review feedback
  • Loading branch information
ianthehat authored Feb 2, 2018
1 parent 6b653a8 commit 213d5fc
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 125 deletions.
11 changes: 3 additions & 8 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@ load("@io_bazel_rules_go//go/private:tools/lines_sorted_test.bzl", "lines_sorted
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")
load("@io_bazel_rules_go//go/private:rules/stdlib.bzl", "stdlib")

go_context_data(
name = "go_bootstrap_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",
}),
stdlib_all = [],
stdlib(
name = "stdlib",
visibility = ["//visibility:public"],
)

Expand Down
2 changes: 0 additions & 2 deletions go/private/BUILD.sdk.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
load("@io_bazel_rules_go//go/private:rules/stdlib.bzl", "stdlib")

package(default_visibility = [ "//visibility:public" ])

filegroup(
Expand Down
48 changes: 16 additions & 32 deletions go/private/context.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,20 @@ INFERRED_PATH = "inferred"

EXPORT_PATH = "export"

def _declare_file(go, path="", ext="", name = ""):
filename = mode_string(go.mode) + "/"
filename += name if name else go._ctx.label.name
def _child_name(go, path, ext, name):
childname = mode_string(go.mode) + "/"
childname += name if name else go._ctx.label.name
if path:
filename += "~/" + path
childname += "~/" + path
if ext:
filename += ext
return go.actions.declare_file(filename)
childname += ext
return childname

def _declare_file(go, path="", ext="", name = ""):
return go.actions.declare_file(_child_name(go, path, ext, name))

def _declare_directory(go, path="", ext="", name = ""):
return go.actions.declare_directory(_child_name(go, path, ext, name))

def _new_args(go):
args = go.actions.args()
Expand Down Expand Up @@ -195,20 +201,9 @@ def go_context(ctx, attr=None):
mode = get_mode(ctx, toolchain, context_data)
root, binary = _get_go_binary(context_data)

stdlib = None
for check in [s[GoStdLib] for s in context_data.stdlib_all]:
if (check.mode.goos == mode.goos and
check.mode.goarch == mode.goarch and
check.mode.race == mode.race and
check.mode.pure == mode.pure):
if stdlib:
fail("Multiple matching standard library for {}: {} and {}".format(
mode_string(mode),
check.root_file.dirname,
stdlib.root_file.dirname))
stdlib = check
if not stdlib and context_data.stdlib_all:
fail("No matching standard library for "+mode_string(mode))
stdlib = getattr(attr, "_stdlib", None)
if stdlib:
stdlib = get_source(stdlib).stdlib

importpath, pathtype = _infer_importpath(ctx)
return GoContext(
Expand Down Expand Up @@ -241,21 +236,12 @@ def go_context(ctx, attr=None):
new_library = _new_library,
library_to_source = _library_to_source,
declare_file = _declare_file,
declare_directory = _declare_directory,

# Private
_ctx = ctx, # TODO: All uses of this should be removed
)

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)),
])
return stdlibs

def _go_context_data(ctx):
cpp = ctx.fragments.cpp
features = ctx.features
Expand All @@ -275,7 +261,6 @@ def _go_context_data(ctx):
compiler_path, _ = cpp.ld_executable.rsplit("/", 1)
return struct(
strip = ctx.attr.strip,
stdlib_all = ctx.attr.stdlib_all,
crosstool = ctx.files._crosstool,
package_list = ctx.file._package_list,
sdk_files = ctx.files._sdk_files,
Expand All @@ -295,7 +280,6 @@ go_context_data = rule(
_go_context_data,
attrs = {
"strip": attr.string(mandatory = True),
"stdlib_all": attr.label_list(default = _stdlib_all()),
# Hidden internal attributes
"_crosstool": attr.label(default = Label("//tools/defaults:crosstool")),
"_package_list": attr.label(
Expand Down
24 changes: 0 additions & 24 deletions go/private/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
load("@io_bazel_rules_go//go/private:common.bzl", "MINIMUM_BAZEL_VERSION")
load("@io_bazel_rules_go//go/private:repository_tools.bzl", "go_repository_tools")
load("@io_bazel_rules_go//go/private:go_repository.bzl", "go_repository")
load("@io_bazel_rules_go//go/private:rules/stdlib.bzl", "go_stdlib")
load("@io_bazel_rules_go//go/private:skylib/lib/versions.bzl", "versions")
load("@io_bazel_rules_go//go/toolchain:toolchains.bzl", "go_register_toolchains")
load("@io_bazel_rules_go//go/platform:list.bzl", "GOOS_GOARCH")
Expand Down Expand Up @@ -55,29 +54,6 @@ def go_rules_dependencies():
type = "zip",
)

for goos, goarch in GOOS_GOARCH:
_maybe(go_stdlib,
name = "go_stdlib_{}_{}_cgo".format(goos, goarch),
goos = goos,
goarch = goarch,
race = False,
pure = False,
)
_maybe(go_stdlib,
name = "go_stdlib_{}_{}_pure".format(goos, goarch),
goos = goos,
goarch = goarch,
race = False,
pure = True,
)
_maybe(go_stdlib,
name = "go_stdlib_{}_{}_cgo_race".format(goos, goarch),
goos = goos,
goarch = goarch,
race = True,
pure = False,
)

_maybe(go_repository_tools,
name = "io_bazel_rules_go_repository_tools",
)
Expand Down
1 change: 1 addition & 0 deletions go/private/rules/aspect.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ go_archive_aspect = aspect(
"embed",
"compiler",
"compilers",
"_stdlib",
],
attrs = {
"pure": attr.string(values = [
Expand Down
10 changes: 8 additions & 2 deletions go/private/rules/rule.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@ load(
"go_archive_aspect",
)

_ASPECT_ATTRS = ["pure", "static", "msan", "race"]

def go_rule(implementation, attrs={}, toolchains=[], bootstrap=False, **kwargs):
attrs["_go_context_data"] = attr.label(default = Label("@io_bazel_rules_go//:go_context_data"))
aspects = []
# If all the aspect attributes are present, also trigger the aspect on the stdlib attribute
if all([k in attrs for k in _ASPECT_ATTRS]):
aspects.append(go_archive_aspect)
if not bootstrap:
attrs["_go_context_data"] = attr.label(default = Label("@io_bazel_rules_go//:go_context_data"))
attrs["_stdlib"] = attr.label(default = Label("@io_bazel_rules_go//:stdlib"), aspects = aspects)
toolchains = toolchains + ["@io_bazel_rules_go//go:toolchain"]
else:
attrs["_go_context_data"] = attr.label(default = Label("@io_bazel_rules_go//:go_bootstrap_context_data"))
toolchains = toolchains + ["@io_bazel_rules_go//go:bootstrap_toolchain"]

return rule(
Expand Down
77 changes: 20 additions & 57 deletions go/private/rules/stdlib.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,90 +16,53 @@ load(
"@io_bazel_rules_go//go/private:providers.bzl",
"GoStdLib",
)
load("@io_bazel_rules_go//go/private:context.bzl",
load(
"@io_bazel_rules_go//go/private:context.bzl",
"go_context",
)
load(
"@io_bazel_rules_go//go/private:rules/rule.bzl",
"go_rule",
)

_STDLIB_BUILD = """
load("@io_bazel_rules_go//go/private:rules/stdlib.bzl", "stdlib")
stdlib(
name = "{name}",
goos = "{goos}",
goarch = "{goarch}",
race = {race},
pure = {pure},
visibility = ["//visibility:public"],
)
"""

def _stdlib_impl(ctx):
go = go_context(ctx)
pkg = ctx.actions.declare_directory("pkg")
root_file = ctx.actions.declare_file("ROOT")
def _stdlib_library_to_source(go, attr, source, merge):
pkg = go.declare_directory(go, "pkg")
root_file = go.declare_file(go, "ROOT")
files = [root_file, go.go, pkg]
args = go.args(go)
args.add(["-out", root_file.dirname])
if ctx.attr.race:
if go.mode.race:
args.add("-race")
ctx.actions.write(root_file, "")
go.actions.write(root_file, "")
go.actions.run(
inputs = go.sdk_files + go.sdk_tools + [go.package_list, root_file],
outputs = [pkg],
mnemonic = "GoStdlib",
executable = ctx.executable._stdlib_builder,
executable = attr._stdlib_builder.files.to_list()[0],
arguments = [args],
)
source["stdlib"] = GoStdLib(
root_file = root_file,
mode = go.mode,
libs = [pkg],
headers = [pkg],
files = files,
)

return [
DefaultInfo(
files = depset(files),
),
GoStdLib(
root_file = root_file,
mode = go.mode,
libs = [pkg],
headers = [pkg],
files = files,
),
]
def _stdlib_impl(ctx):
go = go_context(ctx)
library = go.new_library(go, resolver = _stdlib_library_to_source)
source = go.library_to_source(go, ctx.attr, library, False)
return [source, library]

stdlib = go_rule(
_stdlib_impl,
bootstrap = True,
attrs = {
"goos": attr.string(mandatory = True),
"goarch": attr.string(mandatory = True),
"race": attr.bool(mandatory = True),
"pure": attr.bool(mandatory = True),
"_stdlib_builder": attr.label(
executable = True,
cfg = "host",
default = Label("@io_bazel_rules_go//go/tools/builders:stdlib"),
),
},
)

def _go_stdlib_impl(ctx):
ctx.file("BUILD.bazel", _STDLIB_BUILD.format(
name = ctx.name,
goos = ctx.attr.goos,
goarch = ctx.attr.goarch,
race = ctx.attr.race,
pure = ctx.attr.pure,
))

go_stdlib = repository_rule(
implementation = _go_stdlib_impl,
attrs = {
"goos": attr.string(mandatory = True),
"goarch": attr.string(mandatory = True),
"race": attr.bool(mandatory = True),
"pure": attr.bool(mandatory = True),
},
)
"""See /go/toolchains.rst#go-sdk for full documentation."""

0 comments on commit 213d5fc

Please sign in to comment.