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          )