代码之家  ›  专栏  ›  技术社区  ›  Steve Vermeulen

无法将py_binary目标用作自定义规则中的可执行文件

  •  0
  • Steve Vermeulen  · 技术社区  · 1 年前

    我有一个py_binary可执行目标,希望从自定义规则中使用它。我能够做到这一点,但只能通过使用自定义规则复制py_binary目标的依赖项。有没有办法避免这种重复并自动包括py_binary的依赖项?

    我已经将问题简化为以下内容(通过运行//foo:main-target来重现)

    greet/BUILD.bazel :

    py_binary(
        name = "greet",
        srcs = ["greet.py"],
        deps = ["@rules_python//python/runfiles"],
        visibility = ["//visibility:public"],
    )
    

    greet/greet.py :

    from rules_python.python.runfiles import runfiles
    
    print("hello world")
    

    foo/BUILD.bazel :

    load("//bazel:defs.bzl", "foo_binary")
    
    foo_binary(
        name = "main",
    )
    

    bazel/BUILD.bazel 空的

    bazel/defs.bzl :

    def _foo_binary(ctx):
        shell_script = ctx.actions.declare_file("run.sh")
        ctx.actions.write(
            output = shell_script,
            content = """#!/bin/bash
    $0.runfiles/svkj/{runtime}
    """.format(runtime=ctx.executable._greet.short_path),
            is_executable = True,
        )
    
        return [
            DefaultInfo(
                executable = shell_script,
                runfiles = ctx.runfiles(
                    files = ctx.files._greet + ctx.files.deps + ctx.files._python,
                    collect_data = True
                ),
            ),
        ]
    
    foo_binary = rule(
        implementation = _foo_binary,
        attrs = {
            "deps": attr.label_list(
                allow_files=True,
            ),
            "_greet": attr.label(
                default = "//greet:greet",
                cfg = "exec",
                executable = True,
            ),
            # TODO - Why is it necessary to add this explicitly?
            "_python": attr.label_list(
                allow_files=True,
                default = ["@python3_9//:python3", "@rules_python//python/runfiles"],
            ),
        },
        executable = True,
    )
    

    bazel/BUILD.bazel :

    工作空间:

    workspace(name = "svkj")
    
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "rules_python",
        sha256 = "5fa3c738d33acca3b97622a13a741129f67ef43f5fdfcec63b29374cc0574c29",
        strip_prefix = "rules_python-0.9.0",
        url = "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.9.0.tar.gz",
    )
    
    load("@rules_python//python:repositories.bzl", "python_register_toolchains")
    
    python_register_toolchains(
        name = "python3_9",
        python_version = "3.9",
    )
    
    load("@python3_9//:defs.bzl", "interpreter")
    
    0 回复  |  直到 1 年前
        1
  •  2
  •   lummax    1 年前

    您需要正确收集的运行文件 _greet 二进制的而不仅仅是使用 打招呼 二进制本身,请尝试以下操作以包括其依赖项(和数据依赖项):

    DefaultInfo(
      executable = shell_script,
      runfiles = ctx._greet[DefaultInfo].default_runfiles
    )
    

    另请参阅: https://bazel.build/extending/rules#runfiles