Skip to content

bindgen: don't register_toolchains in Bzlmod #3231

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

Merged
merged 11 commits into from
Feb 27, 2025

Conversation

lalten
Copy link
Contributor

@lalten lalten commented Feb 2, 2025

I'm currently in the process of getting rules_ros2 onto Bzlmod. One challenge is that its rust support requires rules_rust_bindgen, which depends on llvm-project, which takes more than GitHub Action's maximum configurable job timeout (10h) to build. See mvukov/rules_ros2#238 (comment)

This PR adds new "bring your own clang" build flags: --@rules_rust_bindgen//:clang and --@rules_rust_bindgen//:libclang. As the added test shows, you can point these at toolchains_llvm's pre-compiled clang.

The fancy !!set and << merge key yaml magic is documented in https://github.com/bazelbuild/continuous-integration/tree/master?tab=readme-ov-file#sharing-configuration-between-tasks

Let me know what you think about this. I'm also curious what's the rationale for depending on llvm-project instead of toolchains_llvm in the first place. Maybe instead of making this configurable (and thus adding complexity) rules_rust_bindgen could just be switched over to toolchains_llvm completely?

@lalten lalten mentioned this pull request Feb 2, 2025
@UebelAndre
Copy link
Collaborator

Thanks! Outside of bzlmod the expectation was that consumers could bring their own clang by defining their own toolchains and not registering the default ones via:

def rust_bindgen_register_toolchains(register_toolchains = True):
"""Registers the default toolchains for the `rules_rust` [bindgen][bg] rules.
[bg]: https://rust-lang.github.io/rust-bindgen/
Args:
register_toolchains (bool, optional): Whether or not to register toolchains.
"""
if register_toolchains:
native.register_toolchains(str(Label("//:default_bindgen_toolchain")))

I think that would be a better approach than to have build flags users need to put in their .bazelrc files. I'm still fairly new to bzlmod but does that sound possible?

@lalten
Copy link
Contributor Author

lalten commented Feb 7, 2025

Outside of bzlmod the expectation was that consumers could bring their own clang by defining their own toolchains

Yes that's what we did as well so far in another repo that doesn't use the Bzlmod bindgen yet.

I'm not a toolchains registering expert but https://bazel.build/external/migration#register-toolchains:~:text=You%20cannot%20call%20native.register_toolchains%20in%20a%20module%20extension. sounds like it is not possible to do this outside of MODULE.bazel

@lalten
Copy link
Contributor Author

lalten commented Feb 11, 2025

Friendly bump on this @UebelAndre :)

@UebelAndre
Copy link
Collaborator

UebelAndre commented Feb 12, 2025

I'm not a toolchains registering expert but https://bazel.build/external/migration#register-toolchains:~:text=You%20cannot%20call%20native.register_toolchains%20in%20a%20module%20extension. sounds like it is not possible to do this outside of MODULE.bazel

I think what you can do is set the toolchain registration as dev_dependency = True and require that consumers of rules_rust_bindgen always explicitly register their own. I might then make a target @rules_rust_bindgen//toolchain for folks to use and document the need to add the following to their MODULE.bazel files.

register_toolchains(
    "@rules_rust_bindgen//toolchain",
)

Or in your case

register_toolchains(
    "//my/bindgen/toolchain",
)

@lalten
Copy link
Contributor Author

lalten commented Feb 12, 2025

set the toolchain registration as dev_dependency = True and require that consumers of rules_rust_bindgen always explicitly register their own.

Interesting idea! I tried this out and it works.

I might then make a target @rules_rust_bindgen//toolchain for folks to use and document the need

sgtm

@UebelAndre
Copy link
Collaborator

set the toolchain registration as dev_dependency = True and require that consumers of rules_rust_bindgen always explicitly register their own.

Interesting idea! I tried this out and it works.

I might then make a target @rules_rust_bindgen//toolchain for folks to use and document the need

sgtm

Do you wanna put up a pull request for this? 😅

@lalten lalten changed the title Add bring-your-own-clang build flags: --@rules_rust_bindgen//:clang, --@rules_rust_bindgen//:libclang bindgen: don't register_toolchains in Bzlmod Feb 12, 2025
Copy link
Collaborator

@UebelAndre UebelAndre left a comment

Choose a reason for hiding this comment

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

Nice, thanks! For the example though you'll wanna make sure it's running in CI by adding it to .bazelci/presubmit.yml. Then I think this is good to go!

libclang = ":libclang",
)

build_test(
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you wanna actually have a use of the toolchain in this example through toolchain resolution. Why not copy the simple test here instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using bindgen_test_suite here isn't straightforward because its deps are dev_dependencies of @rules_rust_bindgen. I used a symlink to reuse the integration test instead.

Copy link
Collaborator

Choose a reason for hiding this comment

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

What is a bindgen_test_suite?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@lalten
Copy link
Contributor Author

lalten commented Feb 13, 2025

I pushed my commits but I've run into an interesting problem: Somehow the toolchain depends on itself. Maybe you have an idea?

cd examples/bindgen_toolchainbazel test //...
ERROR: Misconfigured toolchains: //:my_bindgen_toolchain is declared as a toolchain but has inappropriate dependencies. Declared toolchains should be created with the 'toolchain' rule and should not have dependencies that themselves require toolchains.
.-> //:libclang
|   toolchain types @@bazel_tools//tools/cpp:toolchain_type
|   toolchain type @@bazel_tools//tools/cpp:toolchain_type
|   RegisteredToolchains
|   //:my_bindgen_toolchain
`-- //:libclang
Target //:clang up-to-date:
  bazel-bin/clang.exe
ERROR: Analysis of target '//test/integration/simple:simple' failed; build aborted
INFO: Elapsed time: 0.227s, Critical Path: 0.00s
INFO: 1 process: 5 action cache hit, 1 internal.
ERROR: Build did NOT complete successfully
ERROR: No test targets were found, yet testing was requested

rust_bindgen_toolchain(
name = "my_bindgen_toolchain",
bindgen = "@rules_rust_bindgen//3rdparty:bindgen",
clang = ":clang",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why the native_binary for this attribute?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@llvm_toolchain_llvm//:bin/clang is a filegroup, not an executable Label, so it needs to be "converted" with a genrule with executable=True, or a native_binary.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would genuinely just duplicate the code (which is not a lot). If I end up adding more tests I don't want them to appear so an example. We have no bindgen example currently so this would effectively become that and should show general use of the bindgen rules but with a custom toolchain (which is super useful info in an example).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

makes sense, done

llvm.toolchain(llvm_version = "17.0.6")
use_repo(llvm, "llvm_toolchain_llvm")

register_toolchains("//:my_bindgen_toolchain")
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is caused because you haven't registered a toolchain target but instead a rust_bindgen_toolchain target. You're missing that intermediate.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This I think is the solution to #3231 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

great point! I missed that one somehow. Now it works 👍

Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: can this be named README.md? That's the pattern we've used all over the repo.

@lalten lalten requested a review from UebelAndre February 18, 2025 08:41
@lalten
Copy link
Contributor Author

lalten commented Feb 20, 2025

friendly bump @UebelAndre

@UebelAndre UebelAndre enabled auto-merge February 27, 2025 16:43
@UebelAndre UebelAndre added this pull request to the merge queue Feb 27, 2025
Merged via the queue into bazelbuild:main with commit eec80a3 Feb 27, 2025
2 of 3 checks passed
@lalten lalten deleted the bindgen-clang-label-setting branch April 5, 2025 13:59
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.

2 participants