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