Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bazel rules for handling directories #494

Closed
wants to merge 3 commits into from

Conversation

matts1
Copy link

@matts1 matts1 commented Apr 19, 2024

I first created this rule to better support sysroots inside rules_cc (bazelbuild/bazel#20334).

However, upon review, @t-rad679 wrote "This issue of wanting packages (directories) instead of individual target labels is coming up frequently for me. Maybe we could reuse this provider for use cases other than sysroot?".

I think this is sufficiently broadly applicable to work with anything. For example, here is some things I plan to do with it down the line:

# arm_sysroot/BUILD.bazel
directory(
    name = "sysroot",
    srcs = glob(["**"], exclude = ["BUILD.bazel"])
)

# toolchain/BUILD.bazel
alias(
    name = "sysroot",
    actual = select({
       ":is_arm": "@arm_sysroot//:sysroot",
       "//conditions:default": "@amd64_sysroot//:sysroot",
    },
)

# Will be implemented in bazel-skylib in a later PR
filter_directory(
   name = "clang_files"
   directory = ":sysroot",
   srcs = ["usr/bin/clang"],
   data = ["lib/libc.so.6"]
)

# Already implemented in rules_cc
cc_tool(
   name = "clang_files",
   executable = ":clang",
)

subdirectory(
    name = "header_dir",
    directory = ":sysroot",
    srcs = ["usr/include"],
)

# Will be implemented in bazel-skylib in a later PR
glob_directory(
    name = "header_files",
    directory = ":header_dir",
    srcs = ["*.h"],
)

# Already implemented in rules_cc
cc_action_type_config(
    name = "c_compile",
    actions = ["@rules_cc//cc/toolchains/actions:c_compile"],
    tools = [":clang"],
    data = [":header_files"],
)

# Already mostly implemented in rules_cc
cc_toolchain(
    name = "cc_toolchain",
    action_type_configs = [":c_compile", ...]
    # At the moment these two params are strings. This PR will allow me to change them to labels.
    sysroot = ":sysroot",
    cxx_builtin_include_dirs = [":header_dir"],
)

@armandomontanez FYI

Note: for now, I haven't written any documentation, but I can add them once the concept gets approval.

@matts1
Copy link
Author

matts1 commented Apr 19, 2024

Build failures appear to be for an unrelated reason.

@fmeum
Copy link
Contributor

fmeum commented Apr 20, 2024

It's not unrelated, the test runs on skylib itself and you thus need to add the new directory directories you created.

@matts1
Copy link
Author

matts1 commented Apr 22, 2024

Ah, thanks, I was in a hurry when I looked at it last and didn't get a chance to fully check it out. Should be fixed now.

@armandomontanez
Copy link

The handling of this would be a lot simpler if this Bazel bug was fixed:
bazelbuild/bazel#12954

Would it make sense to have a single directory rule instead?

directory(
    name = "root",
    dir = ":__pkg__",  # special-case "__pkg__" to match the existing special-cased label.
    srcs = glob(["**"]),
)

directory(
    name = "subdir",
    dir = ":a",
    srcs = glob(["a/**"]),
)


visibility("public")

DirectoryInfo = provider(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This provider looks surprisingly heavyweight. Someone reaching for this kind of rule probably just wants to do something like:

ctx.actions.run(
    executable = [ctx.executable._sphinx],
    inputs = ctx.docs_root["DefaultInfo"].files.to_list(),
    outputs = [out_dir],
    arguments = [
        ctx.docs_root["DirectoryInfo"].directory,
        out_dir.path,
    ]
)

With the current provider's structure, how to achieve that goal is non-obvious to me. I understand that a lot of this information is handy (and in some cases critical to the current implementation), but it seems to get in the way of usability.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, I created rules_directory to do this instead. I'll close this PR.

And I agree with your concerns, when rewriting for rules_directory I simplified it a lot. The following should now be possible:

directory(
    name = "docs_root",
    srcs = glob(["**/*"], exclude=["BUILD.bazel"])
)

foo_rule(
    ...,
    docs_root = ":docs_root",
)

Then in the foo_rule implementation:

ctx.actions.run(
    executable = [ctx.executable._sphinx],
    inputs = ctx.docs_root[DefaultInfo].files.to_list(),
    outputs = [out_dir],
    arguments = [
        # This is preferred. It auto-detects if it's a source directory or a generated directory and picks appropriately.
        directory_path(ctx.docs_root[DirectoryInfo]),
        # If it can't tell which it is, one of these may be required
        ctx.docs_root[DirectoryInfo].source_path,
        ctx.docs_root[DirectoryInfo].generated_path,
        out_dir.path,
    ]
)

@matts1 matts1 closed this May 7, 2024
@matts1 matts1 deleted the directory branch May 7, 2024 00:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants