diff --git a/go/private/BUILD.sdk.bazel b/go/private/BUILD.sdk.bazel index ea2d5b7494..5d6ce57854 100644 --- a/go/private/BUILD.sdk.bazel +++ b/go/private/BUILD.sdk.bazel @@ -1,23 +1,64 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_sdk") +load("@io_bazel_rules_go//go/toolchain:toolchains.bzl", "declare_toolchains") +load("@io_bazel_rules_go//go/private:rules/sdk.bzl", "package_list") + package(default_visibility = ["//visibility:public"]) filegroup( - name = "files", - srcs = glob([ - "bin/go*", - "src/**", - "pkg/**", - ]), + name = "libs", + srcs = glob( + ["pkg/{goos}_{goarch}/**/*.a"], + exclude = ["pkg/{goos}_{goarch}/**/cmd/**"], + ), +) + +filegroup( + name = "headers", + srcs = glob(["pkg/include/*.h"]), +) + +filegroup( + name = "srcs", + srcs = glob(["src/**"]), ) filegroup( name = "tools", + srcs = glob(["pkg/tool/**"]), +) + +go_sdk( + name = "go_sdk", + goos = "{goos}", + goarch = "{goarch}", + root_file = "ROOT", + package_list = ":package_list", + libs = [":libs"], + headers = [":headers"], + srcs = [":srcs"], + tools = [":tools"], + go = "bin/go{exe}", +) + +# TODO(jayconrod): Gazelle depends on this file directly. This dependency +# should be broken, and this rule should be folded into go_sdk. +package_list( + name = "package_list", + srcs = [":srcs"], + root_file = "ROOT", + out = "packages.txt", +) + +declare_toolchains( + host = "{goos}_{goarch}", + sdk = ":go_sdk", +) + +filegroup( + name = "files", srcs = glob([ "bin/go*", - "pkg/tool/**", - ]) + select({ - "@io_bazel_rules_go//go/platform:darwin_amd64": ["@local_config_cc//:cc_wrapper"], - "//conditions:default": [], - }), + "src/**", + "pkg/**", + ]), ) - -exports_files(["packages.txt", "ROOT"]) diff --git a/go/private/actions/asm.bzl b/go/private/actions/asm.bzl index 847c08ef96..0561272403 100644 --- a/go/private/actions/asm.bzl +++ b/go/private/actions/asm.bzl @@ -33,11 +33,11 @@ def emit_asm( fail("source is a required parameter") out_obj = go.declare_file(go, path = source.basename[:-2], ext = ".o") - inputs = hdrs + go.sdk_tools + go.stdlib.files + [source] + inputs = hdrs + go.sdk.tools + go.sdk.headers + go.stdlib.libs + [source] args = go.args(go) args.add_all([source, "--"]) - includes = ([go.stdlib.root_file.dirname + "/pkg/include"] + + includes = ([go.sdk.root_file.dirname + "/pkg/include"] + [f.dirname for f in hdrs]) # TODO(#1463): use uniquify=True when available. diff --git a/go/private/actions/compile.bzl b/go/private/actions/compile.bzl index 30958852b1..f24517d22d 100644 --- a/go/private/actions/compile.bzl +++ b/go/private/actions/compile.bzl @@ -55,7 +55,7 @@ def emit_compile( inputs = (sources + [go.package_list] + [archive.data.file for archive in archives] + - go.sdk_tools + go.stdlib.files) + go.sdk.tools + go.stdlib.libs) outputs = [out_lib] builder_args = go.args(go) @@ -105,7 +105,7 @@ def _bootstrap_compile(go, sources, out_lib, gc_goopts): args.extend(gc_goopts) args.extend([s.path for s in sources]) go.actions.run_shell( - inputs = sources + go.sdk_files + go.sdk_tools, + inputs = sources + go.sdk.libs + go.sdk.tools + [go.go], outputs = [out_lib], mnemonic = "GoCompile", command = "export GOROOT=$(pwd)/{} && export GOROOT_FINAL=GOROOT && {} {}".format(go.root, go.go.path, " ".join(args)), diff --git a/go/private/actions/cover.bzl b/go/private/actions/cover.bzl index 318e332462..e8edbc5452 100644 --- a/go/private/actions/cover.bzl +++ b/go/private/actions/cover.bzl @@ -56,7 +56,7 @@ def emit_cover(go, source): "-mode=set", ]) go.actions.run( - inputs = [src] + go.sdk_tools, + inputs = [src] + go.sdk.tools, outputs = [out], mnemonic = "GoCover", executable = go.builders.cover, diff --git a/go/private/actions/link.bzl b/go/private/actions/link.bzl index a0fda39b87..74fb965a0a 100644 --- a/go/private/actions/link.bzl +++ b/go/private/actions/link.bzl @@ -141,8 +141,8 @@ def emit_link( archive.cgo_deps, go.crosstool, stamp_inputs, - go.sdk_tools, - go.stdlib.files, + go.sdk.tools, + go.stdlib.libs, ), outputs = [executable], mnemonic = "GoLink", @@ -154,7 +154,7 @@ def emit_link( def _bootstrap_link(go, archive, executable, gc_linkopts): """See go/toolchains.rst#link for full documentation.""" - inputs = [archive.data.file] + go.sdk_files + go.sdk_tools + inputs = [archive.data.file] + go.sdk.libs + go.sdk.tools + [go.go] args = ["tool", "link", "-s", "-o", executable.path] args.extend(gc_linkopts) args.append(archive.data.file.path) diff --git a/go/private/actions/pack.bzl b/go/private/actions/pack.bzl index 63adc5bc91..19808c2562 100644 --- a/go/private/actions/pack.bzl +++ b/go/private/actions/pack.bzl @@ -25,7 +25,7 @@ def emit_pack( if out_lib == None: fail("out_lib is a required parameter") - inputs = [in_lib] + go.sdk_tools + objects + archives + inputs = [in_lib] + go.sdk.tools + objects + archives args = go.args(go) args.add_all(["-in", in_lib]) diff --git a/go/private/context.bzl b/go/private/context.bzl index 61aa90fd5f..04bbd62341 100644 --- a/go/private/context.bzl +++ b/go/private/context.bzl @@ -79,7 +79,7 @@ def _declare_directory(go, path = "", ext = "", name = ""): def _new_args(go): args = go.actions.args() - args.add_all(["-sdk", go.sdk_root.dirname]) + args.add_all(["-sdk", go.sdk.root_file.dirname]) if go.tags: args.add("-tags") args.add_joined(go.tags, join_with = ",") @@ -192,20 +192,6 @@ def _infer_importpath(ctx): importpath = importpath[1:] return importpath, importpath, INFERRED_PATH -def _get_go_binary(context_data): - for f in context_data.sdk_tools: - parent = paths.dirname(f.path) - sdk = paths.dirname(parent) - parent = paths.basename(parent) - if parent != "bin": - continue - basename = paths.basename(f.path) - name, ext = paths.split_extension(basename) - if name != "go": - continue - return f - fail("Could not find go executable in go_sdk") - def go_context(ctx, attr = None): toolchain = ctx.toolchains["@io_bazel_rules_go//go:toolchain"] @@ -230,14 +216,14 @@ def go_context(ctx, attr = None): tags.append("race") if mode.msan: tags.append("msan") - binary = _get_go_binary(context_data) + binary = toolchain.sdk.go stdlib = getattr(attr, "_stdlib", None) if stdlib: stdlib = get_source(stdlib).stdlib goroot = stdlib.root_file.dirname else: - goroot = context_data.sdk_root.dirname + goroot = toolchain.sdk.root_file.dirname env = dict(context_data.env) env.update({ @@ -249,22 +235,31 @@ def go_context(ctx, attr = None): "PATH": context_data.cgo_tools.compiler_path, }) + # TODO(jayconrod): remove this. It's way too broad. Everything should + # depend on more specific lists. + sdk_files = ([toolchain.sdk.go] + + toolchain.sdk.srcs + + toolchain.sdk.headers + + toolchain.sdk.libs + + toolchain.sdk.tools) + importpath, importmap, pathtype = _infer_importpath(ctx) return GoContext( # Fields toolchain = toolchain, + sdk = toolchain.sdk, mode = mode, root = goroot, go = binary, stdlib = stdlib, - sdk_root = context_data.sdk_root, - sdk_files = context_data.sdk_files, - sdk_tools = context_data.sdk_tools, + sdk_root = toolchain.sdk.root_file, + sdk_files = sdk_files, + sdk_tools = toolchain.sdk.tools, actions = ctx.actions, exe_extension = goos_to_extension(mode.goos), shared_extension = goos_to_shared_extension(mode.goos), crosstool = context_data.crosstool, - package_list = context_data.package_list, + package_list = toolchain.sdk.package_list, importpath = importpath, importmap = importmap, pathtype = pathtype, @@ -316,10 +311,6 @@ def _go_context_data(ctx): return struct( strip = ctx.attr.strip, crosstool = ctx.files._crosstool, - package_list = ctx.file._package_list, - sdk_root = ctx.file._sdk_root, - sdk_files = ctx.files._sdk_files, - sdk_tools = ctx.files._sdk_tools, tags = tags, env = env, cgo_tools = struct( @@ -337,26 +328,7 @@ go_context_data = rule( _go_context_data, attrs = { "strip": attr.string(mandatory = True), - # Hidden internal attributes "_crosstool": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), - "_package_list": attr.label( - allow_files = True, - single_file = True, - default = "@go_sdk//:packages.txt", - ), - "_sdk_root": attr.label( - allow_single_file = True, - default = "@go_sdk//:ROOT", - ), - "_sdk_files": attr.label( - allow_files = True, - default = "@go_sdk//:files", - ), - "_sdk_tools": attr.label( - allow_files = True, - cfg = "host", - default = "@go_sdk//:tools", - ), "_xcode_config": attr.label( default = Label("@bazel_tools//tools/osx:current_xcode_config"), ), diff --git a/go/private/go_toolchain.bzl b/go/private/go_toolchain.bzl index 7921abad59..b116beb24b 100644 --- a/go/private/go_toolchain.bzl +++ b/go/private/go_toolchain.bzl @@ -15,6 +15,8 @@ Toolchain rules used by go. """ +load("@io_bazel_rules_go//go/platform:list.bzl", "GOOS_GOARCH") +load("@io_bazel_rules_go//go/private:providers.bzl", "GoSDK") load("@io_bazel_rules_go//go/private:actions/archive.bzl", "emit_archive") load("@io_bazel_rules_go//go/private:actions/asm.bzl", "emit_asm") load("@io_bazel_rules_go//go/private:actions/binary.bzl", "emit_binary") @@ -24,9 +26,11 @@ load("@io_bazel_rules_go//go/private:actions/link.bzl", "emit_link") load("@io_bazel_rules_go//go/private:actions/pack.bzl", "emit_pack") def _go_toolchain_impl(ctx): + sdk = ctx.attr.sdk[GoSDK] + cross_compile = ctx.attr.goos != sdk.goos or ctx.attr.goarch != sdk.goarch return [platform_common.ToolchainInfo( name = ctx.label.name, - cross_compile = ctx.attr.cross_compile, + cross_compile = cross_compile, default_goos = ctx.attr.goos, default_goarch = ctx.attr.goarch, actions = struct( @@ -43,27 +47,43 @@ def _go_toolchain_impl(ctx): link = ctx.attr.link_flags, link_cgo = ctx.attr.cgo_link_flags, ), + sdk = sdk, )] _go_toolchain = rule( _go_toolchain_impl, attrs = { # Minimum requirements to specify a toolchain - "goos": attr.string(mandatory = True), - "goarch": attr.string(mandatory = True), - "cross_compile": attr.bool(default = False), + "goos": attr.string( + mandatory = True, + doc = "Default target OS", + ), + "goarch": attr.string( + mandatory = True, + doc = "Default target architecture", + ), + "sdk": attr.label( + mandatory = True, + providers = [GoSDK], + doc = "The SDK this toolchain is based on", + ), # Optional extras to a toolchain - "link_flags": attr.string_list(default = []), - "cgo_link_flags": attr.string_list(default = []), + "link_flags": attr.string_list( + doc = "Flags passed to the Go internal linker", + ), + "cgo_link_flags": attr.string_list( + doc = "Flags passed to the external linker (if it is used)", + ), }, + doc = "Defines a Go toolchain based on an SDK", + provides = [platform_common.ToolchainInfo], ) -def go_toolchain(name, target, host = None, constraints = [], **kwargs): +def go_toolchain(name, target, sdk, host = None, constraints = [], **kwargs): """See go/toolchains.rst#go-toolchain for full documentation.""" if not host: host = target - cross = host != target goos, _, goarch = target.partition("_") target_constraints = constraints + [ "@io_bazel_rules_go//go/toolchain:" + goos, @@ -80,7 +100,7 @@ def go_toolchain(name, target, host = None, constraints = [], **kwargs): name = impl_name, goos = goos, goarch = goarch, - cross_compile = cross, + sdk = sdk, tags = ["manual"], visibility = ["//visibility:public"], **kwargs @@ -92,3 +112,32 @@ def go_toolchain(name, target, host = None, constraints = [], **kwargs): target_compatible_with = target_constraints, toolchain = ":" + impl_name, ) + +def generate_toolchains(host, sdk): + host_goos, _, host_goarch = host.partition("_") + toolchains = [] + for target_goos, target_goarch in GOOS_GOARCH: + target = "{}_{}".format(target_goos, target_goarch) + toolchain_name = "go_" + target + link_flags = [] + cgo_link_flags = [] + if "darwin" in host: + cgo_link_flags.extend(["-shared", "-Wl,-all_load"]) + if "linux" in host: + cgo_link_flags.append("-Wl,-whole-archive") + + # Add the primary toolchain + toolchains.append(dict( + name = toolchain_name, + host = host, + target = target, + sdk = sdk, + link_flags = link_flags, + cgo_link_flags = cgo_link_flags, + )) + return toolchains + +def generate_toolchain_names(): + # Keep in sync with generate_toolchains + return ["go_{}_{}".format(target_goos, target_goarch) + for target_goos, target_goarch in GOOS_GOARCH] diff --git a/go/private/rules/cgo.bzl b/go/private/rules/cgo.bzl index 5d5179431a..da6463d483 100644 --- a/go/private/rules/cgo.bzl +++ b/go/private/rules/cgo.bzl @@ -190,7 +190,7 @@ def _cgo_codegen_impl(ctx): tool_args.add_all(["-objdir", out_dir]) - inputs = sets.union(ctx.files.srcs, go.crosstool, go.sdk_tools, go.stdlib.files) + inputs = sets.union(ctx.files.srcs, go.crosstool, go.sdk.tools, go.stdlib.libs) deps = depset() runfiles = ctx.runfiles(collect_data = True) for d in ctx.attr.deps: @@ -310,7 +310,7 @@ def _cgo_import_impl(ctx): inputs = [ ctx.file.cgo_o, ctx.files.sample_go_srcs[0], - ] + go.sdk_tools, + ] + go.sdk.tools, outputs = [out], executable = go.builders.cgo, arguments = [args], diff --git a/go/private/rules/info.bzl b/go/private/rules/info.bzl index 68093846c0..f806f82fc2 100644 --- a/go/private/rules/info.bzl +++ b/go/private/rules/info.bzl @@ -27,7 +27,7 @@ def _go_info_impl(ctx): args = go.args(go) args.add_all(["-out", report]) go.actions.run( - inputs = go.stdlib.files, + inputs = [go.go], outputs = [report], mnemonic = "GoInfo", executable = ctx.executable._go_info, diff --git a/go/private/rules/stdlib.bzl b/go/private/rules/stdlib.bzl index 878625ee08..4c76a68de4 100644 --- a/go/private/rules/stdlib.bzl +++ b/go/private/rules/stdlib.bzl @@ -36,7 +36,6 @@ def _stdlib_library_to_source(go, attr, source, merge): src = go.declare_directory(go, "src") root_file = go.declare_file(go, "ROOT") filter_buildid = attr._filter_buildid_builder.files.to_list()[0] - files = [root_file, go.go, pkg] args = go.args(go) args.add_all(["-out", root_file.dirname]) if go.mode.race: @@ -54,9 +53,15 @@ def _stdlib_library_to_source(go, attr, source, merge): "CGO_CFLAGS": " ".join(go.cgo_tools.c_options), "CGO_LDFLAGS": " ".join(go.cgo_tools.linker_options), }) + inputs = (go.sdk.srcs + + go.sdk.headers + + go.sdk.tools + + [go.sdk.go, filter_buildid, go.sdk.package_list, go.sdk.root_file] + + go.crosstool) + outputs = [pkg, src] go.actions.run( - inputs = go.sdk_files + go.sdk_tools + go.crosstool + [filter_buildid, go.package_list, root_file], - outputs = [pkg, src], + inputs = inputs, + outputs = outputs, mnemonic = "GoStdlib", executable = attr._stdlib_builder.files.to_list()[0], arguments = [args], @@ -64,11 +69,7 @@ def _stdlib_library_to_source(go, attr, source, merge): ) source["stdlib"] = GoStdLib( root_file = root_file, - mode = go.mode, libs = [pkg], - headers = [pkg], - srcs = [src], - files = files, ) def _stdlib_impl(ctx): diff --git a/go/private/sdk.bzl b/go/private/sdk.bzl index 49f77d2eed..9a3489778e 100644 --- a/go/private/sdk.bzl +++ b/go/private/sdk.bzl @@ -12,51 +12,42 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@io_bazel_rules_go//go/private:common.bzl", "env_execute", "executable_path") +load( + "@io_bazel_rules_go//go/private:common.bzl", + "env_execute", + "executable_path", +) +load( + "@io_bazel_rules_go//go/private:go_toolchain.bzl", + "generate_toolchains", + "generate_toolchain_names", +) def _go_host_sdk_impl(ctx): path = _detect_host_sdk(ctx) - _sdk_build_file(ctx) + host = _detect_host_platform(ctx) + _sdk_build_file(ctx, host) _local_sdk(ctx, path) - _prepare(ctx) -go_host_sdk = repository_rule( +_go_host_sdk = repository_rule( _go_host_sdk_impl, environ = ["GOROOT"], ) -def _go_download_sdk_impl(ctx): - if ctx.os.name == "linux": - host = "linux_amd64" - res = ctx.execute(["uname", "-p"]) - if res.return_code == 0: - uname = res.stdout.strip() - if uname == "s390x": - host = "linux_s390x" - elif uname == "ppc64le": - host = "linux_ppc64le" - elif uname == "i686": - host = "linux_386" +def go_host_sdk(name, **kwargs): + _go_host_sdk(name = name, **kwargs) + _register_toolchains(name) - # Default to amd64 when uname doesn't return a known value. - - elif ctx.os.name == "mac os x": - host = "darwin_amd64" - elif ctx.os.name.startswith("windows"): - host = "windows_amd64" - elif ctx.os.name == "freebsd": - host = "freebsd_amd64" - else: - fail("Unsupported operating system: " + ctx.os.name) +def _go_download_sdk_impl(ctx): sdks = ctx.attr.sdks + host = _detect_host_platform(ctx) if host not in sdks: fail("Unsupported host {}".format(host)) filename, sha256 = ctx.attr.sdks[host] - _sdk_build_file(ctx) + _sdk_build_file(ctx, host) _remote_sdk(ctx, [url.format(filename) for url in ctx.attr.urls], ctx.attr.strip_prefix, sha256) - _prepare(ctx) -go_download_sdk = repository_rule( +_go_download_sdk = repository_rule( _go_download_sdk_impl, attrs = { "sdks": attr.string_list_dict(), @@ -65,34 +56,30 @@ go_download_sdk = repository_rule( }, ) +def go_download_sdk(name, **kwargs): + _go_download_sdk(name = name, **kwargs) + _register_toolchains(name) + def _go_local_sdk_impl(ctx): - _sdk_build_file(ctx) + host = _detect_host_platform(ctx) + _sdk_build_file(ctx, host) _local_sdk(ctx, ctx.attr.path) - _prepare(ctx) -go_local_sdk = repository_rule( +_go_local_sdk = repository_rule( _go_local_sdk_impl, attrs = { "path": attr.string(), }, ) -def _prepare(ctx): - # Create a text file with a list of standard packages. - # OPT: just list directories under src instead of running "go list". No - # need to read all source files. We need a portable way to run code though. - result = env_execute( - ctx, - arguments = [executable_path(ctx, "./bin/go"), "list", "..."], - environment = { - "GOROOT": str(ctx.path(".")), - "GOPATH": "", - }, - ) - if result.return_code != 0: - fail("failed to list standard packages: code {}:\n{}".format(result.return_code, result.stdout + result.stderr)) - ctx.file("packages.txt", result.stdout) - ctx.file("ROOT", "") +def go_local_sdk(name, **kwargs): + _go_local_sdk(name = name, **kwargs) + _register_toolchains(name) + +def _register_toolchains(repo): + labels = ["@{}//:{}".format(repo, name) + for name in generate_toolchain_names()] + native.register_toolchains(*labels) def _remote_sdk(ctx, urls, strip_prefix, sha256): ctx.download_and_extract( @@ -105,14 +92,46 @@ def _local_sdk(ctx, path): for entry in ["src", "pkg", "bin"]: ctx.symlink(path + "/" + entry, entry) -def _sdk_build_file(ctx): +def _sdk_build_file(ctx, host): ctx.file("ROOT") + goos, _, goarch = host.partition("_") ctx.template( "BUILD.bazel", Label("@io_bazel_rules_go//go/private:BUILD.sdk.bazel"), executable = False, + substitutions = { + "{goos}": goos, + "{goarch}": goarch, + "{exe}": ".exe" if goos == "windows" else "", + }, ) +def _detect_host_platform(ctx): + if ctx.os.name == "linux": + host = "linux_amd64" + res = ctx.execute(["uname", "-p"]) + if res.return_code == 0: + uname = res.stdout.strip() + if uname == "s390x": + host = "linux_s390x" + elif uname == "ppc64le": + host = "linux_ppc64le" + elif uname == "i686": + host = "linux_386" + + # Default to amd64 when uname doesn't return a known value. + + elif ctx.os.name == "mac os x": + host = "darwin_amd64" + elif ctx.os.name.startswith("windows"): + host = "windows_amd64" + elif ctx.os.name == "freebsd": + host = "freebsd_amd64" + else: + fail("Unsupported operating system: " + ctx.os.name) + + return host + def _detect_host_sdk(ctx): root = "@invalid@" if "GOROOT" in ctx.os.environ: diff --git a/go/private/tools/vet.bzl b/go/private/tools/vet.bzl index 187b8e7b25..d1e0edfb48 100644 --- a/go/private/tools/vet.bzl +++ b/go/private/tools/vet.bzl @@ -33,7 +33,12 @@ Please do not rely on it for production use, but feel free to use it and file is go = go_context(ctx) script_file = go.declare_file(go, ext = ".bash") gopath = [] - files = ctx.files.data + go.stdlib.files + runfiles = ctx.runfiles( + files = ctx.files.data + go.stdlib.libs + go.sdk.tools + [go.go], + collect_data = True, + ) + root_file = go.stdlib.root_file.short_path + goroot, _, _ = root_file.rpartition("/") gopath = [] packages = [] for data in ctx.attr.data: @@ -42,16 +47,18 @@ Please do not rely on it for production use, but feel free to use it and file is packages += [entry.gopath + "/" + package.dir for package in entry.packages] ctx.actions.write(output = script_file, is_executable = True, content = """ export GOPATH="{gopath}" +export GOROOT="$(pwd)/{goroot}" {go} tool vet {packages} """.format( go = go.go.short_path, - gopath = ":".join(["$(pwd)/{})".format(entry) for entry in gopath]), + goroot = goroot, + gopath = ":".join(["$(pwd)/{}".format(entry) for entry in gopath]), packages = " ".join(packages), )) - return struct( + return [DefaultInfo( files = depset([script_file]), - runfiles = ctx.runfiles(files, collect_data = True), - ) + runfiles = runfiles, + )] _go_vet_generate = go_rule( _go_vet_generate_impl, diff --git a/go/toolchain/BUILD.bazel b/go/toolchain/BUILD.bazel index dbff580785..65fa47664d 100644 --- a/go/toolchain/BUILD.bazel +++ b/go/toolchain/BUILD.bazel @@ -1,11 +1,8 @@ load( ":toolchains.bzl", "declare_constraints", - "declare_toolchains", ) package(default_visibility = ["//visibility:public"]) -declare_toolchains() - declare_constraints() diff --git a/go/toolchain/toolchains.bzl b/go/toolchain/toolchains.bzl index ef64c2e27e..72348e67d1 100644 --- a/go/toolchain/toolchains.bzl +++ b/go/toolchain/toolchains.bzl @@ -1,5 +1,6 @@ load( "//go/private:go_toolchain.bzl", + "generate_toolchains", "go_toolchain", ) load( @@ -181,35 +182,6 @@ SDK_REPOSITORIES = { }, } -def _generate_toolchains(): - # Use all the above information to generate all the possible toolchains we might support - toolchains = [] - for host_goos, host_goarch in GOOS_GOARCH: - host = "{}_{}".format(host_goos, host_goarch) - for target_goos, target_goarch in GOOS_GOARCH: - target = "{}_{}".format(target_goos, target_goarch) - toolchain_name = "go_{}".format(host) - if host != target: - toolchain_name += "_cross_" + target - link_flags = [] - cgo_link_flags = [] - if "darwin" in host: - cgo_link_flags.extend(["-shared", "-Wl,-all_load"]) - if "linux" in host: - cgo_link_flags.append("-Wl,-whole-archive") - - # Add the primary toolchain - toolchains.append(dict( - name = toolchain_name, - host = host, - target = target, - link_flags = link_flags, - cgo_link_flags = cgo_link_flags, - )) - return toolchains - -_toolchains = _generate_toolchains() - _label_prefix = "@io_bazel_rules_go//go/toolchain:" def go_register_toolchains(go_version = DEFAULT_VERSION): @@ -229,11 +201,6 @@ def go_register_toolchains(go_version = DEFAULT_VERSION): else: fail("Unknown go version {}".format(go_version)) - # Use the final dictionaries to register all the toolchains - for toolchain in _toolchains: - name = _label_prefix + toolchain["name"] - native.register_toolchains(name) - def declare_constraints(): for goos, constraint in GOOS.items(): if constraint: @@ -266,15 +233,7 @@ def declare_constraints(): ], ) -def declare_toolchains(): +def declare_toolchains(host, sdk): # Use the final dictionaries to create all the toolchains - for toolchain in _toolchains: - go_toolchain( - # Required fields - name = toolchain["name"], - host = toolchain["host"], - target = toolchain["target"], - # Optional fields - link_flags = toolchain["link_flags"], - cgo_link_flags = toolchain["cgo_link_flags"], - ) + for toolchain in generate_toolchains(host, sdk): + go_toolchain(**toolchain) diff --git a/tests/bazel_tests.bzl b/tests/bazel_tests.bzl index 62aae753f8..bdc07e79e8 100644 --- a/tests/bazel_tests.bzl +++ b/tests/bazel_tests.bzl @@ -6,6 +6,10 @@ load( "@io_bazel_rules_go//go/private:common.bzl", "env_execute", ) +load( + "@io_bazel_rules_go//go/private:go_toolchain.bzl", + "generate_toolchain_names", +) load( "@io_bazel_rules_go//go/private:rules/rule.bzl", "go_rule", @@ -135,10 +139,15 @@ def _bazel_test_script_impl(ctx): ctx.actions.write(script_file, "", is_executable = True) return [DefaultInfo(files = depset([script_file]))] + register = "" + if any([ext.label.workspace_root.endswith("/go_sdk") for ext in ctx.attr.externals]): + register += "register_toolchains(\n{}\n)\n".format( + "\n".join([' "@go_sdk//:{}",'.format(name) + for name in generate_toolchain_names()])) if ctx.attr.go_version == CURRENT_VERSION: - register = "go_register_toolchains()\n" + register += "go_register_toolchains()\n" elif ctx.attr.go_version != None: - register = 'go_register_toolchains(go_version="{}")\n'.format(ctx.attr.go_version) + register += 'go_register_toolchains(go_version="{}")\n'.format(ctx.attr.go_version) workspace_content = 'workspace(name = "bazel_test")\n\n' for ext in ctx.attr.externals: diff --git a/tests/core/stdlib/stdlib_files.bzl b/tests/core/stdlib/stdlib_files.bzl index b42d02e310..ec34d3fd16 100644 --- a/tests/core/stdlib/stdlib_files.bzl +++ b/tests/core/stdlib/stdlib_files.bzl @@ -12,19 +12,24 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("@io_bazel_rules_go//go:def.bzl", "go_context", "go_rule") load("@io_bazel_rules_go//go/private:providers.bzl", "GoSource") def _stdlib_files_impl(ctx): - files = ctx.attr._stdlib[GoSource].stdlib.files - runfiles = ctx.runfiles(files = files) + go = go_context(ctx) + libs = go.stdlib.libs + runfiles = ctx.runfiles(files = libs + go.sdk.tools) return [DefaultInfo( - files = depset(files), + files = depset(libs), runfiles = runfiles, )] -stdlib_files = rule( +stdlib_files = go_rule( _stdlib_files_impl, attrs = { - "_stdlib": attr.label(default = "@io_bazel_rules_go//:stdlib"), + "pure": attr.string(default = "on"), # force recompilation + "static": attr.string(default = "off"), + "msan": attr.string(default = "off"), + "race": attr.string(default = "off"), }, ) diff --git a/tests/legacy/custom_go_toolchain/BUILD.bazel b/tests/legacy/custom_go_toolchain/BUILD.bazel index dddf178e2f..da3113207e 100644 --- a/tests/legacy/custom_go_toolchain/BUILD.bazel +++ b/tests/legacy/custom_go_toolchain/BUILD.bazel @@ -10,11 +10,6 @@ go_test( bazel_test( name = "custom_go_toolchain", - build = """ -load("@io_bazel_rules_go//go:def.bzl", "go_toolchain") -go_toolchain(name="my_linux_toolchain", target="linux_amd64") -go_toolchain(name="my_darwin_toolchain", target="darwin_amd64") -""", command = "test", config = "fetch", go_version = "", @@ -32,10 +27,6 @@ go_download_sdk( "darwin_amd64": ("go1.10.1.darwin-amd64.tar.gz", "0a5bbcbbb0d150338ba346151d2864fd326873beaedf964e2057008c8a4dc557"), }, ) -register_toolchains( - "@//:my_linux_toolchain", - "@//:my_darwin_toolchain", -) go_rules_dependencies()