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