diff --git a/go/private/actions/archive.bzl b/go/private/actions/archive.bzl new file mode 100644 index 0000000000..3e55c21630 --- /dev/null +++ b/go/private/actions/archive.bzl @@ -0,0 +1,82 @@ +# 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. + +load("@io_bazel_rules_go//go/private:common.bzl", + "split_srcs", +) +load("@io_bazel_rules_go//go/private:mode.bzl", + "mode_string", +) +load("@io_bazel_rules_go//go/private:providers.bzl", + "GoArchive", +) + +def emit_archive(ctx, go_toolchain, + importpath = "", + srcs = (), + direct = (), + cgo_info = None, + importable = True, + mode = None, + gc_goopts = ()): + """See go/toolchains.rst#archive for full documentation.""" + + source = split_srcs(srcs) + lib_name = importpath + ".a" + compilepath = importpath if importable else None + out_dir = "~{}~{}~".format(mode_string(mode), ctx.label.name) + out_lib = ctx.new_file("{}/{}".format(out_dir, lib_name)) + searchpath = out_lib.path[:-len(lib_name)] + + extra_objects = [] + for src in source.asm: + obj = ctx.new_file(src, "%s.dir/%s.o" % (ctx.label.name, src.basename[:-2])) + go_toolchain.actions.asm(ctx, go_toolchain, src, source.headers, obj) + extra_objects += [obj] + archive = cgo_info.archive if cgo_info else None + + if len(extra_objects) == 0 and archive == None: + go_toolchain.actions.compile(ctx, + go_toolchain = go_toolchain, + sources = source.go, + importpath = compilepath, + golibs = direct, + mode = mode, + out_lib = out_lib, + gc_goopts = gc_goopts, + ) + else: + partial_lib = ctx.new_file("{}/~partial.a".format(out_dir)) + go_toolchain.actions.compile(ctx, + go_toolchain = go_toolchain, + sources = source.go, + importpath = compilepath, + golibs = direct, + mode = mode, + out_lib = partial_lib, + gc_goopts = gc_goopts, + ) + go_toolchain.actions.pack(ctx, + go_toolchain = go_toolchain, + in_lib = partial_lib, + out_lib = out_lib, + objects = extra_objects, + archive = archive, + ) + + return GoArchive( + lib = out_lib, + mode = mode, + searchpath = searchpath, + ) diff --git a/go/private/actions/library.bzl b/go/private/actions/library.bzl index 2bc75e5563..0740215844 100644 --- a/go/private/actions/library.bzl +++ b/go/private/actions/library.bzl @@ -25,8 +25,6 @@ load("@io_bazel_rules_go//go/private:providers.bzl", "CgoInfo", "GoLibrary", "GoEmbed", - "library_attr", - "searchpath_attr", ) def emit_library(ctx, go_toolchain, @@ -75,13 +73,6 @@ def emit_library(ctx, go_toolchain, if cgo_info: dep_runfiles += [cgo_info.runfiles] - extra_objects = [] - for src in source.asm: - obj = ctx.new_file(src, "%s.dir/%s.o" % (ctx.label.name, src.basename[:-2])) - go_toolchain.actions.asm(ctx, go_toolchain, src, source.headers, obj) - extra_objects += [obj] - archive = cgo_info.archive if cgo_info else None - for dep in deps: direct += [dep[GoLibrary]] @@ -94,43 +85,22 @@ def emit_library(ctx, go_toolchain, go_srcs, cvars = go_toolchain.actions.cover(ctx, go_toolchain, go_srcs) cover_vars += cvars - lib_name = importpath + ".a" - compilepath = importpath if importable else None + transformed = dict_of(source) + transformed["go"] = go_srcs + + build_srcs = join_srcs(struct(**transformed)) mode_fields = {} # These are added to the GoLibrary provider directly for mode in common_modes: - out_dir = "~{}~{}~".format(mode_string(mode), ctx.label.name) - out_lib = ctx.new_file("{}/{}".format(out_dir, lib_name)) - searchpath = out_lib.path[:-len(lib_name)] - mode_fields[library_attr(mode)] = out_lib - mode_fields[searchpath_attr(mode)] = searchpath - if len(extra_objects) == 0 and archive == None: - go_toolchain.actions.compile(ctx, - go_toolchain = go_toolchain, - sources = go_srcs, - importpath = compilepath, - golibs = direct, - mode = mode, - out_lib = out_lib, - gc_goopts = gc_goopts, - ) - else: - partial_lib = ctx.new_file("{}/~partial.a".format(out_dir)) - go_toolchain.actions.compile(ctx, - go_toolchain = go_toolchain, - sources = go_srcs, - importpath = compilepath, - golibs = direct, - mode = mode, - out_lib = partial_lib, - gc_goopts = gc_goopts, - ) - go_toolchain.actions.pack(ctx, - go_toolchain = go_toolchain, - in_lib = partial_lib, - out_lib = out_lib, - objects = extra_objects, - archive = archive, - ) + mode_fields[mode_string(mode)] = go_toolchain.actions.archive(ctx, + go_toolchain = go_toolchain, + importpath = importpath, + srcs = build_srcs, + direct = direct, + cgo_info =cgo_info, + importable = importable, + mode = mode, + gc_goopts = gc_goopts, + ) dylibs = [] cgo_deps = depset() @@ -142,9 +112,6 @@ def emit_library(ctx, go_toolchain, for d in dep_runfiles: runfiles = runfiles.merge(d) - transformed = dict_of(source) - transformed["go"] = go_srcs - return [ GoLibrary( label = ctx.label, @@ -159,7 +126,7 @@ def emit_library(ctx, go_toolchain, ), GoEmbed( srcs = srcs, # The original sources - build_srcs = join_srcs(struct(**transformed)), # The transformed sources actually compiled + build_srcs = build_srcs, # The transformed sources actually compiled deps = direct, # The direct depencancies of the library cover_vars = cover_vars, # The cover variables for these sources cgo_info = cgo_info, # The cgo information for this library or one of its embeds. diff --git a/go/private/go_toolchain.bzl b/go/private/go_toolchain.bzl index 97d24558ca..fc62c1c240 100644 --- a/go/private/go_toolchain.bzl +++ b/go/private/go_toolchain.bzl @@ -14,6 +14,7 @@ """ Toolchain rules used by go. """ +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") load("@io_bazel_rules_go//go/private:actions/compile.bzl", "emit_compile", "bootstrap_compile") @@ -44,6 +45,7 @@ def _go_toolchain_impl(ctx): get = _get_stdlib, ), actions = struct( + archive = emit_archive, asm = emit_asm, binary = emit_binary, compile = emit_compile if ctx.executable._compile else bootstrap_compile, diff --git a/go/private/providers.bzl b/go/private/providers.bzl index 481a45b581..b81623abe6 100644 --- a/go/private/providers.bzl +++ b/go/private/providers.bzl @@ -25,30 +25,19 @@ GoPath = provider() GoEmbed = provider() """See go/providers.rst#GoEmbed for full documentation.""" +GoArchive = provider() +"""See go/providers.rst#GoArchive for full documentation.""" + CgoInfo = provider() GoStdLib = provider() -def library_attr(mode): - """Returns the attribute name for the library of the given mode. - - mode must a struct returned by common.bzl#mode - """ - return mode_string(mode)+"_library" - def get_library(golib, mode): """Returns the compiled library for the given mode golib must be a GoLibrary mode must a struct returned by common.bzl#mode """ - return getattr(golib, library_attr(mode)) - -def searchpath_attr(mode): - """Returns the search path for the given mode - - mode must a struct returned by common.bzl#mode - """ - return mode_string(mode)+"_searchpath" + return getattr(golib, mode_string(mode)).lib def get_searchpath(golib, mode): """Returns the search path for the given mode @@ -56,6 +45,5 @@ def get_searchpath(golib, mode): golib must be a GoLibrary mode must a struct returned by common.bzl#mode """ - return getattr(golib, searchpath_attr(mode)) - + return getattr(golib, mode_string(mode)).searchpath diff --git a/go/providers.rst b/go/providers.rst index 685ebacb3e..c4a9a570c0 100644 --- a/go/providers.rst +++ b/go/providers.rst @@ -79,21 +79,13 @@ binaries or tests. +--------------------------------+-----------------------------------------------------------------+ | The files needed to run anything that includes this library. | +--------------------------------+-----------------------------------------------------------------+ -| :param:`normal_library` | :type:`File` | +| :param:`normal` | :type:`GoArchive` | +--------------------------------+-----------------------------------------------------------------+ -| The archive file representing the library compiled with the default options. | +| The GoArchive provider representing the library compiled with the default options. | +--------------------------------+-----------------------------------------------------------------+ -| :param:`normal_searchpath` | :type:`string` | +| :param:`race` | :type:`GoArchive` | +--------------------------------+-----------------------------------------------------------------+ -| The search path entry under which the :param:`normal_library` would be found. | -+--------------------------------+-----------------------------------------------------------------+ -| :param:`race_library` | :type:`File` | -+--------------------------------+-----------------------------------------------------------------+ -| The archive file representing the library compiled with the race detector enabled. | -+--------------------------------+-----------------------------------------------------------------+ -| :param:`race_searchpath` | :type:`string` | -+--------------------------------+-----------------------------------------------------------------+ -| The search path entry under which the :param:`race_library` would be found. | +| The GoArchive provider representing the library compiled with the race detector enabled. | +--------------------------------+-----------------------------------------------------------------+ @@ -152,6 +144,29 @@ There are two main uses for this. +--------------------------------+-----------------------------------------------------------------+ +GoArchive +~~~~~~~~~ + +GoArchive is a provider that exposes a compiled library. + ++--------------------------------+-----------------------------------------------------------------+ +| **Name** | **Type** | ++--------------------------------+-----------------------------------------------------------------+ +| :param:`lib` | :type:`compiled archive file` | ++--------------------------------+-----------------------------------------------------------------+ +| The archive file representing the library compiled in a specific :param:`mode` ready for linking | +| into binaries. | ++--------------------------------+-----------------------------------------------------------------+ +| :param:`searchpath` | :type:`string` | ++--------------------------------+-----------------------------------------------------------------+ +| The search path entry under which the :param:`lib` would be found. | ++--------------------------------+-----------------------------------------------------------------+ +| :param:`mode` | :type:`Mode` | ++--------------------------------+-----------------------------------------------------------------+ +| The mode the library was compiled in. | ++--------------------------------+-----------------------------------------------------------------+ + + GoBinary ~~~~~~~~