xref: /aosp_15_r20/external/bazelbuild-rules_go/go/private/actions/stdlib.bzl (revision 9bb1b549b6a84214c53be0924760be030e66b93a)
1*9bb1b549SSpandan Das# Copyright 2019 The Bazel Go Rules 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    "COVERAGE_OPTIONS_DENYLIST",
18*9bb1b549SSpandan Das)
19*9bb1b549SSpandan Dasload(
20*9bb1b549SSpandan Das    "//go/private:providers.bzl",
21*9bb1b549SSpandan Das    "GoStdLib",
22*9bb1b549SSpandan Das)
23*9bb1b549SSpandan Dasload(
24*9bb1b549SSpandan Das    "//go/private:mode.bzl",
25*9bb1b549SSpandan Das    "LINKMODE_NORMAL",
26*9bb1b549SSpandan Das    "extldflags_from_cc_toolchain",
27*9bb1b549SSpandan Das    "link_mode_args",
28*9bb1b549SSpandan Das)
29*9bb1b549SSpandan Dasload("//go/private:sdk.bzl", "parse_version")
30*9bb1b549SSpandan Dasload("//go/private/actions:utils.bzl", "quote_opts")
31*9bb1b549SSpandan Das
32*9bb1b549SSpandan Dasdef emit_stdlib(go):
33*9bb1b549SSpandan Das    """Returns a standard library for the target configuration.
34*9bb1b549SSpandan Das
35*9bb1b549SSpandan Das    If the precompiled standard library is suitable, it will be returned.
36*9bb1b549SSpandan Das    Otherwise, the standard library will be compiled for the target.
37*9bb1b549SSpandan Das
38*9bb1b549SSpandan Das    Returns:
39*9bb1b549SSpandan Das        A list of providers containing GoLibrary and GoSource. GoSource.stdlib
40*9bb1b549SSpandan Das        will point to a new GoStdLib.
41*9bb1b549SSpandan Das    """
42*9bb1b549SSpandan Das    library = go.new_library(go, resolver = _stdlib_library_to_source)
43*9bb1b549SSpandan Das    source = go.library_to_source(go, {}, library, False)
44*9bb1b549SSpandan Das    return [source, library]
45*9bb1b549SSpandan Das
46*9bb1b549SSpandan Dasdef _stdlib_library_to_source(go, _attr, source, _merge):
47*9bb1b549SSpandan Das    if _should_use_sdk_stdlib(go):
48*9bb1b549SSpandan Das        source["stdlib"] = _sdk_stdlib(go)
49*9bb1b549SSpandan Das    else:
50*9bb1b549SSpandan Das        source["stdlib"] = _build_stdlib(go)
51*9bb1b549SSpandan Das
52*9bb1b549SSpandan Dasdef _should_use_sdk_stdlib(go):
53*9bb1b549SSpandan Das    version = parse_version(go.sdk.version)
54*9bb1b549SSpandan Das    if version and version[0] <= 1 and version[1] <= 19 and go.sdk.experiments:
55*9bb1b549SSpandan Das        # The precompiled stdlib shipped with 1.19 or below doesn't have experiments
56*9bb1b549SSpandan Das        return False
57*9bb1b549SSpandan Das    return (go.sdk.libs and  # go.sdk.libs is non-empty if sdk ships with precompiled .a files
58*9bb1b549SSpandan Das            go.mode.goos == go.sdk.goos and
59*9bb1b549SSpandan Das            go.mode.goarch == go.sdk.goarch and
60*9bb1b549SSpandan Das            not go.mode.race and  # TODO(jayconrod): use precompiled race
61*9bb1b549SSpandan Das            not go.mode.msan and
62*9bb1b549SSpandan Das            not go.mode.pure and
63*9bb1b549SSpandan Das            not go.mode.gc_goopts and
64*9bb1b549SSpandan Das            go.mode.link == LINKMODE_NORMAL)
65*9bb1b549SSpandan Das
66*9bb1b549SSpandan Dasdef _build_stdlib_list_json(go):
67*9bb1b549SSpandan Das    out = go.declare_file(go, "stdlib.pkg.json")
68*9bb1b549SSpandan Das    args = go.builder_args(go, "stdliblist")
69*9bb1b549SSpandan Das    args.add("-sdk", go.sdk.root_file.dirname)
70*9bb1b549SSpandan Das    args.add("-out", out)
71*9bb1b549SSpandan Das
72*9bb1b549SSpandan Das    inputs = go.sdk_files
73*9bb1b549SSpandan Das    if not go.mode.pure:
74*9bb1b549SSpandan Das        inputs += go.crosstool
75*9bb1b549SSpandan Das
76*9bb1b549SSpandan Das    go.actions.run(
77*9bb1b549SSpandan Das        inputs = inputs,
78*9bb1b549SSpandan Das        outputs = [out],
79*9bb1b549SSpandan Das        mnemonic = "GoStdlibList",
80*9bb1b549SSpandan Das        executable = go.toolchain._builder,
81*9bb1b549SSpandan Das        arguments = [args],
82*9bb1b549SSpandan Das        env = _build_env(go),
83*9bb1b549SSpandan Das    )
84*9bb1b549SSpandan Das    return out
85*9bb1b549SSpandan Das
86*9bb1b549SSpandan Dasdef _build_env(go):
87*9bb1b549SSpandan Das    env = go.env
88*9bb1b549SSpandan Das
89*9bb1b549SSpandan Das    if go.mode.pure:
90*9bb1b549SSpandan Das        env.update({"CGO_ENABLED": "0"})
91*9bb1b549SSpandan Das        return env
92*9bb1b549SSpandan Das
93*9bb1b549SSpandan Das    # NOTE(#2545): avoid unnecessary dynamic link
94*9bb1b549SSpandan Das    # go std library doesn't use C++, so should not have -lstdc++
95*9bb1b549SSpandan Das    # Also drop coverage flags as nothing in the stdlib is compiled with
96*9bb1b549SSpandan Das    # coverage - we disable it for all CGo code anyway.
97*9bb1b549SSpandan Das    ldflags = [
98*9bb1b549SSpandan Das        option
99*9bb1b549SSpandan Das        for option in extldflags_from_cc_toolchain(go)
100*9bb1b549SSpandan Das        if option not in ("-lstdc++", "-lc++") and option not in COVERAGE_OPTIONS_DENYLIST
101*9bb1b549SSpandan Das    ]
102*9bb1b549SSpandan Das    env.update({
103*9bb1b549SSpandan Das        "CGO_ENABLED": "1",
104*9bb1b549SSpandan Das        "CC": go.cgo_tools.c_compiler_path,
105*9bb1b549SSpandan Das        "CGO_CFLAGS": " ".join(go.cgo_tools.c_compile_options),
106*9bb1b549SSpandan Das        "CGO_LDFLAGS": " ".join(ldflags),
107*9bb1b549SSpandan Das    })
108*9bb1b549SSpandan Das
109*9bb1b549SSpandan Das    return env
110*9bb1b549SSpandan Das
111*9bb1b549SSpandan Dasdef _sdk_stdlib(go):
112*9bb1b549SSpandan Das    return GoStdLib(
113*9bb1b549SSpandan Das        _list_json = _build_stdlib_list_json(go),
114*9bb1b549SSpandan Das        libs = go.sdk.libs,
115*9bb1b549SSpandan Das        root_file = go.sdk.root_file,
116*9bb1b549SSpandan Das    )
117*9bb1b549SSpandan Das
118*9bb1b549SSpandan Dasdef _build_stdlib(go):
119*9bb1b549SSpandan Das    pkg = go.declare_directory(go, path = "pkg")
120*9bb1b549SSpandan Das    args = go.builder_args(go, "stdlib")
121*9bb1b549SSpandan Das    args.add("-out", pkg.dirname)
122*9bb1b549SSpandan Das    if go.mode.race:
123*9bb1b549SSpandan Das        args.add("-race")
124*9bb1b549SSpandan Das    args.add("-package", "std")
125*9bb1b549SSpandan Das    if not go.mode.pure:
126*9bb1b549SSpandan Das        args.add("-package", "runtime/cgo")
127*9bb1b549SSpandan Das    args.add_all(link_mode_args(go.mode))
128*9bb1b549SSpandan Das
129*9bb1b549SSpandan Das    args.add("-gcflags", quote_opts(go.mode.gc_goopts))
130*9bb1b549SSpandan Das
131*9bb1b549SSpandan Das    inputs = (go.sdk.srcs +
132*9bb1b549SSpandan Das              go.sdk.headers +
133*9bb1b549SSpandan Das              go.sdk.tools +
134*9bb1b549SSpandan Das              [go.sdk.go, go.sdk.package_list, go.sdk.root_file] +
135*9bb1b549SSpandan Das              go.crosstool)
136*9bb1b549SSpandan Das    outputs = [pkg]
137*9bb1b549SSpandan Das    go.actions.run(
138*9bb1b549SSpandan Das        inputs = inputs,
139*9bb1b549SSpandan Das        outputs = outputs,
140*9bb1b549SSpandan Das        mnemonic = "GoStdlib",
141*9bb1b549SSpandan Das        executable = go.toolchain._builder,
142*9bb1b549SSpandan Das        arguments = [args],
143*9bb1b549SSpandan Das        env = _build_env(go),
144*9bb1b549SSpandan Das    )
145*9bb1b549SSpandan Das    return GoStdLib(
146*9bb1b549SSpandan Das        _list_json = _build_stdlib_list_json(go),
147*9bb1b549SSpandan Das        libs = [pkg],
148*9bb1b549SSpandan Das        root_file = pkg,
149*9bb1b549SSpandan Das    )
150