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

[bazel] Define rules-based CC lowRISC toolchain #25810

Merged
merged 6 commits into from
Jan 10, 2025

Conversation

jwnrt
Copy link
Contributor

@jwnrt jwnrt commented Jan 8, 2025

Summary

This PR defines a lowRISC toolchain configuration using the new rules added to rules_cc in version 0.0.10 and supersedes the rules from CRT. The actual toolchain and its flags should be identical.

This removes the final dependency that needed to be migrated to Bzlmod.

Overview

The RISC-V C/C++ compiler we're using (the lowRISC toolchain) is currently configured for Bazel in the CRT repo. The correct binaries and flags are bound together in such a way that Bazel can use them to compile, assemble, link, etc.

The rules in CRT are much easier to use than the old way of configuring toolchains in Bazel. The Pigweed project similarly implemented their own rules for configuring toolchains and got them upstreamed into the official rules_cc: https://pigweed.dev/docs/blog/06-better-cpp-toolchains.html

These new rules are very similar to the rules from CRT. This PR uses the new rules to configure the lowRISC toolchain within the OpenTitan repository.

Benefits

  • CRT does not yet support Bzlmod and we had some difficulties porting it.
    • CRT is our last non-bzlmod dependency. This PR is the final step to fully supporting Bzlmod.
  • Configuring the toolchain within the OpenTitan repo makes it easier to iterate on.
    • The toolchain can be updated in one place rather than in two stages across CRT and OpenTitan.
    • New flags can be added and tested immediately on OpenTitan code.

Drawbacks

The new rules-based toolchains have a slightly different CCToolchainInfo provider to the previous ones. Tools are now associated with actions rather than as files. Bazel seems to be moving in the direction of deprecating the files-based associations, so it's a good thing for us to migrate, however there is a chance that some things will not yet be supported.

What this means concretely is that you cannot access tools from the cc_toolchain object using parameters like ld_executable and ar_executable. We were using this feature in some of our rules, and some dependencies like rules_foreign_cc use it too.

Bazel now wants you to use cc_common.get_tool_for_action however this isn't a 1:1 replacement. You can only access tools associated with the CC actions Bazel uses (compiling, linking, etc). For some reason there's no action for objdump even though that tool can be part of the CC toolchain.

I have worked around this by accessing tools directly from the cc_toolchain's data files. This could be considered a hack, but I don't think there are any issues with doing this.

See bazelbuild/rules_cc#297

edit: see conversations below. We are now using get_tool_for_action for everything except the OTBN toolchain which actually needs specifically RISCV32 tools. That toolchain now loads binaries directly from the lowrisc toolchain repository which is more correct.

Testing

The toolchain should be configured the same as from CRT. I've checked that the mask ROM has the same hash when compiled before and after this PR:

# before
$ bazel build //sw/device/silicon_creator/rom:mask_rom --platforms=@crt//platforms/riscv32:opentitan
$ sha256sum bazel-bin/sw/device/silicon_creator/rom/mask_rom_silicon_creator.39.scr.vmem
dbab0d7bcee7d27b9ad17ba450ad98f250c8833c9d5868eed0f39da64dff01b1

# after
$ bazel build //sw/device/silicon_creator/rom:mask_rom --platforms=//third_party/lowrisc:opentitan_platform
$ sha256sum bazel-bin/sw/device/silicon_creator/rom/mask_rom_silicon_creator.39.scr.vmem
dbab0d7bcee7d27b9ad17ba450ad98f250c8833c9d5868eed0f39da64dff01b1

The flags that CRT adds are spread across these three files:

  1. https://github.com/lowRISC/crt/blob/main/platforms/riscv32/features/BUILD.bazel
  2. https://github.com/lowRISC/crt/blob/main/features/common/BUILD.bazel
  3. https://github.com/lowRISC/crt/blob/main/features/embedded/BUILD.bazel

Compare to the flags added in this version:

