gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/seccomp/precompiledseccomp/defs.bzl (about)

     1  """Macro for precompiling seccomp-bpf programs."""
     2  
     3  load("//tools:defs.bzl", "go_binary")
     4  
     5  def precompiled_seccomp_rules(
     6          name,
     7          programs_to_compile_go_library,
     8          programs_to_compile_go_import,
     9          out,
    10          out_package_name,
    11          exclude_in_fastbuild = False):
    12      """Generates a Go source file containing precompiled seccomp-bpf programs.
    13  
    14      Args:
    15          name: Name of the final genrule.
    16          programs_to_compile_go_library: go_library target which describes the
    17              set of seccomp-bpf programs that you wish to precompile. This must
    18              define the following package-level function:
    19              func PrecompiledPrograms() ([]precompiledseccomp.Program, error)
    20          programs_to_compile_go_import: Go-style import path to
    21              `programs_to_compile_go_library`.
    22          out: Name of the Go source file (with the precompiled seccomp-bpf
    23              programs embedded in it) to generate. You can add this file as
    24              source to a `go_library` rule. This will define a package-level
    25              function:
    26              GetPrecompiled(programName string) (precompiledseccomp.Program, bool)
    27          out_package_name: Go package name that `out` belongs to.
    28          exclude_in_fastbuild: Whether to skip precompilation in fastbuild mode.
    29              The auto-generated `GetPrecompiled` function will fail all lookups.
    30      """
    31      if exclude_in_fastbuild:
    32          native.config_setting(
    33              name = name + "_fastbuild_cond",
    34              values = {
    35                  "compilation_mode": "fastbuild",
    36              },
    37          )
    38  
    39      # This genrule copies precompiled_lib.tmpl.go to the directory of wherever
    40      # `precompiled_seccomp_rules` is called.
    41      # This allows the go:embed directive inside the `.gen.go` file below to
    42      # work without rewriting the full path.
    43      native.genrule(
    44          name = name + "_gen_lib",
    45          outs = [out + ".gen.lib.tmpl.go"],
    46          cmd = "cat < $(SRCS) > $@",
    47          srcs = [
    48              "//pkg/seccomp/precompiledseccomp:precompiled_lib.tmpl.go",
    49          ],
    50      )
    51  
    52      # This genrule generates the Go file of the binary that, when run,
    53      # precompiles rules and writes them to a designated file.
    54      gen_cmd_template = (
    55          "  while IFS= read -r line; do" +
    56          "    if echo \"$$line\" | grep -q 'REPLACED_IMPORT_THIS_IS_A_LOAD_BEARING_COMMENT'; then" +
    57          "        {rules_import_echo}" +
    58          "    elif echo \"$$line\" | grep -q 'PROGRAMS_FUNC_THIS_IS_A_LOAD_BEARING_COMMENT'; then" +
    59          "        {load_programs_fn_echo}" +
    60          "    elif echo \"$$line\" | grep -q 'go:embed precompiled_lib.tmpl.go'; then" +
    61          "        echo -e \"//go:embed " + out + ".gen.lib.tmpl.go\";" +
    62          "    else" +
    63          "      echo \"$$line\";" +
    64          "    fi;" +
    65          "  done" +
    66          "  < $(SRCS)" +
    67          "  > $@"
    68      )
    69      gen_cmd = gen_cmd_template.format(
    70          rules_import_echo = (
    71              "echo -e \"\\\\trules \\\"" +
    72              programs_to_compile_go_import +
    73              "\\\"\";"
    74          ),
    75          load_programs_fn_echo = (
    76              "echo -e \"var loadProgramsFn = rules.PrecompiledPrograms\";"
    77          ),
    78      )
    79      native.genrule(
    80          name = name + "_gen",
    81          outs = [out + ".gen.go"],
    82          cmd = gen_cmd,
    83          srcs = [
    84              "//pkg/seccomp/precompiledseccomp:precompile_gen.go",
    85          ],
    86      )
    87      if exclude_in_fastbuild:
    88          native.genrule(
    89              name = name + "_gen_stubbed",
    90              outs = [out + ".gen_stubbed.go"],
    91              cmd = gen_cmd_template.format(
    92                  rules_import_echo = "true;",
    93                  load_programs_fn_echo = (
    94                      "echo -e \"var loadProgramsFn func() ([]precompiledseccomp.Program, error) = nil\";"
    95                  ),
    96              ),
    97              srcs = [
    98                  "//pkg/seccomp/precompiledseccomp:precompile_gen.go",
    99              ],
   100          )
   101  
   102      # This defines the go_binary for the Go file we just generated.
   103      base_gen_bin_deps = [
   104          "//pkg/seccomp/precompiledseccomp",
   105          "//runsc/flag",
   106      ]
   107      gen_bin_deps = [programs_to_compile_go_library] + base_gen_bin_deps
   108      go_binary(
   109          name = name + "_gen_bin",
   110          srcs = [out + ".gen.go"],
   111          deps = gen_bin_deps,
   112          embedsrcs = [
   113              ":" + out + ".gen.lib.tmpl.go",
   114          ],
   115      )
   116      if exclude_in_fastbuild:
   117          go_binary(
   118              name = name + "_gen_stubbed_bin",
   119              srcs = [out + ".gen_stubbed.go"],
   120              deps = base_gen_bin_deps,
   121              embedsrcs = [
   122                  ":" + out + ".gen.lib.tmpl.go",
   123              ],
   124          )
   125  
   126      # This genrule actually runs the go_binary we just declared, and writes
   127      # its output (containing the precompiled rules) to the desired `out` file.
   128      out_cmd = "$(location :" + name + "_gen_bin) --package='" + out_package_name + "' --out=$@"
   129      if exclude_in_fastbuild:
   130          native.genrule(
   131              name = name,
   132              outs = [out],
   133              cmd = select({
   134                  ":" + name + "_fastbuild_cond": (
   135                      "$(location :" + name + "_gen_stubbed_bin) --package='" + out_package_name + "' --out=$@"
   136                  ),
   137                  "//conditions:default": out_cmd,
   138              }),
   139              tools = select({
   140                  ":" + name + "_fastbuild_cond": [":" + name + "_gen_stubbed_bin"],
   141                  "//conditions:default": [":" + name + "_gen_bin"],
   142              }),
   143          )
   144      else:
   145          native.genrule(
   146              name = name,
   147              outs = [out],
   148              cmd = (
   149                  "$(location :" + name + "_gen_bin) --package='" + out_package_name + "' --out=$@"
   150              ),
   151              tools = [":" + name + "_gen_bin"],
   152          )