我正试图在bazel BUILD中为其中一个包编写一个genrule。目的是规则必须在包源上应用一个补丁。我把它写成如下 -
genrule(
name = "patching_rule",
srcs = ["Package"],
outs = ["test_output.txt"],
cmd = "cd $(location Package); patch -p0 < /tmp/mypatch.patch",
)
阅读bazel BUILD文档,我发现“出局”是必填字段。但是,我的补丁肯定不会产生任何结果。在Package源代码中只需要2-3行代码更改。我不能保持“出局”为空,也无法在那里添加虚拟文件。有谁可以帮我解决这个问题?
提前致谢, Nishidha
答案 0 :(得分:3)
如评论中所述,如果你想在一个规则中进行补丁,你需要声明补丁作为输入源,并将结果源作为输出,genrule和Bazel构建不允许修改输入树
但是,由于此特定情况用于修补外部存储库(TensorFlow),因此您可以使用自定义实现替换local_repository
文件中正在使用的任何存储库(可能是WORKSPACE
)(让我们将其命名为local_patched_repository
),因此WORKSPACE
文件部分将如下所示:
load("//:local_patched_repository.bzl", "local_patched_repository")
local_patched_repository(
name = "org_tensorflow",
path = "tensorflow",
patch = "//:mypatch.patch",
)
BUILD
文件旁边有mypatch.patch
个文件(可以为空),local_patched_repository.bzl
和WORKSPACE
。现在local_patched_repository.bzl
的内容如下:
def _impl(rctxt):
path = rtcxt.attr.path
# This path is a bit ugly to get the actual path if it is relative.
if path[0] != "/":
# rctxt.path(Label("//:BUILD")) will returns a path to the BUILD file
# in the current workspace, so getting the dirname get the path
# relative to the workspace.
path = rctxt.path(Label("//:BUILD")).dirname + "/" + path
# Copy the repository
result = rctxt.execute(["cp", "-fr", path + "/*", rctxt.path()])
if result.return_code != 0:
fail("Failed to copy %s (%s)" % (rctxt.attr.path, result.return_code))
# Now patch the repository
patch_file = str(rctxt.path(rctxt.attr.patch).realpath)
result = rctxt.execute(["bash", "-c", "patch -p0 < " + patch_file])
if result.return_code != 0:
fail("Failed to patch (%s): %s" % (result.return_code, result.stderr))
local_patched_repository = repository_rule(
implementation=_impl,
attrs={
"path": attr.string(mandatory=True),
"patch": attr.label(mandatory=True)
},
local = True)
当然这是一个快速实现,并且有一个问题:local = True
将重新计算此存储库,如果修补很慢,您可能想要删除它(这意味着我们不会请参阅tensorflow存储库中的文件更改。除非你更改文件,否则它不会正常重建,除非你遇到了一个bazel bug。
如果您确实要替换cp
,也可以将http_repository
替换为rctx.download_and_extract(但是tensorflow仍然需要进行一些修改,即./configure可以使其与{{1}不兼容}})。
编辑:A patch to patch on the fly the eigen http_repository on TensorFlow