Skip to content

Commit

Permalink
Separate GoArchive from GoLibrary (bazel-contrib#966)
Browse files Browse the repository at this point in the history
actions.library is now responsible for preparing a go_library, whereas
ations.archive is repsonsible for compiling a library to a linkable archive.
At the moment actions.archive is only called from inside actions.library, and
the behvaiour of the system has not changed.
  • Loading branch information
ianthehat authored Oct 27, 2017
1 parent 0193bb6 commit bcc7a4f
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 77 deletions.
82 changes: 82 additions & 0 deletions go/private/actions/archive.bzl
Original file line number Diff line number Diff line change
@@ -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,
)
63 changes: 15 additions & 48 deletions go/private/actions/library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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]]

Expand All @@ -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()
Expand All @@ -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,
Expand All @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions go/private/go_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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,
Expand Down
22 changes: 5 additions & 17 deletions go/private/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -25,37 +25,25 @@ 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
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

39 changes: 27 additions & 12 deletions go/providers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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. |
+--------------------------------+-----------------------------------------------------------------+


Expand Down Expand Up @@ -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
~~~~~~~~

Expand Down

0 comments on commit bcc7a4f

Please sign in to comment.