@jwnrt jwnrt force-pushed the rules-cc-lowrisc-toolchain branch 3 times, most recently from a0115cd to ec562a7 Compare January 8, 2025 16:53
@jwnrt jwnrt requested a review from pamaury January 8, 2025 16:58
@jwnrt jwnrt marked this pull request as ready for review January 8, 2025 16:58
@jwnrt jwnrt requested review from a team and cfrantz as code owners January 8, 2025 16:58
@jwnrt jwnrt requested review from hcallahan-lowrisc and removed request for a team January 8, 2025 16:58
@jwnrt jwnrt force-pushed the rules-cc-lowrisc-toolchain branch 2 times, most recently from edd9495 to 728d95e Compare January 9, 2025 12:03
third_party/lowrisc/extensions.bzl Outdated Show resolved Hide resolved
rules/opentitan/transform.bzl Outdated Show resolved Hide resolved
@jwnrt jwnrt force-pushed the rules-cc-lowrisc-toolchain branch from 728d95e to 290837a Compare January 9, 2025 12:40
@jwnrt jwnrt requested a review from nbdd0121 January 9, 2025 12:44
@jwnrt
Copy link
Contributor Author

jwnrt commented Jan 9, 2025

Ah, English Breakfast is broken because it doesn't use bitmanip and I took away the feature for enabling that.

@pamaury
Copy link
Contributor

pamaury commented Jan 9, 2025

Regarding the problem with actions vs tools, would it make sense to define custom actions using cc_action_type to work around this?

@jwnrt jwnrt force-pushed the rules-cc-lowrisc-toolchain branch from 290837a to 1b1dbf6 Compare January 9, 2025 14:10
@jwnrt
Copy link
Contributor Author

jwnrt commented Jan 9, 2025

There was a new feature added to CRT after I started this work: lowRISC/crt#41

I'll need to port those flags too

@jwnrt
Copy link
Contributor Author

jwnrt commented Jan 9, 2025

Regarding the problem with actions vs tools, would it make sense to define custom actions using cc_action_type to work around this?

Hmm, that looks like it could work actually. I'll take a look at this.

@jwnrt jwnrt force-pushed the rules-cc-lowrisc-toolchain branch 2 times, most recently from af8bb67 to 4dbbc3c Compare January 9, 2025 15:21
@jwnrt
Copy link
Contributor Author

jwnrt commented Jan 9, 2025

I tried out the action_type method and it mostly does seem to work, but honestly it ends up being more complicated and I think error prone than looking up tools directly. With the action types, you're still looking them up by string but now the string is something we define within the bazel project and it has to match everywhere it's used.

The built-in actions expose their names through @rules_cc//cc:action_names.bzl constants, but even those are unintuitive. The name for the archiver is CPP_LINK_STATIC_LIBRARY_ACTION_NAME for example.

For these situations in our repo where we know we want a specific tool like riscv32-unknown-elf-ld, I think it makes more sense to just ask for it directly.

@jwnrt
Copy link
Contributor Author

jwnrt commented Jan 9, 2025

I've also added the minsize feature and left it disabled by default since the version of CRT that it's added to hasn't been brought in here yet so it's not yet enabled.

@jwnrt jwnrt force-pushed the rules-cc-lowrisc-toolchain branch 3 times, most recently from b046393 to 3e43cb4 Compare January 10, 2025 13:50
Previously we were accessing the lowRISC toolchain indirectly via CRT,
but this isn't possible with Bzlmod. We need to pull the repo in
directly.

Signed-off-by: James Wainwright <james.wainwright@lowrisc.org>
@jwnrt jwnrt force-pushed the rules-cc-lowrisc-toolchain branch 2 times, most recently from 1eccfe1 to d661fa2 Compare January 10, 2025 13:53
@jwnrt
Copy link
Contributor Author

jwnrt commented Jan 10, 2025

@nbdd0121 @pamaury I have changed the code again to use cc_common.get_tool_for_action in the end like you both suggested.

