blob: 963d563a600bc902001faf6e41b7da5467e2b58b [file] [log] [blame] [view]
Zach Reiznerab5fdd32017-08-05 02:48:451# Rust on Chrome OS
2
Mike Frysinger05bebd52021-01-27 18:48:113*** note
4**Warning: This document is old & has moved. Please update any links:**<br>
5https://chromium.googlesource.com/chromiumos/docs/+/HEAD/rust_on_cros.md
6***
7
paulhsiaa238e9f2019-03-12 09:41:198This provides information on creating [Rust] projects for installation within
9Chrome OS and Chrome OS SDK. All commands and paths given are from within the
10SDK's chroot.
Zach Reiznerab5fdd32017-08-05 02:48:4511
12[TOC]
13
Zach Reiznerab5fdd32017-08-05 02:48:4514## Usage
15
paulhsiaa238e9f2019-03-12 09:41:1916[cros-rust.eclass] is an eclass that supports first-party and third-party crate
David Pursehouseb3b7da12019-06-17 12:23:3917dependencies. Rust project's ebuild should inherit the eclass to support Rust
paulhsiaa238e9f2019-03-12 09:41:1918building in Chrome OS build system.
Zach Reiznerab5fdd32017-08-05 02:48:4519
paulhsiaa238e9f2019-03-12 09:41:1920> **WARNING**: Some legacy projects are still using [cargo.eclass]. These two
21> eclasses can't be used together in a single project. Rust projects with
22> dependencies should all use `cros-rust.eclass`.
Zach Reiznerab5fdd32017-08-05 02:48:4523
paulhsiaa238e9f2019-03-12 09:41:1924### cros-rust.eclass
Zach Reiznerab5fdd32017-08-05 02:48:4525
paulhsiaa238e9f2019-03-12 09:41:1926All the Rust projects using `cros-rust.eclass` will get dependent crates from
27`/build/${BOARD}/usr/lib/cros_rust_registry` instead of [crates.io].
28You'll learn how to publish first-party and third-party crates to
29`cros_rust_registry` in the following sections.
30
31### Third-party ebuild crates
32
33To import a third-party crate, we need to create an ebuild for it in
34`~/chromiumos/src/third_party/chromiumos-overlay/dev-rust/<crate_name>/<crate_name>-<crate_version>.ebuild`.
Fletcher Woodruffb2acef82020-07-20 20:39:2835For an `example` crate with the following [SemVer] dependencies:
paulhsiaa238e9f2019-03-12 09:41:1936
37```toml
38[dependencies]
Fletcher Woodruffb2acef82020-07-20 20:39:2839libc = "0.2"
40getopts = "1.2"
41rayon = "1.4.1"
42http = "^0.1.8"
43indexmap = "^1.0"
44string = "~1.2"
45bit-set = "~2.7.1"
46walkdir = "~2"
paulhsiaa238e9f2019-03-12 09:41:1947```
48
Fletcher Woodruffb2acef82020-07-20 20:39:2849We would create the following ebuild:
Zach Reiznerab5fdd32017-08-05 02:48:4550
51```bash
52# Copyright <copyright_year> The Chromium OS Authors. All rights reserved.
53# Distributed under the terms of the GNU General Public License v2
54
Fletcher Woodruffb2acef82020-07-20 20:39:2855EAPI="7"
Zach Reiznerab5fdd32017-08-05 02:48:4556
Allen Webb7b9fc022019-09-24 20:58:5157CROS_RUST_REMOVE_DEV_DEPS=1
58
paulhsiaa238e9f2019-03-12 09:41:1959inherit cros-rust
60
61DESCRIPTION="An example library"
62HOMEPAGE="url/to/the/homepage"
63SRC_URI="https://crates.io/api/v1/crates/${PN}/${PV}/download -> ${P}.crate"
64
65LICENSE="|| ( <fill in license> )"
66SLOT="${PV}/${PR}"
67KEYWORDS="*"
68
69DEPEND="
Fletcher Woodruffb2acef82020-07-20 20:39:2870 =dev-rust/libc-0.2*:=
71 =dev-rust/getopts-1.2*:=
72 >=dev-rust/rayon-1.4.1:= <dev-rust/rayon-2.0
73 >=dev-rust/http-0.1.8:= <dev-rust/http-0.2
74 =dev-rust/indexmap-1*:=
75 =dev-rust/string-1.2*:=
76 >=dev-rust/bit-set-2.7.1:= <dev-rust/bit-set-2.8
77 =dev-rust/walkdir-2*:=
Zach Reiznerab5fdd32017-08-05 02:48:4578"
Zach Reiznerab5fdd32017-08-05 02:48:4579```
80
paulhsiaa238e9f2019-03-12 09:41:1981- `DESCRIPTION`, `HOMEPAGE`, `SRC_URI` and `LICENSE` should be found from
82 `Cargo.toml` or [crates.io].
83- All the dependencies should have a `cros-rust` ebuild and be listed in
84 DEPEND section.
Fletcher Woodruffb2acef82020-07-20 20:39:2885- Dependencies in `Cargo.toml` which do not have any operator specified in
86 their version number (for example, '^', '<', '~') are handled the same as
87 crates with '^' specified.
paulhsiaa238e9f2019-03-12 09:41:1988- Download the crate from [crates.io] and upload it to [localmirror].
89 (Check details in "Depending on Crates" section).
90- Run command `ebuild example.ebuild digest` to generate Manifest.
Zach Reiznerab5fdd32017-08-05 02:48:4591
paulhsiaa238e9f2019-03-12 09:41:1992After creating the ebuild file, running `emerge-${BOARD} <crate_name>` will
93install the crate's package to `cros-rust-registry`.
94
Allen Webb7b9fc022019-09-24 20:58:5195Many third party crates have dev dependencies that are not actually needed
96for Chrome OS. To keep dev dependencies from being enforced
97`cros-rust.eclass` provides, `CROS_RUST_REMOVE_DEV_DEPS` which can be set to
98remove the dev dependencies during `src_prepare`. This is especially useful when
99there would otherwise be circular dependencies.
100
paulhsiaa238e9f2019-03-12 09:41:19101### Empty crates
102
103If some third-party crates are dependent on some **unused** crates (e.g.,
104dependencies uses by unused features or they're in dev-dependencies) and we want
105to mock those **unused** crates out, we could create empty-crate ebuilds for
106them. Here is an empty ebuild for example crate:
107
108```bash
109# Copyright <copyright_year> The Chromium OS Authors. All rights reserved.
110# Distributed under the terms of the GNU General Public License v2
111
112EAPI="6"
113
114CROS_RUST_EMPTY_CRATE=1
115
116inherit cros-rust
117
118DESCRIPTION="Empty example crate"
119HOMEPAGE=""
120
121LICENSE="BSD-Google"
122SLOT="${PV}/${PR}"
123KEYWORDS="*"
124```
125
126### First-party crates
127
128You can create your Rust project in anywhere in the Chrome OS system and it's
129ebuild in a suitable place in `chromiumos-overlay` with name
130`<category>/<crate_name>-9999.ebuild`. Here is an ebuild for
131an example **first-party** crate:
132
133```bash
134# Copyright <copyright_year> The Chromium OS Authors. All rights reserved.
135# Distributed under the terms of the GNU General Public License v2
136
137EAPI="6"
138
139CROS_WORKON_LOCALNAME="example"
140CROS_WORKON_PROJECT="path/to/project/repository"
141# We don't use CROS_WORKON_OUTOFTREE_BUILD here since project's Cargo.toml is
142# using "provided by ebuild" macro which supported by cros-rust.
143CROS_WORKON_SUBTREE="path/to/project/subtree"
144
145inherit cros-workon cros-rust
146
147DESCRIPTION="An example first party project"
148HOMEPAGE="home_page_url"
149
150LICENSE="BSD-Google"
Chirantan Ekbote61b7be32019-09-25 01:56:38151SLOT="0/${PVR}"
paulhsiaa238e9f2019-03-12 09:41:19152KEYWORDS="~*"
153IUSE="test"
154
155DEPEND="
156 dev-rust/third_party_crate:=
157 example2/first_party_crate:=
158"
159
160src_unpack() {
161 cros-workon_src_unpack
162 S+="/path/to/project/subtree"
163
164 cros-rust_src_unpack
165}
166
167src_compile() {
Andrew McRae089013e2019-06-11 02:15:20168 ecargo_build
paulhsiaa238e9f2019-03-12 09:41:19169 use test && ecargo_test --no-run
170}
171
172src_test() {
173 if use x86 || use amd64; then
174 ecargo_test
175 else
176 elog "Skipping rust unit tests on non-x86 platform"
177 fi
178}
179
180src_install() {
181 # You can
182 # 1. Publish this library for other first-party crates by
183 cros-rust_publish "${PN}" "$(cros-rust_get_crate_version)"
184 # 2. Install the binary to image by
185 dobin "$(cros-rust_get_build_dir)/example_bin"
186}
187```
188
189If the Rust project will be used by other first-party crates, remember to
190publish it by using the `cros-rust_publish` command.
191
192> **WARNING**: Please make sure your project could be built by both steps for
193> engineering productivity:
194>
195> 1. From chroot with `emerge-${BOARD} CRATE-EBUILD-NAME`
196>
197> **Tips**: You can set `USE=-lto` to speed up build times when using
198> emerge. This turns off link time optimization, which is useful for
199> release builds but significantly increases build times and isn't really
200> needed during development.
201>
202> 2. From project root directory with `cargo build`
203>
David Pursehouseb3b7da12019-06-17 12:23:39204> We add two macros to resolve conflicts between these two build system. Check
paulhsiaa238e9f2019-03-12 09:41:19205> details from the following section.
206
207### Cargo.toml macros
208
209Using `cros-rust` ebuild could support building crates in Chrome OS build
210system, but it will break local `cargo build` in some situations. We add two
David Pursehouseb3b7da12019-06-17 12:23:39211macros which are recognized by ebuild for `Cargo.toml` to keep both build system
paulhsiaa238e9f2019-03-12 09:41:19212work.
213
214- Provided by ebuild
215
216 This macro introduces a replacement of:
217
218 ```toml
219 [dependencies]
220 data_model = { path = "../data_model" } # provided by ebuild
221 ```
222
223 with:
224
225 ```toml
226 [dependencies]
227 data_model = { version = "*" }
228 ```
229
230 **Example usage**: Add dependency to first-party crate
231
232 1. Add the dependent crate to DEPEND section in ebuild.
David Pursehouseb3b7da12019-06-17 12:23:39233 2. Use relative path for imported crates in `Cargo.toml` but with
paulhsiaa238e9f2019-03-12 09:41:19234 `# provided by ebuild` macro:
235
236 ```toml
237 [dependencies]
238 data_model = { path = "../data_model" } # provided by ebuild
239 ```
240
241- Ignored by ebuild
242
243 We will use this to discard parts of `[patch.crates-io]` which should be
244 applied to local developer builds but not to ebuilds.
245
246 This macro introduces a replacement of:
247
248 ```toml
249 audio_streams = { path = "../../third_party/adhd/audio_streams" } # ignored by ebuild
250 ```
251
252 with empty line while building with emerge.
253
254 **Example usage**: Add dependency to first-party crate for sub-crates from
255 root crate.
256
257 1. Add the dependent crate to DEPEND section in root crate's ebuild.
David Pursehouseb3b7da12019-06-17 12:23:39258 2. Use relative path for imported crates in `[patch.crates-io]` section in
paulhsiaa238e9f2019-03-12 09:41:19259 root crate's `Cargo.toml` but with `# ignored by ebuild` macro:
260
261 ```toml
262 [patch.crates-io]
263 audio_streams = { path = "../../third_party/adhd/audio_streams" } # ignored by ebuild
264 ```
Zach Reiznerab5fdd32017-08-05 02:48:45265
266## Depending on Crates
267
paulhsiaa238e9f2019-03-12 09:41:19268Because the sources for all ebuilds in Chrome OS must be available at
269[localmirror], you will have to upload all third-party crate dependencies for
270the project to localmirror.
Zach Reiznerab5fdd32017-08-05 02:48:45271
paulhsiaa238e9f2019-03-12 09:41:19272The following will download a crate, upload it to localmirror, and make it
273accessible for download:
Zach Reiznerab5fdd32017-08-05 02:48:45274
paulhsiaa238e9f2019-03-12 09:41:19275> **WARNING**: localmirror is shared by all Chrome OS developers. If you break
276> it, everybody will have a bad day.
Zach Reiznerab5fdd32017-08-05 02:48:45277
Tom Hughese6f05112019-08-06 15:35:38278```bash
Zach Reiznerab5fdd32017-08-05 02:48:45279curl -L 'https://crates.io/api/v1/crates/<crate_name>/<crate_version>/download' >/tmp/crates/<crate_name>-<crate_version>.crate
paulhsiaa238e9f2019-03-12 09:41:19280gsutil cp -a public-read /tmp/crates/<crate_name>-<crate_version>.crate gs://chromeos-localmirror/distfiles/
Zach Reiznerab5fdd32017-08-05 02:48:45281```
282
paulhsiaa238e9f2019-03-12 09:41:19283## Cross-compiling
Zach Reiznerab5fdd32017-08-05 02:48:45284
285The toolchain that is installed by default is targetable to the following triples:
286
Zach Reiznere0434ea2018-12-01 02:40:52287| Target Triple | Description |
288|-------------------------------|-------------------------------------------------------------------------------------|
289| `x86_64-pc-linux-gnu` | **(default)** Used exclusively for packages installed in the chroot |
290| `armv7a-cros-linux-gnueabihf` | Used by 32-bit usermode ARM devices |
291| `aarch64-cros-linux-gnu` | Used by 64-bit usermode ARM devices (none of these exist as of November 30th, 2018) |
292| `x86_64-cros-linux-gnu` | Used by x86_64 devices |
Zach Reiznerab5fdd32017-08-05 02:48:45293
paulhsiaa238e9f2019-03-12 09:41:19294When building Rust projects for development, a non-default target can be
295selected as follows:
Zach Reiznerab5fdd32017-08-05 02:48:45296
Tom Hughese6f05112019-08-06 15:35:38297```bash
Zach Reizner9125e7f2017-08-22 18:05:19298cargo build --target=<target_triple>
299```
300
paulhsiaa238e9f2019-03-12 09:41:19301If a specific board is being targeted, that board's sysroot can be used for
302compiling and linking purposes by setting the `SYSROOT` environment variable as
303follows:
Zach Reizner9125e7f2017-08-22 18:05:19304
Tom Hughese6f05112019-08-06 15:35:38305```bash
Zach Reizner9125e7f2017-08-22 18:05:19306export SYSROOT="/build/<board>"
Zach Reiznerab5fdd32017-08-05 02:48:45307```
paulhsiaa238e9f2019-03-12 09:41:19308
309If C files are getting compiled with a build script that uses the `cc` or `gcc`
310crates, you may also need to set the `TARGET_CC` environment variable to point
311at the appropriate C compiler.
Sonny Rao3d6115d2018-02-07 00:42:24312
Tom Hughese6f05112019-08-06 15:35:38313```bash
Sonny Rao3d6115d2018-02-07 00:42:24314export TARGET_CC="<target_triple>-clang"
315```
Zach Reiznerab5fdd32017-08-05 02:48:45316
paulhsiaa238e9f2019-03-12 09:41:19317If a C/C++ package is being pulled in via `pkg-config`, the
318`PKG_CONFIG_ALLOW_CROSS` environment
319variable should be exposed. Without this, you might see `CrossCompilation`
320as part of an error message during build script execution.
Zach Reiznere0434ea2018-12-01 02:40:52321
Tom Hughese6f05112019-08-06 15:35:38322```bash
Zach Reiznere0434ea2018-12-01 02:40:52323export PKG_CONFIG_ALLOW_CROSS=1
324```
325
paulhsiaa238e9f2019-03-12 09:41:19326[rust]: https://www.rust-lang.org
327[cargo]: https://crates.io/
Mike Frysinger9fc0fc02020-09-05 05:18:57328[cargo.eclass]: https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/HEAD/eclass/cargo.eclass
paulhsiaa238e9f2019-03-12 09:41:19329[crates.io]: https://crates.io
Mike Frysinger9fc0fc02020-09-05 05:18:57330[cros-rust.eclass]: https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/HEAD/eclass/cros-rust.eclass
Daniel Verkamp8a12ef62018-12-03 21:55:58331[localmirror]: archive_mirrors.md
Zach Reiznerab5fdd32017-08-05 02:48:45332[link time optimizations]: https://en.wikipedia.org/wiki/Interprocedural_optimization
paulhsiaa238e9f2019-03-12 09:41:19333[semver]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html