From a9c73d472c439661e8a9b348c5715a79d1eb0fa8 Mon Sep 17 00:00:00 2001 From: Ian Cottrell Date: Tue, 9 Jan 2018 19:37:48 -0500 Subject: [PATCH] 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 --- BUILD.bazel | 11 ++---- go/private/BUILD.sdk.bazel | 2 - go/private/context.bzl | 48 ++++++++--------------- go/private/repositories.bzl | 24 ------------ go/private/rules/aspect.bzl | 1 + go/private/rules/rule.bzl | 7 +++- go/private/rules/stdlib.bzl | 77 ++++++++++--------------------------- 7 files changed, 45 insertions(+), 125 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index a6fc837466..dd6335ea65 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -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"], ) diff --git a/go/private/BUILD.sdk.bazel b/go/private/BUILD.sdk.bazel index 55e73809cc..d9e773e0d1 100644 --- a/go/private/BUILD.sdk.bazel +++ b/go/private/BUILD.sdk.bazel @@ -1,5 +1,3 @@ -load("@io_bazel_rules_go//go/private:rules/stdlib.bzl", "stdlib") - package(default_visibility = [ "//visibility:public" ]) filegroup( diff --git a/go/private/context.bzl b/go/private/context.bzl index b902979b0a..c6d42ae44e 100644 --- a/go/private/context.bzl +++ b/go/private/context.bzl @@ -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 _declare_child(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(_declare_child(go, path, ext, name)) + +def _declare_directory(go, path="", ext="", name = ""): + return go.actions.declare_directory(_declare_child(go, path, ext, name)) def _new_args(go): args = go.actions.args() @@ -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( @@ -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 @@ -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, @@ -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( diff --git a/go/private/repositories.bzl b/go/private/repositories.bzl index ad15e45d35..e0f96277b6 100644 --- a/go/private/repositories.bzl +++ b/go/private/repositories.bzl @@ -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") @@ -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", ) diff --git a/go/private/rules/aspect.bzl b/go/private/rules/aspect.bzl index 2473b63996..88f960eef9 100644 --- a/go/private/rules/aspect.bzl +++ b/go/private/rules/aspect.bzl @@ -71,6 +71,7 @@ go_archive_aspect = aspect( "embed", "compiler", "compilers", + "_stdlib", ], attrs = { "pure": attr.string(values = [ diff --git a/go/private/rules/rule.bzl b/go/private/rules/rule.bzl index c59ffcb91c..f2baae2bcf 100644 --- a/go/private/rules/rule.bzl +++ b/go/private/rules/rule.bzl @@ -18,11 +18,14 @@ load( ) 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([k in attrs for k in ["pure", "static", "msan", "race"]]): + 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( diff --git a/go/private/rules/stdlib.bzl b/go/private/rules/stdlib.bzl index 88600bf725..fee9ccb46e 100644 --- a/go/private/rules/stdlib.bzl +++ b/go/private/rules/stdlib.bzl @@ -16,7 +16,8 @@ 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( @@ -24,58 +25,40 @@ load( "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", @@ -83,23 +66,3 @@ stdlib = go_rule( ), }, ) - -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."""