github.com/bazelbuild/rules_go@v0.47.2-0.20240515105122-e7ddb9ea474e/go/private/rules/sdk.bzl (about)

     1  # Copyright 2014 The Bazel 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:providers.bzl",
    17      "GoSDK",
    18  )
    19  
    20  def _go_sdk_impl(ctx):
    21      package_list = ctx.file.package_list
    22      if package_list == None:
    23          package_list = ctx.actions.declare_file("packages.txt")
    24          _build_package_list(ctx, ctx.files.srcs, ctx.file.root_file, package_list)
    25      return [GoSDK(
    26          goos = ctx.attr.goos,
    27          goarch = ctx.attr.goarch,
    28          experiments = ctx.attr.experiments,
    29          root_file = ctx.file.root_file,
    30          package_list = package_list,
    31          libs = ctx.files.libs,
    32          headers = ctx.files.headers,
    33          srcs = ctx.files.srcs,
    34          tools = ctx.files.tools,
    35          go = ctx.executable.go,
    36          version = ctx.attr.version,
    37      )]
    38  
    39  go_sdk = rule(
    40      _go_sdk_impl,
    41      attrs = {
    42          "goos": attr.string(
    43              mandatory = True,
    44              doc = "The host OS the SDK was built for",
    45          ),
    46          "goarch": attr.string(
    47              mandatory = True,
    48              doc = "The host architecture the SDK was built for",
    49          ),
    50          "experiments": attr.string_list(
    51              mandatory = False,
    52              doc = "Go experiments to enable via GOEXPERIMENT",
    53          ),
    54          "root_file": attr.label(
    55              mandatory = True,
    56              allow_single_file = True,
    57              doc = "A file in the SDK root directory. Used to determine GOROOT.",
    58          ),
    59          "package_list": attr.label(
    60              allow_single_file = True,
    61              doc = ("A text file containing a list of packages in the " +
    62                     "standard library that may be imported."),
    63          ),
    64          "libs": attr.label_list(
    65              # allow_files is not set to [".a"] because that wouldn't allow
    66              # for zero files to be present, as is the case in Go 1.20+.
    67              # See also https://github.com/bazelbuild/bazel/issues/7516
    68              allow_files = True,
    69              doc = ("Pre-compiled .a files for the standard library, " +
    70                     "built for the execution platform"),
    71          ),
    72          "headers": attr.label_list(
    73              allow_files = [".h"],
    74              doc = (".h files from pkg/include that may be included in " +
    75                     "assembly sources"),
    76          ),
    77          "srcs": attr.label_list(
    78              allow_files = True,
    79              doc = "Source files for packages in the standard library",
    80          ),
    81          "tools": attr.label_list(
    82              allow_files = True,
    83              cfg = "exec",
    84              doc = ("List of executable files in the SDK built for " +
    85                     "the execution platform, excluding the go binary"),
    86          ),
    87          "go": attr.label(
    88              mandatory = True,
    89              allow_single_file = True,
    90              executable = True,
    91              cfg = "exec",
    92              doc = "The go binary",
    93          ),
    94          "version": attr.string(
    95              doc = "The version of the Go SDK.",
    96          ),
    97      },
    98      doc = ("Collects information about a Go SDK. The SDK must have a normal " +
    99             "GOROOT directory structure."),
   100      provides = [GoSDK],
   101  )
   102  
   103  def _package_list_impl(ctx):
   104      _build_package_list(ctx, ctx.files.srcs, ctx.file.root_file, ctx.outputs.out)
   105      return [DefaultInfo(files = depset([ctx.outputs.out]))]
   106  
   107  package_list = rule(
   108      _package_list_impl,
   109      attrs = {
   110          "srcs": attr.label_list(
   111              allow_files = True,
   112              doc = "Source files for packages in the standard library",
   113          ),
   114          "root_file": attr.label(
   115              mandatory = True,
   116              allow_single_file = True,
   117              doc = "A file in the SDK root directory. Used to determine GOROOT.",
   118          ),
   119          "out": attr.output(
   120              mandatory = True,
   121              doc = "File to write. Must be 'packages.txt'.",
   122              # Gazelle depends on this file directly. It has to be an output
   123              # attribute because Bazel has no other way of knowing what rule
   124              # produces this file.
   125              # TODO(jayconrod): Update Gazelle and simplify this.
   126          ),
   127      },
   128  )
   129  
   130  def _build_package_list(ctx, srcs, root_file, out):
   131      packages = {}
   132      src_dir = root_file.dirname + "/src/"
   133      for src in srcs:
   134          pkg_src_dir = src.dirname
   135          if not pkg_src_dir.startswith(src_dir):
   136              continue
   137          pkg_name = pkg_src_dir[len(src_dir):]
   138          packages[pkg_name] = None
   139      content = "\n".join(sorted(packages.keys())) + "\n"
   140      ctx.actions.write(out, content)