...

Text file src/github.com/bazelbuild/rules_go/go/private/actions/archive.bzl

Documentation: github.com/bazelbuild/rules_go/go/private/actions

     1# Copyright 2014 The Bazel Authors. All rights reserved.
     2#
     3# Licensed under the Apache License, Version 2.0 (the "License");
     4# you may not use this file except in compliance with the License.
     5# You may obtain a copy of the License at
     6#
     7#    http://www.apache.org/licenses/LICENSE-2.0
     8#
     9# Unless required by applicable law or agreed to in writing, software
    10# distributed under the License is distributed on an "AS IS" BASIS,
    11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12# See the License for the specific language governing permissions and
    13# limitations under the License.
    14
    15load(
    16    "//go/private:common.bzl",
    17    "as_tuple",
    18    "split_srcs",
    19)
    20load(
    21    "//go/private:mode.bzl",
    22    "LINKMODE_C_ARCHIVE",
    23    "LINKMODE_C_SHARED",
    24    "mode_string",
    25)
    26load(
    27    "//go/private:providers.bzl",
    28    "GoArchive",
    29    "GoArchiveData",
    30    "effective_importpath_pkgpath",
    31    "get_archive",
    32)
    33load(
    34    "//go/private/rules:cgo.bzl",
    35    "cgo_configure",
    36)
    37load(
    38    "//go/private/actions:compilepkg.bzl",
    39    "emit_compilepkg",
    40)
    41
    42def emit_archive(go, source = None, _recompile_suffix = "", recompile_internal_deps = None):
    43    """See go/toolchains.rst#archive for full documentation."""
    44
    45    if source == None:
    46        fail("source is a required parameter")
    47
    48    split = split_srcs(source.srcs)
    49    testfilter = getattr(source.library, "testfilter", None)
    50    pre_ext = ""
    51    if go.mode.link == LINKMODE_C_ARCHIVE:
    52        pre_ext = "_"  # avoid collision with go_binary output file with .a extension
    53    elif testfilter == "exclude":
    54        pre_ext = ".internal"
    55    elif testfilter == "only":
    56        pre_ext = ".external"
    57    if _recompile_suffix:
    58        pre_ext += _recompile_suffix
    59    out_lib = go.declare_file(go, name = source.library.name, ext = pre_ext + ".a")
    60
    61    # store export information for compiling dependent packages separately
    62    out_export = go.declare_file(go, name = source.library.name, ext = pre_ext + ".x")
    63    out_cgo_export_h = None  # set if cgo used in c-shared or c-archive mode
    64    out_facts = None
    65    nogo = go.get_nogo(go)
    66    if nogo:
    67        out_facts = go.declare_file(go, name = source.library.name, ext = pre_ext + ".facts")
    68
    69    direct = [get_archive(dep) for dep in source.deps]
    70    runfiles = source.runfiles
    71    data_files = runfiles.files
    72
    73    files = []
    74    for a in direct:
    75        files.append(a.runfiles)
    76        if a.source.mode != go.mode:
    77            fail("Archive mode does not match {} is {} expected {}".format(a.data.label, mode_string(a.source.mode), mode_string(go.mode)))
    78    runfiles.merge_all(files)
    79
    80    importmap = "main" if source.library.is_main else source.library.importmap
    81    importpath, _ = effective_importpath_pkgpath(source.library)
    82
    83    if source.cgo and not go.mode.pure:
    84        # TODO(jayconrod): do we need to do full Bourne tokenization here?
    85        cppopts = [f for fs in source.cppopts for f in fs.split(" ")]
    86        copts = [f for fs in source.copts for f in fs.split(" ")]
    87        cxxopts = [f for fs in source.cxxopts for f in fs.split(" ")]
    88        clinkopts = [f for fs in source.clinkopts for f in fs.split(" ")]
    89        cgo = cgo_configure(
    90            go,
    91            srcs = split.go + split.c + split.asm + split.cxx + split.objc + split.headers,
    92            cdeps = source.cdeps,
    93            cppopts = cppopts,
    94            copts = copts,
    95            cxxopts = cxxopts,
    96            clinkopts = clinkopts,
    97        )
    98        if go.mode.link in (LINKMODE_C_SHARED, LINKMODE_C_ARCHIVE):
    99            out_cgo_export_h = go.declare_file(go, path = "_cgo_install.h")
   100        cgo_deps = cgo.deps
   101        runfiles = runfiles.merge(cgo.runfiles)
   102        emit_compilepkg(
   103            go,
   104            sources = split.go + split.c + split.asm + split.cxx + split.objc + split.headers,
   105            cover = source.cover,
   106            embedsrcs = source.embedsrcs,
   107            importpath = importpath,
   108            importmap = importmap,
   109            archives = direct,
   110            out_lib = out_lib,
   111            out_export = out_export,
   112            out_facts = out_facts,
   113            nogo = nogo,
   114            out_cgo_export_h = out_cgo_export_h,
   115            gc_goopts = source.gc_goopts,
   116            cgo = True,
   117            cgo_inputs = cgo.inputs,
   118            cppopts = cgo.cppopts,
   119            copts = cgo.copts,
   120            cxxopts = cgo.cxxopts,
   121            objcopts = cgo.objcopts,
   122            objcxxopts = cgo.objcxxopts,
   123            clinkopts = cgo.clinkopts,
   124            testfilter = testfilter,
   125        )
   126    else:
   127        cgo_deps = depset()
   128        emit_compilepkg(
   129            go,
   130            sources = split.go + split.c + split.asm + split.cxx + split.objc + split.headers,
   131            cover = source.cover,
   132            embedsrcs = source.embedsrcs,
   133            importpath = importpath,
   134            importmap = importmap,
   135            archives = direct,
   136            out_lib = out_lib,
   137            out_export = out_export,
   138            out_facts = out_facts,
   139            nogo = nogo,
   140            gc_goopts = source.gc_goopts,
   141            cgo = False,
   142            testfilter = testfilter,
   143            recompile_internal_deps = recompile_internal_deps,
   144        )
   145
   146    data = GoArchiveData(
   147        # TODO(#2578): reconsider the provider API. There's a lot of redundant
   148        # information here. Some fields are tuples instead of lists or dicts
   149        # since GoArchiveData is stored in a depset, and no value in a depset
   150        # may be mutable. For now, new copied fields are private (named with
   151        # a leading underscore) since they may change in the future.
   152
   153        # GoLibrary fields
   154        name = source.library.name,
   155        label = source.library.label,
   156        importpath = source.library.importpath,
   157        importmap = source.library.importmap,
   158        importpath_aliases = source.library.importpath_aliases,
   159        pathtype = source.library.pathtype,
   160
   161        # GoSource fields
   162        srcs = as_tuple(source.srcs),
   163        orig_srcs = as_tuple(source.orig_srcs),
   164        _orig_src_map = tuple([source.orig_src_map.get(src, src) for src in source.srcs]),
   165        _cover = as_tuple(source.cover),
   166        _embedsrcs = as_tuple(source.embedsrcs),
   167        _x_defs = tuple(source.x_defs.items()),
   168        _gc_goopts = as_tuple(source.gc_goopts),
   169        _cgo = source.cgo,
   170        _cdeps = as_tuple(source.cdeps),
   171        _cppopts = as_tuple(source.cppopts),
   172        _copts = as_tuple(source.copts),
   173        _cxxopts = as_tuple(source.cxxopts),
   174        _clinkopts = as_tuple(source.clinkopts),
   175        _cgo_exports = as_tuple(source.cgo_exports),
   176
   177        # Information on dependencies
   178        _dep_labels = tuple([d.data.label for d in direct]),
   179        _dep_importmaps = tuple([d.data.importmap for d in direct]),
   180
   181        # Information needed by dependents
   182        file = out_lib,
   183        export_file = out_export,
   184        facts_file = out_facts,
   185        data_files = as_tuple(data_files),
   186        _cgo_deps = as_tuple(cgo_deps),
   187    )
   188    x_defs = dict(source.x_defs)
   189    for a in direct:
   190        x_defs.update(a.x_defs)
   191    cgo_exports_direct = list(source.cgo_exports)
   192
   193    # Ensure that the _cgo_export.h of the current target comes first when cgo_exports is iterated
   194    # by prepending it and specifying the order explicitly. This is required as the CcInfo attached
   195    # to the archive only exposes a single header rather than combining all headers.
   196    if out_cgo_export_h:
   197        cgo_exports_direct.insert(0, out_cgo_export_h)
   198    cgo_exports = depset(direct = cgo_exports_direct, transitive = [a.cgo_exports for a in direct], order = "preorder")
   199    return GoArchive(
   200        source = source,
   201        data = data,
   202        direct = direct,
   203        libs = depset(direct = [out_lib], transitive = [a.libs for a in direct]),
   204        transitive = depset([data], transitive = [a.transitive for a in direct]),
   205        x_defs = x_defs,
   206        cgo_deps = depset(transitive = [cgo_deps] + [a.cgo_deps for a in direct]),
   207        cgo_exports = cgo_exports,
   208        runfiles = runfiles,
   209        mode = go.mode,
   210    )

View as plain text