The OTBN toolchain still needs specific riscv32-unknown-elf-* binaries and always will, so I've changed that code to depend directly on them from the lowrisc toolchain rather than pull them from the cc_toolchain.

In theory this will allow us to do things like introduce a CHERIoT toolchain as the cc_toolchain and have everything automatically load the right tools while OTBN can continue using its non-CHERIoT versions.

@jwnrt jwnrt force-pushed the rules-cc-lowrisc-toolchain branch from d661fa2 to 2b0b66d Compare January 10, 2025 14:05
@pamaury
Copy link
Contributor

pamaury commented Jan 10, 2025

Thanks @jwnrt Regarding OTBN, I think you new code is fine for now. Maybe we can revisit it later with either a custom toolchain or by adding custom actions for the missing tools if necessary.

toolchain/BUILD Outdated Show resolved Hide resolved
Copy link
Contributor

@pamaury pamaury left a comment

Choose a reason for hiding this comment

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

Looks good but I would suggest to use a constant for the objdump action.

@jwnrt jwnrt force-pushed the rules-cc-lowrisc-toolchain branch from 2b0b66d to 568a89b Compare January 10, 2025 14:23
jwnrt added 3 commits January 10, 2025 14:35
Bazel is moving towards deprecating the `tool_path` style of CC
toolchain which allowed executables to be taken using the `*_executable`
parameters. The new method is `cc_common.get_tool_for_action` which
works with both the old and new toolchain style.

This commit changes all usages except for `objdump` which has no
associated action. A future commit will create a custom objdump action
for our toolchain and change this usage then.

The OTBN toolchain actually needs exact tools. Instead of pulling these
from the `cc_toolchain` it makes more sense to access the binaries
directly from our toolchain repo.

Signed-off-by: James Wainwright <james.wainwright@lowrisc.org>
Matches the arguments used in `//third_party/coremark/top_earlgrey`.
Allows the feature-per-warning method from CRT to be replaced with one
set of warnings which is easier to manage.

Signed-off-by: James Wainwright <james.wainwright@lowrisc.org>
This uses the new rules-based toolchain feature of `rules_cc` to define
the lowRISC toolchain with the same flags that the CRT toolchain had.

There are two differences:

1. The CRT toolchain does not have the `guards` feature enabled by
   default, we enable it in `.bazelrc`. This new one is enabled
   automatically.

2. The CRT toolchain has `-Wpedantic` enabled by default, but we disable
   it in `.bazelrc`. This new one has it disabled by default.

Signed-off-by: James Wainwright <james.wainwright@lowrisc.org>
@jwnrt jwnrt force-pushed the rules-cc-lowrisc-toolchain branch from 568a89b to 794cedd Compare January 10, 2025 14:36
jwnrt added 2 commits January 10, 2025 15:15
This removes the dependency on CRT and registers the new rules-based
toolchain instead.

Since `guards` is now enabled by default and `pedantic` is now disabled
by default, we can remove those configurations from `.bazelrc`. The
configuration to disable `guards` is still present.

Without CRT, we also don't need to manually load the following repos
into the airgapped environment:

* `@python3_toolchains`
* `@ninja_1.11.0_linux`
* `@cmake-3.23.2-linux-x86_64`

We also now need to switch how we access objdump in our disassembly
rule to use the actions-based method. See previous commits.

Signed-off-by: James Wainwright <james.wainwright@lowrisc.org>
Signed-off-by: James Wainwright <james.wainwright@lowrisc.org>
@jwnrt jwnrt force-pushed the rules-cc-lowrisc-toolchain branch from 794cedd to c145262 Compare January 10, 2025 15:20
@jwnrt jwnrt mentioned this pull request Jan 10, 2025
16 tasks
@jwnrt jwnrt merged commit 4ee5ecb into lowRISC:master Jan 10, 2025
38 checks passed
@jwnrt jwnrt deleted the rules-cc-lowrisc-toolchain branch January 10, 2025 20:57
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.

3 participants