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