Skip to content

Commit a8837a5

Browse files
authored
Add docs for building Fuchsia locally and in CI (rust-lang#1989)
1 parent 3f1e015 commit a8837a5

File tree

4 files changed

+224
-13
lines changed

4 files changed

+224
-13
lines changed

src/SUMMARY.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
- [Compiletest](./tests/compiletest.md)
2525
- [UI tests](./tests/ui.md)
2626
- [Test headers](./tests/headers.md)
27+
- [Integration testing](./tests/integration.md)
28+
- [Crater](./tests/crater.md)
29+
- [Fuchsia](./tests/fuchsia.md)
2730
- [Performance testing](./tests/perf.md)
28-
- [Crater](./tests/crater.md)
2931
- [Suggest tests tool](./tests/suggest-tests.md)
3032
- [Debugging the compiler](./compiler-debugging.md)
3133
- [Using the tracing/logging instrumentation](./tracing.md)

src/tests/fuchsia.md

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# Fuchsia integration tests
2+
3+
[Fuchsia](https://fuchsia.dev) is an open-source operating system with about 2
4+
million lines of Rust code.[^loc] It has caught a large number of [regressions]
5+
in the past and was subsequently included in CI.
6+
7+
## Building Fuchsia in CI
8+
9+
Fuchsia builds as part of the suite of bors tests that run before a pull request
10+
is merged.
11+
12+
If you are worried that a pull request might break the Fuchsia builder and want
13+
to test it out before submitting it to the bors queue, simply add this line to
14+
your PR description:
15+
16+
> try-job: x86_64-gnu-integration
17+
18+
Then when you `@bors try` it will pick the job that builds Fuchsia.
19+
20+
## Building Fuchsia locally
21+
22+
Because Fuchsia uses languages other than Rust, it does not use Cargo as a build
23+
system. It also requires the toolchain build to be configured in a [certain
24+
way][build-toolchain].
25+
26+
The recommended way to build Fuchsia is to use the Docker scripts that check out
27+
and run a Fuchsia build for you. If you've run Docker tests before, you can
28+
simply run this command from your Rust checkout to download and build Fuchsia
29+
using your local Rust toolchain.
30+
31+
```
32+
src/ci/docker/run.sh x86_64-gnu-integration
33+
```
34+
35+
See the [Testing with Docker](docker.md) chapter for more details on how to run
36+
and debug jobs with Docker.
37+
38+
Note that a Fuchsia checkout is *large* – as of this writing, a checkout and
39+
build takes 46G of space – and as you might imagine, it takes awhile to
40+
complete.
41+
42+
### Modifying the Fuchsia checkout
43+
44+
The main reason you would want to build Fuchsia locally is because you need to
45+
investigate a regression. After running a Docker build, you'll find the Fuchsia
46+
checkout inside the `obj/fuchsia` directory of your Rust checkout. If you
47+
modify the `KEEP_CHECKOUT` line in the [build-fuchsia.sh] script to
48+
`KEEP_CHECKOUT=1`, you can change the checkout as needed and rerun the build
49+
command above. This will reuse all the build results from before.
50+
51+
You can find more options to customize the Fuchsia checkout in the
52+
[build-fuchsia.sh] script.
53+
54+
### Customizing the Fuchsia build
55+
56+
You can find more info about the options used to build Fuchsia in Rust CI in the
57+
[build_fuchsia_from_rust_ci.sh] script invoked by [build-fuchsia.sh].
58+
59+
The Fuchsia build system uses [GN], a metabuild system that generates [Ninja]
60+
files and then hands off the work of running the build to Ninja.
61+
62+
Fuchsia developers use `fx` to run builds and perform other development tasks.
63+
This tool is located in `.jiri_root/bin` of the Fuchsia checkout; you may need
64+
to add this to your `$PATH` for some workflows.
65+
66+
There are a few `fx` subcommands that are relevant, including:
67+
68+
* `fx set` accepts build arguments, writes them to `out/default/args.gn`, and runs GN.
69+
* `fx build` builds the Fuchsia project using Ninja. It will automatically pick
70+
up changes to build arguments and rerun GN. By default it builds everything,
71+
but it also accepts target paths to build specific targets (see below).
72+
* `fx clippy` runs Clippy on specific Rust targets (or all of them). We use this
73+
in the Rust CI build to avoid running codegen on most Rust targets. Underneath
74+
it invokes Ninja, just like `fx build`. The clippy results are saved in json
75+
files inside the build output directory before being printed.
76+
77+
#### Target paths
78+
79+
GN uses paths like the following to identify build targets:
80+
81+
```
82+
//src/starnix/kernel:starnix_core
83+
```
84+
85+
The initial `//` means the root of the checkout, and the remaining slashes are
86+
directory names. The string after `:` is the _target name_ of a target defined
87+
in the `BUILD.gn` file of that directory.
88+
89+
The target name can be omitted if it is the same as the directory name. In other
90+
words, `//src/starnix/kernel` is the same as `//src/starnix/kernel:kernel`.
91+
92+
These target paths are used inside `BUILD.gn` files to reference dependencies,
93+
and can also be used in `fx build`.
94+
95+
#### Modifying compiler flags
96+
97+
You can put custom compiler flags inside a GN `config` that is added to a target.
98+
As a simple example:
99+
100+
```
101+
config("everybody_loops") {
102+
rustflags = [ "-Zeverybody-loops" ]
103+
}
104+
105+
rustc_binary("example") {
106+
crate_root = "src/bin.rs"
107+
# ...existing keys here...
108+
configs += [ ":everybody_loops" ]
109+
}
110+
```
111+
112+
This will add the flag `-Zeverybody-loops` to rustc when building the `example`
113+
target. Note that you can also use [`public_configs`] for a config to be added
114+
to every target that depends on that target.
115+
116+
If you want to add a flag to every Rust target in the build, you can add
117+
rustflags to the [`//build/config:compiler`] config or to the OS-specific
118+
configs referenced in that file. Note that `cflags` and `ldflags` are ignored on
119+
Rust targets.
120+
121+
#### Running ninja and rustc commands directly
122+
123+
Going down one layer, `fx build` invokes `ninja`, which in turn eventually
124+
invokes `rustc`. All build actions are run inside the out directory, which is
125+
usually `out/default` inside the Fuchsia checkout.
126+
127+
You can get ninja to print the actual command it invokes by forcing that command
128+
to fail, e.g. by adding a syntax error to one of the source files of the target.
129+
Once you have the command, you can run it from inside the output directory.
130+
131+
After changing the toolchain itself, the build setting `rustc_version_string` in
132+
`out/default/args.gn` needs to be changed so that `fx build` or `ninja` will
133+
rebuild all the Rust targets. This can be done in a text editor and the contents
134+
of the string do not matter, as long as it changes from one build to the next.
135+
[build_fuchsia_from_rust_ci.sh] does this for you by hashing the toolchain
136+
directory.
137+
138+
The Fuchsia website has more detailed documentation of the [build system].
139+
140+
#### Other tips and tricks
141+
142+
When using `build_fuchsia_from_rust_ci.sh` you can comment out the `fx set`
143+
command after the initial run so it won't rerun GN each time. If you do this you
144+
can also comment out the version_string line to save a couple seconds.
145+
146+
`export NINJA_PERSISTENT_MODE=1` to get faster ninja startup times after the
147+
initial build.
148+
149+
## Fuchsia target support
150+
151+
To learn more about Fuchsia target support, see the Fuchsia chapter in [the
152+
rustc book][platform-support].
153+
154+
[regressions]: https://gist.github.com/tmandry/7103eba4bd6a6fb0c439b5a90ae355fa
155+
[build-toolchain]: https://fuchsia.dev/fuchsia-src/development/build/rust_toolchain
156+
[build-fuchsia.sh]: https://github.com/rust-lang/rust/blob/99f77a2eda555b50b518f74823ab636a20efb87f/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh
157+
[build_fuchsia_from_rust_ci.sh]: https://cs.opensource.google/fuchsia/fuchsia/+/main:scripts/rust/build_fuchsia_from_rust_ci.sh?q=build_fuchsia_from_rust_ci&ss=fuchsia
158+
[platform-support]: https://doc.rust-lang.org/nightly/rustc/platform-support/fuchsia.html
159+
[GN]: https://gn.googlesource.com/gn/+/main#gn
160+
[Ninja]: https://ninja-build.org/
161+
[`public_configs`]: https://gn.googlesource.com/gn/+/main/docs/reference.md#var_public_configs
162+
[`//build/config:compiler`]: https://cs.opensource.google/fuchsia/fuchsia/+/main:build/config/BUILD.gn;l=121;drc=c26c473bef93b33117ae417893118907a026fec7
163+
[build system]: https://fuchsia.dev/fuchsia-src/development/build/build_system
164+
165+
[^loc]: As of June 2024, Fuchsia had about 2 million lines of first-party Rust code
166+
and a roughly equal amount of third-party code, as counted by tokei (excluding
167+
comments and blanks).

src/tests/integration.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Integration testing
2+
3+
Rust tests integration with real-world code to catch regressions and make
4+
informed decisions about the evolution of the language.
5+
6+
## Testing methods
7+
8+
### Crater
9+
10+
Crater is a tool which runs tests on many thousands of public projects. This
11+
tool has its own separate infrastructure for running, and is not run as part of
12+
CI. See the [Crater chapter](crater.md) for more details.
13+
14+
### Cargo test
15+
16+
`cargotest` is a small tool which runs `cargo test` on a few sample projects
17+
(such as `servo`, `ripgrep`, `tokei`, etc.).
18+
This runs as part of CI and ensures there aren't any significant regressions.
19+
20+
> Example: `./x test src/tools/cargotest`
21+
22+
### Integration builders
23+
24+
Integration jobs build large open-source Rust projects that are used as
25+
regression tests in CI. Our integration jobs build the following projects:
26+
27+
- [Fuchsia](fuchsia.md)
28+
- Linux kernel
29+
30+
## A note about terminology
31+
32+
The term "integration testing" can be used to mean many things. Many of the
33+
compiletest tests within the Rust repo could be justifiably called integration
34+
tests, because they test the integration of many parts of the compiler, or test
35+
the integration of the compiler with other external tools. Calling all of them
36+
integration tests would not be very helpful, especially since those kinds of
37+
tests already have their own specialized names.
38+
39+
We use the term "integration" here to mean integrating the Rust compiler and
40+
toolchain with the ecosystem of Rust projects that depend on it. This is partly
41+
for lack of a better term, but it also reflects a difference in testing approach
42+
from other projects and the comparative advantage it implies.
43+
44+
The Rust compiler is part of the ecosystem, and the ecosystem is in many cases
45+
part of Rust, both in terms of libraries it uses and in terms of the efforts of many
46+
contributors who come to "scratch their own itch". Finally, because Rust has the
47+
ability to do integration testing at such a broad scale, it shortens development
48+
cycles by finding defects earlier.
49+

src/tests/intro.md

+5-12
Original file line numberDiff line numberDiff line change
@@ -132,19 +132,12 @@ More information can be found in the [toolstate documentation].
132132
[toolstate documentation]: https://forge.rust-lang.org/infra/toolstate.html
133133
[toolstate website]: https://rust-lang-nursery.github.io/rust-toolstate/
134134

135-
### Cargo test
135+
### Integration testing
136136

137-
`cargotest` is a small tool which runs `cargo test` on a few sample projects
138-
(such as `servo`, `ripgrep`, `tokei`, etc.).
139-
This ensures there aren't any significant regressions.
140-
141-
> Example: `./x test src/tools/cargotest`
142-
143-
### Crater
144-
145-
Crater is a tool which runs tests on many thousands of public projects.
146-
This tool has its own separate infrastructure for running.
147-
See the [Crater chapter](crater.md) for more details.
137+
Rust tests integration with real-world code to catch regressions and make
138+
informed decisions about the evolution of the language. There are several kinds
139+
of integration tests, including Crater. See the [Integration testing
140+
chapter](integration.md) for more details.
148141

149142
### Performance testing
150143

0 commit comments

Comments
 (0)