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