While updating the Rust toolchain there are various issues that can arise. Things can break, roadblocks can get in the way, and others might need to be brought in. In this section we describe the different types of issues that can occur, examples, and instruct on how to move past them.
They are organized by topics: - Section 2.1: Itemizes various breaks that can occur when building Rust during Step Test-2 Build locally. - Section 2.2: Describes roadblocks hit when testing during Step Test-3:Test, which is a part of Step Release-8: Testing Build - Section 2.3: Proves some notes on updating the prebuilts during Step Release-9:Update Prebuilts - Section 2.4: Describes issues with uploading to Gerrit as done in both Step Release 6:Upload and Step Release 10:Upload to Gerrit
Things that can break while building the Rust toolchain:
The Android project carries several patches for the Rust toolchain source. Patches make changes to a code file. In order for a patch file to be successfully applied the code that it is targeting needs to match the code file closely enough for the algorithm in the patch
program to identify the relevant code. If a patch file fails to be applied then it is likely due to a change in the targeted code base. In which case, the next step is to figure out if the patch is still necessary to be applied or if that Patch file can be removed.
To know which patch file failed take a look at the terminal error message. The error message will also say what hunk # and name of the Rust file. Open up the patch file in android_rust/patches
and the Rust file. At this point it'll either look like (1) patch was already applied, (2) the codebase was otherwise modified.
In the case of (1), it would be useful to verify that the patch was applied. This can be done by look at the log history for that Rust file.If you do believe that the patch was merged upstream then you just need to remove the patch from the patches/
directory, e.g.
pushd toolchain/android_rust repo start update-rustc-$RUST_VERSION git rm patches/rustc-000n-Already-merged.patch git commit -m "Remove Foo patch that has landed upstream" popd
In the case of (2), the codebase was changed in some way. Sometimes the difference might be very simple. For instance, one time the difference was just a variable name change and looking at the log history confirmed that.
To be able to successfully apply the patch the code in the patch must match the code base exactly so go ahead and modify the patch code to match the code base. If adding or removing lines of code be sure to update the number of lines that is noted in the patch file. If you are unsure if the change upholds the intent of the patch go ahead and email the patch owner, but note they will also be added as a reviewer. When generating patch files using git format-patch
be sure to include extra context (-U10
) as it is needed to successfully apply some patches.
After editing the patch file, upload the change to Gerrit, and ask the patch owner to review the changes to make sure the intent of the patch is still Upheld. Use the topic with “source”.
Here is an example of updating a patch file to correspond to changes in code CL.
It may also be useful to create a new patch. The following:
git format-patch -U10 HEAD~
will generate a patch file for just the previous commit.
Sometimes another library needs to be imported. We can do this by adding to the STDLIB_SOURCES
definition in the tools/build.py
script.
For example we got the following:
error: couldn't read prebuilts/rust/linux-x86/1.59.0/src/stdlibs/library/core/src/../../portable-simd/crates/core_simd/src/mod.rs: No such file or direct ory (os error 2) --> prebuilts/rust/linux-x86/1.59.0/src/stdlibs/library/core/src/lib.rs:415:1 | 415 | mod core_simd; | ^^^^^^^^^^^^^^ error: aborting due to previous error 22:37:34 ninja failed with: exit status 1 #### failed to build some targets (18 seconds) ####
and as a result we added the portable-simd library as seen in this CL.
TODO: text here to describe how the user will know this type of error occurred and how to fix it
TODO: text here to describe how the user will know this type of error occurred and how to fix it
Sometimes a new crate is added and a modification needs to be made to prebuilts/rustc/Android.bp
.
TODO: text here to describe how the user will know this type of error occurred and how to fix it
The solution might be to disable a new flag that have been added to the build process. Example CL
Check the out
file CMakeCache.txt
to see any additional flags that may have been added during the build process. Try testing the new flags with the older version of the compiler.
failed to execute command: "strip" "--strip-debug" "/usr/local/google/home/aosp/out/rustc/build/x86_64-unknown-linux-gnu/llvm/lib/libLLVM-17.so" error: No such file or directory (os error 2)
This indicates that strip
is not available on your local computer. We solved this by adding a symbolic link to another tool CL
Question: Should this be added to Section 2.1 Build Error - Missing Crate
or is it a different type of error?
If the sysroot build is broken, check whether the error mentions a missing crate. If it does, there have likely been new components added to the sysroot. To address this, you will need to:
STDLIB_SOURCES
in toolchain/android_rust/tools/build.py
.DIST_DIR=$TOOLCHAIN/dist ./toolchain/android_rust/tools/build.py
$DIST_DIR
prebuilts/rust
in your Android tree and use git fetch local
followed by a checkout to get it imported into your Android tree.prebuilts/rust/Android.bp
. Except for publicly exported crates (which you're not adding right now), all modules in this file must be suffixed with .rust_sysroot
to avoid confusion with user crates. Dependency edges should all be of rlib
form unless depending on a publicly exported crate, in which case the dependency edge should match the type of the final product. As examples, libterm
(exported) depends by dylib
on libstd
, but libterm.static
(also exported) depends by rlib
on libstd.static
.libhashbrown.rust_sysroot
is built only as an rlib
, and is linked as an rlib
everywhere it is used.Things that can break during testing:
A Hermeticity breakage occurs when the build uses a tool or header that is different from what we expect. For instance, a crate including a build script allowing a different compiler/library to be used than expected. Some of these issues arise because of bugs in the upstream build system. Others can also be caused because the environment they are built-in have certain defaults set and carry unintended expectations.
TODO @Chriswailes: Describle how to approach this type of problem, given lzma-sys example.
There can be build breakage issues.
For instance, needing to change "-C passes='sancov'"
, to "-C passes='sancov-module'"
, such as in this CL.
A common issue is that this step triggers new warnings on existing source files. If the compiler suggests a fix, apply it. Otherwise make the most reasonable looking change necessary to keep the compiler happy and rely on the original author to determine correctness during code review.
Here is an example of the workflow to modify file x.rs:
# navigate to the repo with file x.rs repo start rust-1.59.0-fixes # make changes to x.rs git add x.rs git commit
The commit message should include the testing strategy and buganizer ticket number. Here is an example commit message from one of these types of CLs.
Changes for the Rust 1.59.0 update bug: 215232614 Test: TreeHugger and compiling with m rust Change-Id: I1d25f5550f60ff1046a3a312f7bd210483bf9364
Note, that it is preferable to create one commit per big change to a repo, so it might be helpful to use amend when adding more changes to the code:
$ git commit --amend --no-edit
After committing the changes continue to upload them to Gerrit with
repo upload .
In Gerrit for the corresponding CL include the owners of the file as reviewers and do not set a topic
.
Next we will need to periodically check-in on these CLs. If they pass presubmit, then we are waiting for the CLs to be approved/submitted by the file owners. This can take a few days and may require a friendly nudge.
If the files do not pass presubmit then the changes may not have been backwards compatible with Rust and we will need to compile it with the latest version of Rust. If that is the case on Gerrit include it in the topic rust-update-prebuilts-1.59.0
, with an updated Rust version number.
We are not able to move to the final Step 12 (tagging) until these CLs created in this process has been submitted/accepted.
Clipper errors are typically pretty straightforward but sometimes it’s not clear what to change. Try checking at the change history or how the change has been implemented in other parts of the Rust codebase. For instance, builder.config.llvm_link_shared
was changed to !builder.llvm_link_shared()
.
A miscompilation may have occured when it successfully compiles but the devices fail to boot or pass CTS tests.
TODO: text here to describe how the user will know this type of error occurred and how to fix it
The following error:
warning: `-Z symbol-mangling-version` is deprecated; use `-C symbol-mangling-version`
led to changes where that variable was used with -Z
was changed to -C
in rust/config/global.go
. CL .
With this error
~/updates/aosp : > ./toolchain/android_rust/tools/test_compiler.py --prebuilt-path dist/rust-dev.tar.xz --target aosp_cf_x86_6 4_phone --image Test prebuilt directory already exists. Deleting contents. Extracting archive /usr/local/google/home/chiw/updates/aosp/dist/rust-dev.tar.xz /usr/local/google/home/chiw/updates/aosp/prebuilts/build-tools/linux-x86/bin/xz: /usr/local/google/home/c hiw/updates/aosp/dist/rust-dev.tar: File exists Traceback (most recent call last): File "/usr/local/google/home/chiw/updates/aosp/./toolchain/android_rust/test_compiler.py", line 198, in <module> sys.exit(main()) ^^^^^^ File "/usr/local/google/home/chiw/updates/aosp/./toolchain/android_rust/test_compiler.py", line 143, in main prepare_prebuilts(args.prebuilt_path) File "/usr/local/google/home/chiw/updates/aosp/./toolchain/android_rust/test_compiler.py", line 129, in prepare_prebuilts (target_and_version_path / "bin" / "rustc").touch() File "/usr/lib/python3.11/pathlib.py", line 1109, in touch fd = os.open(self, flags, mode) ^^^^^^^^^^^^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory: '/usr/local/google/home/chiw/updates/aosp/prebuil ts/rust/linux-x86/9.99.9/bin/rustc
Try
rm $DIST_DIR/rust-dev.tar
New lints/clippys can cause build breakage and may require significant refactoring as the code base grows. To avoid blocking toolchain upgrades, explicitly allow the breaking lints/clippys when first upgrading the toolchain.
build/soong/rust/config/lints.go
with the -A
flag.Things that can break when updating the prebuilts:
Try deleting the branch git branch -D rust-update-prebuilts-1.59.0-local
: > ./toolchain/android_rust/tools/update_prebuilts.py --chained 1.62.0 Unable to fetch LKGB build ID
This means you forgot to run gcert.
Note that some tests might fail during presubmit because of code that live in other manifests. Make the appropriate changes as usual, but in the right place.
Things that can break while uploading files to Gerrit:
Help, Gerrit won't take my update!
First, try again. Sometimes Gerrit is just flaky and will take it on the second or third try.
If that‘s still not working, you are likely hitting a size limitation (for example, because rustc
updated it’s LLVM revision, so the diff is bigger than usual). In this case, you will need to work with the build team to get them to use a “direct push” to skip Gerrit's hooks. Look at the initial import bug for an example conversation about importing oversized changes.
Use this to get away from detached head:
git branch -u aosp/master
If presbuilts failed presubmit, one thing you can do is try to run test locally
source build/envsetup.sh lunch aosp_cf_x86_64_phone-staging-userdebug m acloud create --local-image export ANDROID_SERIAL=<value printed by previous command> atest bytes_test_tests_test_bytes // or whatever tests are failing in the prebuilts
There could be an error parsing the results of running Rust tests.
A prior release Rust v.1.61 release notes include messages with ignored tests. We had to modify how the trade federation code analyzes the result of running tests (changed regex). CL The Gerrit CL triggered the same changes in Critique.
Sometimes it might be necessary to change the android_rust scripts themselves. Here are some examples:
out/a
on failure then try running m out/a
to reproduce the issue locally. * upstream Check recent relevant changes to the Rust upstream code since the last update