README.md
1# 3rd party Rust crates from crates.io
2
3This repository contains Rust crates imported from crates.io for use by the Android platform.
4
5The files in this repository are managed by a tool, which you can run from this directory:
6
7```
8./crate_tool help
9```
10
11Most of the files here should not be edited manually, and pre-upload checks will catch and prevent such changes.
12
13## How to edit build rules
14
15Do not edit Android.bp files directly. Instead, edit cargo_embargo.json and run `./crate_tool regenerate <crate name>`.
16
17Refer to the [cargo_embargo documentation](https://android.googlesource.com/platform/development/+/main/tools/cargo_embargo/README.md)
18for more information.
19
20## How to update a crate
21
22Do not use `external_updater`. Use `crate_tool` as follows:
23
24### Finding updatable crates
25
26This will print every newer version of every crate:
27
28```
29./crate_tool updatable-crates
30```
31
32### Analyzing updates for a particular crate
33
34To check all newer versions of a crate for potential problems:
35
36```
37./crate_tool analyze-updates <crate name>
38```
39
40### Updating a crate
41
42To update a crate to a specified version:
43
44```
45./crate_tool update <crate name> <version>
46```
47
48This does not do any `repo` or `git` operations, so if the update is successful, you will need to run `repo start`, `git commit`, `repo upload`, etc.
49
50Several problems can occur when updating a crate:
51* Patches can fail to apply. In this case, you may need to edit or remove the offending patch files in in the `patches/` directory.
52* `cargo_embargo` may fail, requiring edits to `cargo_embargo.json`
53* Android may fail to build due to missing dependencies or syntax changes in the updated crate.
54
55The update command does not try to build the Android tree, but a recommended local test before `repo upload` is to build everything under `external/rust`:
56
57```
58source build/envsetup.sh
59lunch aosp_husky-trunk_staging-eng
60cd external/rust
61mm
62```
63
64### Manual updates
65
66Instead of running `./crate_tool update <crate name> <version>`, you can edit `pseudo_crate/Cargo.toml` directly and run
67`./crate_tool regenerate <crate name>`. This can be useful when pairs of crates need to be updated in lockstep. This can happen, for example,
68when a crate has an associated proc_macro crate. So to update `foo` and `foo_derive` together, edit the versions of both in `pseudo_crate/Cargo.toml`, then run:
69
70```
71./crate_tool regenerate foo foo_derive
72```
73
74### Keeping crates updated
75
76If you don't have a specific crate you need to update, but want to help keep the crate repository up-to-date, the crate tool can suggest crate updates that seem likely to succeed:
77
78```
79./crate_tool suggest-updates
80```
81
82Since the only way to be confident an update will work is to try building it, the tool can try out the suggested updates and see if they succeed. If you have some spare cycles, try running the following overnight:
83
84```
85./crate_tool try-updates | tee crate-updates
86```
87
88## How to add a patch file
89
90You should avoid creating patches, if possible. Every patch file is an ongoing
91operational burden that makes it more difficult to keep our crates up-to-date.
92
93If a patch is absolutely necessary, you should, if possible, send a pull
94request to the upstream crate, so we can eliminate the Android patch in the
95future, when upgrading.
96
97To create a patch for crate "foo", edit the files directly. Then do:
98
99```
100git diff --relative=crates/foo -- crates/foo/<file1> crates/foo/<file2> > patches/<name>.patch`
101```
102
103If you stage or commit the change and the patch, you should see no new changes
104when you run "regenerate".
105
106## I want to know how the sausage is made
107
108The source code for `crate_tool` is [here](https://android.googlesource.com/platform/development/+/refs/heads/main/tools/external_crates/).
109
110The basic principle of the tool is that every crate directory in
111[crates/](https://android.googlesource.com/platform/external/rust/android-crates-io/+/refs/heads/main/crates/)
112must be exactly reproducible by an automatic process from a known set of inputs:
113
114* The crate archive from crates.io.
115* A limited set of known Android-specific customizations, such as `METADATA`, `TEST_MAPPING`, and `MODULE_LICENSE_*` files.
116* Any necessary patches, in the `patches/` directory.
117* `cargo_embargo.json`, which is used to generate `Android.bp`.
118
119Therefore, what `./crate_tool regenerate <crate name>` does is:
120
121* Downloads the crate from crates.io, using `cargo vendor`
122* Copies (or generates from scratch) `METADATA`, `TEST_MAPPING`, etc.
123* Applies patches to the crate.
124* Generates `Android.bp` by running cargo_embargo.
125* Replaces the crate directory with the regenerated contents.
126
127The pre-upload check does exactly the same thing, but without the final step. Instead of replacing the directory contents, it
128checks that what it generated from scratch matches the actual crate directory contents.
129
130Crate update are also built on top of `regenerate`. What `./crate_tool update <crate name> <version>` does is:
131
132* `cargo remove <crate_name>`
133* `cargo add <crate_name>@=<version>`
134* `./crate_tool regenerate <crate name>`
135