gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/tools/defs.bzl (about) 1 """Wrappers for common build rules. 2 3 These wrappers apply common BUILD configurations (e.g., proto_library 4 automagically creating cc_ and go_ proto targets) and act as a single point of 5 change for Google-internal and bazel-compatible rules. 6 """ 7 8 load("//tools/bazeldefs:cc.bzl", _cc_binary = "cc_binary", _cc_flags_supplier = "cc_flags_supplier", _cc_grpc_library = "cc_grpc_library", _cc_library = "cc_library", _cc_proto_library = "cc_proto_library", _cc_test = "cc_test", _cc_toolchain = "cc_toolchain", _gbenchmark = "gbenchmark", _gbenchmark_internal = "gbenchmark_internal", _grpcpp = "grpcpp", _gtest = "gtest", _select_gtest = "select_gtest", _vdso_linker_option = "vdso_linker_option") 9 load("//tools/bazeldefs:defs.bzl", _BuildSettingInfo = "BuildSettingInfo", _bool_flag = "bool_flag", _bpf_program = "bpf_program", _build_test = "build_test", _bzl_library = "bzl_library", _coreutil = "coreutil", _default_net_util = "default_net_util", _more_shards = "more_shards", _most_shards = "most_shards", _proto_library = "proto_library", _select_system = "select_system", _short_path = "short_path", _version = "version") 10 load("//tools/bazeldefs:go.bzl", _gazelle = "gazelle", _go_binary = "go_binary", _go_grpc_and_proto_libraries = "go_grpc_and_proto_libraries", _go_library = "go_library", _go_path = "go_path", _go_proto_library = "go_proto_library", _go_test = "go_test", _gotsan_flag_values = "gotsan_flag_values", _gotsan_values = "gotsan_values", _select_goarch = "select_goarch", _select_goos = "select_goos") 11 load("//tools/bazeldefs:pkg.bzl", _pkg_deb = "pkg_deb", _pkg_tar = "pkg_tar") 12 load("//tools/bazeldefs:platforms.bzl", _default_platform = "default_platform", _platform_capabilities = "platform_capabilities", _platforms = "platforms", _save_restore_platforms = "save_restore_platforms") 13 load("//tools/bazeldefs:tags.bzl", _go_suffixes = "go_suffixes", _local_test_tags = "local_test_tags") 14 load("//tools/go_marshal:defs.bzl", "go_marshal", "marshal_deps", "marshal_test_deps") 15 load("//tools/go_stateify:defs.bzl", "go_stateify") 16 load("//tools/nogo:defs.bzl", "nogo_test") 17 18 # Core rules. 19 build_test = _build_test 20 bzl_library = _bzl_library 21 bool_flag = _bool_flag 22 BuildSettingInfo = _BuildSettingInfo 23 default_net_util = _default_net_util 24 select_system = _select_system 25 short_path = _short_path 26 coreutil = _coreutil 27 more_shards = _more_shards 28 most_shards = _most_shards 29 version = _version 30 31 # C++ rules. 32 cc_binary = _cc_binary 33 cc_flags_supplier = _cc_flags_supplier 34 cc_grpc_library = _cc_grpc_library 35 cc_library = _cc_library 36 cc_test = _cc_test 37 cc_toolchain = _cc_toolchain 38 gbenchmark = _gbenchmark 39 gbenchmark_internal = _gbenchmark_internal 40 gtest = _gtest 41 grpcpp = _grpcpp 42 vdso_linker_option = _vdso_linker_option 43 select_gtest = _select_gtest 44 45 # Go rules. 46 gazelle = _gazelle 47 go_path = _go_path 48 select_goos = _select_goos 49 select_goarch = _select_goarch 50 go_proto_library = _go_proto_library 51 gotsan_values = _gotsan_values 52 gotsan_flag_values = _gotsan_flag_values 53 54 # BPF rules. 55 bpf_program = _bpf_program 56 57 # Packaging rules. 58 pkg_deb = _pkg_deb 59 pkg_tar = _pkg_tar 60 61 # Platform options. 62 default_platform = _default_platform 63 platforms = _platforms 64 platform_capabilities = _platform_capabilities 65 save_restore_platforms = _save_restore_platforms 66 67 # Tags. 68 local_test_tags = _local_test_tags 69 70 def go_binary(name, nogo = True, pure = False, static = False, x_defs = None, **kwargs): 71 """Wraps the standard go_binary. 72 73 Args: 74 name: the rule name. 75 nogo: enable nogo analysis. 76 pure: build a pure Go (no CGo) binary. 77 static: build a static binary. 78 x_defs: additional linker definitions. 79 **kwargs: standard go_binary arguments. 80 """ 81 _go_binary( 82 name = name, 83 pure = pure, 84 static = static, 85 x_defs = x_defs, 86 **kwargs 87 ) 88 if nogo: 89 # Note that the nogo rule applies only for go_library and go_test 90 # targets, therefore we construct a library from the binary sources. 91 # This is done because the binary may not be in a form that objdump 92 # supports (i.e. a pure Go binary). 93 _go_library( 94 name = name + "_nogo_library", 95 srcs = kwargs.get("srcs", []), 96 deps = kwargs.get("deps", []), 97 embedsrcs = kwargs.get("embedsrcs", []), 98 testonly = 1, 99 ) 100 nogo_test( 101 name = name + "_nogo", 102 config = "//:nogo_config", 103 srcs = kwargs.get("srcs", []), 104 deps = [":" + name + "_nogo_library"], 105 tags = ["nogo"], 106 ) 107 108 def calculate_sets(srcs): 109 """Calculates special Go sets for templates. 110 111 Args: 112 srcs: the full set of Go sources. 113 114 Returns: 115 A dictionary of the form: 116 117 "": [src1.go, src2.go] 118 "suffix": [src3suffix.go, src4suffix.go] 119 120 Note that suffix will typically start with '_'. 121 """ 122 result = dict() 123 for file in srcs: 124 if not file.endswith(".go"): 125 continue 126 target = "" 127 for suffix in _go_suffixes: 128 if file.endswith(suffix + ".go"): 129 target = suffix 130 if not target in result: 131 result[target] = [file] 132 else: 133 result[target].append(file) 134 return result 135 136 def go_imports(name, src, out): 137 """Simplify a single Go source file by eliminating unused imports.""" 138 native.genrule( 139 name = name, 140 srcs = [src], 141 outs = [out], 142 tools = ["@org_golang_x_tools//cmd/goimports:goimports"], 143 cmd = ("$(location @org_golang_x_tools//cmd/goimports:goimports) $(SRCS) > $@"), 144 ) 145 146 def go_library(name, srcs, deps = [], imports = [], stateify = True, force_add_state_pkg = False, marshal = False, marshal_debug = False, nogo = True, **kwargs): 147 """Wraps the standard go_library and does stateification and marshalling. 148 149 The recommended way is to use this rule with mostly identical configuration as the native 150 go_library rule. 151 152 These definitions provide additional flags (stateify, marshal) that can be used 153 with the generators to automatically supplement the library code. 154 155 load("//tools:defs.bzl", "go_library") 156 157 go_library( 158 name = "foo", 159 srcs = ["foo.go"], 160 ) 161 162 Args: 163 name: the rule name. 164 srcs: the library sources. 165 deps: the library dependencies. 166 imports: imports required for stateify. 167 stateify: whether statify is enabled (default: true). 168 force_add_state_pkg: whether to skip checking whether the state package 169 is included in `deps`, and to just instead include it outright. 170 This allows `go_library` to be used in conjunction with `select` 171 statements in `deps`. 172 marshal: whether marshal is enabled (default: false). 173 marshal_debug: whether the gomarshal tools emits debugging output (default: false). 174 nogo: enable nogo analysis. 175 **kwargs: standard go_library arguments. 176 """ 177 all_srcs = srcs 178 all_deps = deps 179 dirname, _, _ = native.package_name().rpartition("/") 180 full_pkg = dirname + "/" + name 181 if stateify: 182 # Only do stateification for non-state packages without manual autogen. 183 # First, we need to segregate the input files via the special suffixes, 184 # and calculate the final output set. 185 state_sets = calculate_sets(srcs) 186 for (suffix, src_subset) in state_sets.items(): 187 go_stateify( 188 name = name + suffix + "_state_autogen_with_imports", 189 srcs = src_subset, 190 imports = imports, 191 package = full_pkg, 192 out = name + suffix + "_state_autogen_with_imports.go", 193 ) 194 go_imports( 195 name = name + suffix + "_state_autogen", 196 src = name + suffix + "_state_autogen_with_imports.go", 197 out = name + suffix + "_state_autogen.go", 198 ) 199 all_srcs = all_srcs + [ 200 name + suffix + "_state_autogen.go" 201 for suffix in state_sets.keys() 202 ] 203 204 if force_add_state_pkg or "//pkg/state" not in all_deps: 205 all_deps = all_deps + ["//pkg/state"] 206 207 if marshal: 208 # See above. 209 marshal_sets = calculate_sets(srcs) 210 for (suffix, src_subset) in marshal_sets.items(): 211 go_marshal( 212 name = name + suffix + "_abi_autogen", 213 srcs = src_subset, 214 debug = select({ 215 "//tools/go_marshal:marshal_config_verbose": True, 216 "//conditions:default": marshal_debug, 217 }), 218 imports = imports, 219 package = name, 220 ) 221 extra_deps = [ 222 dep 223 for dep in marshal_deps 224 if not dep in all_deps 225 ] 226 all_deps = all_deps + extra_deps 227 all_srcs = all_srcs + [ 228 name + suffix + "_abi_autogen_unsafe.go" 229 for suffix in marshal_sets.keys() 230 ] 231 232 _go_library( 233 name = name, 234 srcs = all_srcs, 235 deps = all_deps, 236 **kwargs 237 ) 238 if nogo: 239 nogo_test( 240 name = name + "_nogo", 241 config = "//:nogo_config", 242 srcs = all_srcs, 243 deps = [":" + name], 244 tags = ["nogo"], 245 ) 246 247 if marshal: 248 # Ignore importpath for go_test. 249 kwargs.pop("importpath", None) 250 251 # See above. 252 marshal_sets = calculate_sets(srcs) 253 for (suffix, _) in marshal_sets.items(): 254 _go_test( 255 name = name + suffix + "_abi_autogen_test", 256 srcs = [ 257 name + suffix + "_abi_autogen_test.go", 258 name + suffix + "_abi_autogen_unconditional_test.go", 259 ], 260 library = ":" + name, 261 deps = marshal_test_deps, 262 **kwargs 263 ) 264 265 def go_test(name, nogo = True, **kwargs): 266 """Wraps the standard go_test. 267 268 Args: 269 name: the rule name. 270 nogo: enable nogo analysis. 271 **kwargs: standard go_test arguments. 272 """ 273 _go_test( 274 name = name, 275 **kwargs 276 ) 277 if nogo: 278 nogo_test( 279 name = name + "_nogo", 280 config = "//:nogo_config", 281 srcs = kwargs.get("srcs", []), 282 deps = [":" + name], 283 tags = ["nogo"], 284 ) 285 286 def proto_library(name, srcs, deps = None, has_services = 0, **kwargs): 287 """Wraps the standard proto_library. 288 289 Given a proto_library named "foo", this produces up to five different 290 targets: 291 - foo_proto: proto_library rule. 292 - foo_go_proto: go_proto_library rule. 293 - foo_cc_proto: cc_proto_library rule. 294 - foo_go_grpc_proto: go_grpc_library rule. 295 - foo_cc_grpc_proto: cc_grpc_library rule. 296 297 Args: 298 name: the name to which _proto, _go_proto, etc, will be appended. 299 srcs: the proto sources. 300 deps: for the proto library and the go_proto_library. 301 has_services: 1 to build gRPC code, otherwise 0. 302 **kwargs: standard proto_library arguments. 303 """ 304 _proto_library( 305 name = name + "_proto", 306 srcs = srcs, 307 deps = deps, 308 has_services = has_services, 309 **kwargs 310 ) 311 if has_services: 312 _go_grpc_and_proto_libraries( 313 name = name, 314 deps = deps, 315 **kwargs 316 ) 317 else: 318 _go_proto_library( 319 name = name, 320 deps = deps, 321 **kwargs 322 ) 323 _cc_proto_library( 324 name = name + "_cc_proto", 325 deps = [":" + name + "_proto"], 326 **kwargs 327 ) 328 if has_services: 329 _cc_grpc_library( 330 name = name + "_cc_grpc_proto", 331 srcs = [":" + name + "_proto"], 332 deps = [":" + name + "_cc_proto"], 333 **kwargs 334 )