【问题标题】:Skylark - How to execute a jar from a repository ruleSkylark - 如何从存储库规则执行 jar
【发布时间】:2017-06-29 23:19:38
【问题描述】:

上下文

我正在编写一个调用另一个 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 和 skylark 食谱。

其次,更重要的是,我不确定部署 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

附带说明,我不确定这是否是错误/错误,但 File.root.path 评估为 None,尽管 File.none 不是 None。

My first approach参与是为了尝试使用云雀[ctx.binary]

方法2

接下来我尝试模仿输入二进制示例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),
         ...

    }

然后,在我的外部项目中,我将云雀规则加载到 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:$1,与BUILD文件在同一目录中。

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

干杯。

【问题讨论】:

  • 你能解释一下你试图从另一个仓库运行的目标吗?它有什么作用?

标签: bazel


【解决方案1】:

您似乎将存储库规则与构建扩展(“正常”规则)混为一谈。一个好的经验法则是:

  • 存储库规则用于将源获取到您的系统或将它们符号链接到 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 在您需要重新定位它时很有用)。

您问题的其他内容:

我不确定这是否是 bug/nit,但 File.root.path 评估为 None,

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

Bazel 抱怨 src/script.sh 不存在。

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

【讨论】:

    猜你喜欢
    • 2014-09-13
    • 2018-04-08
    • 2010-12-25
    • 2019-06-19
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 2011-04-08
    • 2017-08-11
    相关资源
    最近更新 更多