Skylark - 如何从存储库规则执行 jar

Skylark - How to execute a jar from a repository rule

上下文

我正在编写调用另一个 Bazel 项目的存储库规则。我目前的方法是将附加项目构建为部署 jar。我希望用户能够像这样实例化规则:

jar_path = some/relative/path
my_rule(name = "something", p_arg="m_arg", binary=jar_path)

然后给定 jar_path 和参数,我希望存储库规则在 shell 中执行以下命令:

java -jar $(SOME_JAR) $(ARGUMENTS_PROVIDED_BY_RULE) 

问题

首先,不清楚如何最好地完成部署 jar 方法。到目前为止,我已经尝试了两种不同的方法,并取得了不同程度的成功。例如,我浏览了 scala_rules、maven_rules 和云雀食谱。

其次,更重要的是,我不确定部署 jar 是否是实现我的目标的最佳途径。同样,我的兴趣是从当前托管在 github 上的外部 Bazel 项目调用目标。 (如此可行,我可以尝试使用 http_archive 规则获取项目)。

下面,我描述一下我所做的尝试。

方法一

我的第一种方法涉及尝试使用 ctx.action 中的 command 字段执行命令。我尝试了

的各种枚举
java -jar {computed_absolute_path_of_deploy_jar} {args_passed_from_instantiation}. 

我最大的问题是确定部署 jar 的绝对路径。该文件的根路径将包含一些附加信息。例如,它会喜欢这样的东西。

/abs/olute/path[ something ]/rela/tive/path

附带说明一下,我不确定这是否是 bug/nit,但 File.root.path 的评估结果为 None,尽管 File.none 不是 None。

My first approach涉及到是尝试使用云雀[ctx.binary]

方法二

接下来我尝试模仿输入二进制示例 from the docs。这也没有成功。问题是找不到实际的二进制文件。这是我的配置方式。

首先,我将存储库规则放宽为常规的云雀规则。

def _test_binary(ctx):
    ctx.action(
        ....
        arguments = [ctx.attr.p_arg],
        executable = ctx.executable.binary)

test_binary = rule(
    ...
    attrs = {
         "binary":attr.label(mandatory=True, cfg="host", allow_files=True, executable=True),
         ...

    }

然后,在我的外部项目中,我将 skylark 规则加载到 WORKSPACE 文件中。最后,我从我的一个 BUILD 文件中调用了宏,如下所示:

load("@something_rule//:something_rule.bzl", "test_binary")

test_binary(name = "hello", p_arg = "hello", binary = "script.sh")

该脚本是一行 java -jar something_deploy.jar -- -arg:,并且与 BUILD 文件位于同一目录中。

Bazel 抱怨 src/script.sh 不存在。我想是因为它正在寻找 /private/var/tmp/-bazel_username/somehash/relative_path 中的文件。作为回应,我试图通过绝对路径,这是不允许的。

干杯。

您似乎混淆了存储库规则和构建扩展("normal" 规则)。一个好的经验法则是:

  • 存储库规则用于将资源获取到您的系统或将它们符号链接到 Bazel 可以看到它们的地方。
  • 构建扩展用于其他一切:编译、复制文件、运行 二进制文件等

我实际上认为您不需要为此使用任何一个。您说另一个项目在 GitHub 上,因此您可以将以下内容添加到您的 WORKSPACE 文件中:

http_archive(
    name = "other_project",
    ...
)

然后,在您的 BUILD 文件中:

genrule(
    name = "run-a-jar",
    srcs = ["@other_project//some/relative:path"],
    cmd = "java -jar $(location @other_project//some/relative:path) -- arg1 arg2 > $@",
    outs = ["jar-output"],
)

您不需要使用 _deploy.jar 目标,因为您没有将 jar 移出它的项目(_deploy.jar 在您需要重新定位它时很有用)。

你问题的其他内容:

I'm not sure if this is a bug/nit, but the File.root.path, evaluated to None,

您确定它没有评估为 "" 吗?该路径是相对于执行根目录的,因此对于源,它将始终是 ""(对于输出,它将是 bazel-out/local-fastbuild/bin 或类似的)。

Bazel complains that src/script.sh does not exist.

-s 传递给 Bazel 确实可以帮助调试 Skylark 规则。您可以准确地看到它在看什么地方。