Skylark - 如何从存储库规则

时间:2017-06-29 23:19:38

标签: bazel

上下文

我正在编写一个调用另一个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是否是实现目标的最佳途径。同样,我的兴趣是从外部Bazel项目调用目标,该项目当前托管在github上。 (如此可行,我可以尝试使用http_archive规则获取项目。)

下面,我描述了我的尝试。

方法1

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

的枚举
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涉及的是尝试使用skylark [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),
         ...

    }

然后,在我的外部项目中,我将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:$1,与BUILD文件位于同一目录中。

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

干杯。

1 个答案:

答案 0 :(得分:4)

看起来您正在将存储库规则与构建扩展混合("正常"规则)。一个好的经验法则是:

  • 存储库规则用于将源代码发送到您的系统或将它们符号化到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,评估为无,

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

  

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

-s传递给Bazel可以真正帮助调试Skylark规则。你可以看到它的确切位置。