如何在bazel中创建目录结构

How to create a directory structure in bazel

我想在 bazel 中创建以下结构。

dir1
   |_ file1
   |_ file2
   |_ dir2
         |_file3

创建一个特定的结构似乎并不简单。 我希望有一个简单且可重复使用的规则。 类似于:

makedir(
  name = "dir1",
  path = "dir1",
)

makedir(
  name = "dir2",
  path = "dir1/dir2",
  deps = [":dir1"],
)

我尝试过的:

用例是我想用bazel创建一个squashfs

请务必注意 Bazel provides some packaging 功能。

create a squashfs,该命令需要一个包含工件的目录结构。

在我的例子中,我想创建一个目录结构和 运行 mksquashfs 来生成一个 squashfs 文件。

为此,我最终修改了 bazel's docs on packaging 中的基本示例。

load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar")

genrule(
    name = "file1",
    outs = ["file1.txt"],
    cmd = "echo exampleText > $@",
)

pkg_tar(
    name = "dir1",
    strip_prefix = ".",
    package_dir = "/usr/bin",
    srcs = [":file1"],
    mode = "0755",
)

pkg_tar(
    name = "dir2",
    strip_prefix = ".",
    package_dir = "/usr/share",
    srcs = ["//main:file2.txt", "//main:file3.txt"],
    mode = "0644",
)

pkg_tar(
    name = "pkg",
    extension = "tar.gz",
    deps = [
        ":dir1",
        ":dir2",
    ],
)

如果有更简单的方法来创建 tar 或目录结构而不需要中间 tars,我会给出最佳答案。

您始终可以创建一个 genrule target or a shell_binary 目标来执行 bash 命令或一个 shell 脚本(分别)来创建这些目录。

genrule 一起,您可以使用 bazel 的 $(location),这将确保您创建的目录结构将位于 bazel 的 sandbox 环境内的输出路径下。 genrule example 显示了如何使用它。

Here 您可以找到有关预定义输出路径的更多详细信息。

您可以创建这样一个使用 genrule 的 Bazel 宏:

def mkdir(name, out_dir, marker_file = "marker"):
    """Create an empty directory that you can use as an input in another rule

    This will technically create an empty marker file in that directory to avoid Bazel warnings.
    You should depend on this marker file.
    """
    path = "%s/%s" % (out_dir, marker_file)
    native.genrule(
        name = name,
        outs = [path],
        cmd = """mkdir -p $$(dirname $(location :%s)) && touch $(location :%s)""" % (path, path),
    )

然后您可以在 pkg_tar 定义中使用此宏生成的输出:

mkdir(
    name = "generate_a_dir",
    out_dir = "my_dir",
)

pkg_tar(
    name = "package",
    srcs = [
        # ...
        ":generate_a_dir",
    ],
    # ...
)