...

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

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

     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
    15load(
    16    "//go/private:common.bzl",
    17    "COVERAGE_OPTIONS_DENYLIST",
    18    "GO_TOOLCHAIN_LABEL",
    19)
    20load(
    21    "//go/private:providers.bzl",
    22    "GoStdLib",
    23)
    24load(
    25    "//go/private:mode.bzl",
    26    "LINKMODE_NORMAL",
    27    "extldflags_from_cc_toolchain",
    28    "link_mode_args",
    29)
    30load("//go/private:sdk.bzl", "parse_version")
    31load("//go/private/actions:utils.bzl", "quote_opts")
    32
    33def 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
    47def _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
    53def _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
    67def _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
    90def _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
   116def _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
   123def _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    )

View as plain text