How to get WORKSPACE directory in bazel rule

后端 未结 3 835
渐次进展
渐次进展 2021-01-15 04:12

I order to use clang tools like clang-format, clang-tidy or generate a compilation database like this, I need to know the WORKSPACE directory withi

相关标签:
3条回答
  • 2021-01-15 04:19

    You can probably get around this by using realpath. Something like:

    def _impl(ctx):
    
      ctx.actions.run_shell(
        inputs = ctx.files.srcs,
        outputs = [ctx.outputs.executable],
        command = "\n".join(["echo echo $(realpath \"%s\") >> %s" % (f.path,
                  ctx.outputs.executable.path) for f in ctx.files.srcs]),
        execution_requirements = {
            "no-sandbox": "1",
            "no-cache": "1",
            "no-remote": "1",
            "local": "1",
        },
      )
    
    echo_full_path = rule(
        implementation=_impl,
        executable=True,
        attrs={
          "srcs": attr.label_list(allow_files=True),
        }
    )
    

    Note the execution_requirements to get around the potential issues in my comment above.

    0 讨论(0)
  • 2021-01-15 04:21

    I modified @ahumesky's rule to implicitly use the BUILD file as the source and to write only the workspace directory once:

    workspace.bzl

    def _write_workspace_dir_impl(ctx):
        src = ctx.files._src[0]
        out = ctx.actions.declare_file(ctx.label.name)
        ctx.actions.run_shell(
            inputs = ctx.files._src,
            outputs = [out],
            command = """
              full_path="$(readlink -f -- "{src_full}")"
              # Trim the src.short_path suffix from full_path. Double braces to
              # output literal brace for shell.
              echo "${{full_path%/{src_short}}}" >> {out_full}
            """.format(src_full = src.path, src_short = src.short_path, out_full = out.path),
            execution_requirements = {
                "no-sandbox": "1",
                "no-remote": "1",
                "local": "1",
            },
        )
        return [DefaultInfo(files = depset([out]))]
    
    write_workspace_dir = rule(
        implementation = _write_workspace_dir_impl,
        attrs = {
            "_src": attr.label(allow_files = True, default = "BUILD"),
        },
        doc = "Writes the full path of the current workspace dir to a file.",
    )
    

    BUILD

    load(":workspace.bzl", "write_workspace_dir")
    
    write_workspace_dir(
        name = "workspace_dir",
    )
    

    Sample output

    bazel build //build/bazel:workspace_dir
    INFO: Analyzed target //build/bazel:workspace_dir 
    INFO: Build completed successfully, 1 total action
    
    cat bazel-bin/build/bazel/workspace_dir
    /p/$MY_PROJECT
    
    0 讨论(0)
  • 2021-01-15 04:38

    If you're like me and writing a repository_rule instead of a regular one, resolving the following label can help you: "@//:WORKSPACE"

    Then use ctx.path to extract the required data: https://docs.bazel.build/versions/master/skylark/lib/repository_ctx.html#path

    0 讨论(0)
提交回复
热议问题