gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/tools/bazeldefs/go.bzl (about) 1 """Go rules.""" 2 3 load("@bazel_gazelle//:def.bzl", _gazelle = "gazelle") 4 load("@io_bazel_rules_go//go:def.bzl", "GoLibrary", _go_binary = "go_binary", _go_context = "go_context", _go_library = "go_library", _go_path = "go_path", _go_test = "go_test") 5 load("@io_bazel_rules_go//proto:def.bzl", _go_grpc_library = "go_grpc_library", _go_proto_library = "go_proto_library") 6 load("//tools/bazeldefs:defs.bzl", "select_arch", "select_system") 7 8 gazelle = _gazelle 9 10 go_path = _go_path 11 12 def _go_proto_or_grpc_library(go_library_func, name, **kwargs): 13 if "importpath" in kwargs: 14 # If importpath is explicit, pass straight through. 15 go_library_func(name = name, **kwargs) 16 return 17 deps = [] 18 for d in (kwargs.pop("deps", []) or []): 19 if d == "@com_google_protobuf//:timestamp_proto": 20 # Special case: this proto has its Go definitions in a different 21 # repository. 22 deps.append("@org_golang_google_protobuf//" + 23 "types/known/timestamppb") 24 continue 25 if "//" in d: 26 repo, path = d.split("//", 1) 27 deps.append(repo + "//" + path.replace("_proto", "_go_proto")) 28 else: 29 deps.append(d.replace("_proto", "_go_proto")) 30 go_library_func( 31 name = name + "_go_proto", 32 importpath = "gvisor.dev/gvisor/" + native.package_name() + "/" + name + "_go_proto", 33 proto = ":" + name + "_proto", 34 deps = deps, 35 **kwargs 36 ) 37 38 def go_proto_library(name, **kwargs): 39 _go_proto_or_grpc_library(_go_proto_library, name, **kwargs) 40 41 def go_grpc_and_proto_libraries(name, **kwargs): 42 _go_proto_or_grpc_library(_go_grpc_library, name, **kwargs) 43 44 def go_binary(name, static = False, pure = False, x_defs = None, **kwargs): 45 """Build a go binary. 46 47 Args: 48 name: name of the target. 49 static: build a static binary. 50 pure: build without cgo. 51 x_defs: additional definitions. 52 **kwargs: rest of the arguments are passed to _go_binary. 53 """ 54 if static: 55 kwargs["static"] = "on" 56 if pure: 57 kwargs["pure"] = "on" 58 gc_goopts = select({ 59 "//conditions:default": kwargs.pop("gc_goopts", []), 60 "//tools:debug": kwargs.pop("gc_goopts", []) + ["-N", "-l"], 61 }) 62 kwargs["gotags"] = select({ 63 "//conditions:default": kwargs.pop("gotags", []), 64 "//tools:debug": kwargs.pop("gotags", []) + ["debug"], 65 }) 66 _go_binary( 67 name = name, 68 x_defs = x_defs, 69 gc_goopts = gc_goopts, 70 **kwargs 71 ) 72 73 def go_importpath(target): 74 """Returns the importpath for the target.""" 75 return target[GoLibrary].importpath 76 77 def go_library(name, arch_deps = [], **kwargs): 78 _go_library( 79 name = name, 80 importpath = "gvisor.dev/gvisor/" + native.package_name(), 81 **kwargs 82 ) 83 84 def go_test(name, static = False, pure = False, library = None, **kwargs): 85 """Build a go test. 86 87 Args: 88 name: name of the output binary. 89 static: build a static binary. 90 pure: should it be built without cgo. 91 library: the library to embed. 92 **kwargs: rest of the arguments to pass to _go_test. 93 """ 94 if pure: 95 kwargs["pure"] = "on" 96 if static: 97 kwargs["static"] = "on" 98 if library: 99 kwargs["embed"] = [library] 100 _go_test( 101 name = name, 102 **kwargs 103 ) 104 105 def go_rule(rule, implementation, **kwargs): 106 """Wraps a rule definition with Go attributes. 107 108 Args: 109 rule: rule function (typically rule or aspect). 110 implementation: implementation function. 111 **kwargs: other arguments to pass to rule. 112 113 Returns: 114 The result of invoking the rule. 115 """ 116 attrs = kwargs.pop("attrs", dict()) 117 attrs["_go_context_data"] = attr.label(default = "@io_bazel_rules_go//:go_context_data") 118 attrs["_stdlib"] = attr.label(default = "@io_bazel_rules_go//:stdlib") 119 toolchains = kwargs.get("toolchains", []) + ["@io_bazel_rules_go//go:toolchain"] 120 return rule(implementation, attrs = attrs, toolchains = toolchains, **kwargs) 121 122 def go_embed_libraries(target): 123 if hasattr(target.attr, "embed"): 124 return target.attr.embed 125 return [] 126 127 def go_context(ctx, goos = None, goarch = None, std = False): 128 """Extracts a standard Go context struct. 129 130 Args: 131 ctx: the starlark context (required). 132 goos: the GOOS value. 133 goarch: the GOARCH value. 134 std: ignored. 135 136 Returns: 137 A context Go struct with pointers to Go toolchain components. 138 """ 139 140 # We don't change anything for the standard library analysis. All Go files 141 # are available in all instances. Note that this includes the standard 142 # library sources, which are analyzed by nogo. 143 go_ctx = _go_context(ctx) 144 if goos == None: 145 goos = go_ctx.sdk.goos 146 if goarch == None: 147 goarch = go_ctx.sdk.goarch 148 env = go_ctx.env 149 env["CGO_ENABLED"] = "0" 150 return struct( 151 env = env, 152 go = go_ctx.go, 153 goarch = goarch, 154 goos = goos, 155 gotags = go_ctx.tags, 156 nogo_args = [], 157 runfiles = depset([go_ctx.go] + go_ctx.sdk.srcs + go_ctx.sdk.tools + go_ctx.stdlib.libs), 158 stdlib_srcs = go_ctx.sdk.srcs, 159 ) 160 161 def select_goarch(): 162 return select_arch(amd64 = "amd64", arm64 = "arm64") 163 164 def select_goos(): 165 return select_system( 166 linux = "linux", 167 darwin = "darwin", 168 ) 169 170 # Defined by rules_go. 171 gotsan_values = None 172 gotsan_flag_values = {"@io_bazel_rules_go//go/config:race": "true"}