Build your robot code with Bazel - bazelrio

I was inspired by the recent CMake thread and decided to spend some time writing some Bazel helpers for building robot code. Without further ado, bazelrio!

Bazelrio provides some nice convenience features.

  • Easy cross compilation using official toolchains.
    If you build a target and specify the roboRIO platform (ex bazel build <target> --platforms=@bazelrio//platforms/roborio), bazelrio will download an official toolchain for your host and use it.
  • Robot code rules.
    Bazelrio provides a robot_cc_binary rule. Using this rule will generate a regular cc_binary target as well as a runnable <name>.deploy target that you can run to deploy code (wip).
  • Library targets.
    Bazelrio provides cc_library targets for WPILib and (in the future) CTRE, Kauai, and REV libraries. You can easily dep @bazelrio//libraries/wpilibc to include WPILib in your project.
  • Works on macOS, Linux, and Windows.

This project is certainly a work in progress and contributions are welcome. I was heavily inspired by team 971 and 1678 so shoutouts to them as well.

11 Likes

I was adding a similar thing, not focused on building wpilib itself because I was tired if Gradle being so slow, but it spider webbed up to being able to compile and run simulated robots. I didn’t get around to figuring out deployment yet since I haven’t seen a robot since week 2 2020.

allwpilib wasn’t ready to add a third build system, but here is the original PR. https://github.com/wpilibsuite/allwpilib/pull/3370

My rules live here https://github.com/bazelRio. I included she forks of other wpilib projects like shuffleboard and pathweaver configurably building from source or maven deps.

I’m by no means a bazel expert, so it was nice at a quick glance to see we did similar-ish things. Maybe we can combine some of things

3 Likes

Thanks for sharing! I definitely see some room to combine forces. Java targets, Python targets, Romi support, and simulation with Glass are all on my radar longer-term. I have a RIO and a Victor SPX I can test with if you want to send anything my way.

2 Likes

Hi!
This actually looks like a great idea to me and I’d like to contribute (I’m thinking about creating a VSCode extension for starters because I too am not very familiar with Bazel yet).
Are you guys working on Connor’s repository or on the bazelRio organization?

1 Like

We haven’t synced up yet, but either one is probably fine as we’re likely to combine in the future

1 Like

I thought I dm’d you but I don’t see it anywhere. I’ll summerize here for broader viz.

Like I said, I originally did this because I found gradle to be painfully slow with allwpilib when I was making PR’s last December. I use bazel at work, but pretty much limited to basic cc_library and py_library, not dealing in depth with our custom macros / rules / toolchains / remote caching / ci / etc, so this was also a learning experience for me.

allwpilib does some interesting things to deal with the shared libraries and JNI stuff (because windows is gross), so I had to do a lot of hacking and experimenting to get it building. I like the idea of a simpler version as Connor has for teams to used with the maven deps, rather than the full fledged “you can build your robot completely from source, but with weird warts” that I did.

Since I nabbed the organization name bazelRio on github, I think it should live there, but be based more on his rules.

1 Like

While I don’t think our team is ready to make the jump to Bazel for building robot code, we are using Bazel for some library/framework stuff we have in the pipeline, and having your implementation to check against mine for toolchain/platform is really nice (the documentation seems to be very hit or miss at the moment).

Your work also solved a problem I spent about 4 hours trying to debug yesterday:
build --experimental_use_sandboxfs in the .bazelrc (as you document) fixes some nasty issue where the sysroot for the toolchain doesn’t always get applied.

Another thing worth pointing out, two VSCode plugins were just recently released/updated that should make working with Bazel in VSCode a bit nicer: bazel-stack-vscode - Visual Studio Marketplace and bazel-stack-vscode-cc - Visual Studio Marketplace. Both seem to be part of a paid product, but provide free functionality to lint BUILD files and generate a clangd “compilation database” which this plugin can interpret to provide really solid code completion for C/C++ (much better than the Microsoft extension IMO).

Thanks for releasing this! I’ve just recently gotten to the point where I’m reasonably comfortable in Bazel, and I’d love to see it get some more traction in FRC, so projects like this are a big help.

4 Likes

The clang-generated info can also be used with Include-What-You-Use. This can automate #include management, which has several benefits – including significant build speedup in many cases.

1 Like

Slight tangent–GradleRIO can also generate compile-commands.json, but it’s not widely used (and thus may have a few bugs). We don’t use clangd by default for teams because it’s memory intensive and requires additional tools be installed.

2 Likes

Makes sense. Somehow you guys have managed to make the Microsoft C/C++ plugin work (in GradleRIO projects) much better than I have ever been able to in my own testing - it frequently requires me to close and reopen source files to get the Intellisense to update.

2 Likes

There is a significant amount of smarts in the vscode-wpilib extension that reads the GradleRIO build information and keeps Intellisense updated. See https://github.com/wpilibsuite/vscode-wpilib/tree/main/vscode-wpilib/src/cppprovider

1 Like

I ran IWYU on wpilib a while ago, and it generated a lot of false positives, false negatives, and inclusions of platform-specific internal headers that broke the build (both because they’re platform-specific and because the internal headers have #error directives to prevent direct inclusion). I had to fix up basically every file manually.

1 Like

That’s too bad. The version used internally at Google works really well. Of course, it’s basically operating incrementally in that context, since it is automatically run on every check-in, so the code prior to any given check-in is IWYU clean. With a new code base, I imagine it helps if one starts with the most basic headers and works up from there. But it could certainly be the version I linked has issues, or that the code bases are different enough that it doesn’t work with WPILib.

As it happens, Bazel (Blaze inside Google) supports a distinction between public and private headers and can enforce this usage. Anyway, thanks for the work to try this out!

Yeah… the caveats said as much. https://github.com/include-what-you-use/include-what-you-use#caveat

1 Like

Heads up, we’ve moved the project to https://github.com/bazelRio/bazelRio.