Skip to content

Commit 0fcb86b

Browse files
author
David Koloski
committed
Add Fuchsia platform support documentation
1 parent 14dbfeb commit 0fcb86b

File tree

2 files changed

+296
-0
lines changed

2 files changed

+296
-0
lines changed

src/doc/rustc/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
- [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md)
2222
- [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
2323
- [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
24+
- [\*-fuchsia](platform-support/fuchsia.md)
2425
- [\*-kmc-solid_\*](platform-support/kmc-solid.md)
2526
- [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
2627
- [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
# `aarch64-fuchsia` and `x86_64-fuchsia`
2+
3+
**Tier: 2**
4+
5+
[Fuchsia] is a modern open source operating system that's simple, secure,
6+
updatable, and performant.
7+
8+
[Fuchsia]: https://fuchsia.dev/
9+
10+
## Target maintainers
11+
12+
The [Fuchsia team]:
13+
14+
[Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json
15+
16+
- Tyler Mandry ([@tmandry](https://github.com/tmandry))
17+
- Dan Johnson ([@computerdruid](https://github.com/computerdruid))
18+
- David Koloski ([@djkoloski](https://github.com/djkoloski))
19+
- Andrew Pollack ([@andrewpollack](https://github.com/andrewpollack))
20+
- Joseph Ryan ([@P1n3appl3](https://github.com/P1n3appl3))
21+
22+
As the team evolves over time, the specific members listed here may differ from
23+
the members reported by the API. The API should be considered to be
24+
authoritative if this occurs. Instead of pinging individual members, use
25+
`@rustbot ping fuchsia` to contact the team on GitHub.
26+
27+
## Requirements
28+
29+
This target is cross-compiled from a host environment. Development may be done
30+
from the [source tree] or using the Fuchsia SDK.
31+
32+
[source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build
33+
34+
Fuchsia targets support std and follow the `sysv64` calling convention on
35+
x86_64. Fuchsia binaries use the ELF file format.
36+
37+
## Building the target
38+
39+
Before building Rust for Fuchsia, you'll need a clang toolchain that supports
40+
Fuchsia as well. A recent version (14+) of clang should be sufficient to compile
41+
Rust for Fuchsia.
42+
43+
You'll also need a recent copy of the [Fuchsia SDK], which provides the tools
44+
and binaries required to build and link programs for Fuchsia.
45+
46+
[Fuchsia SDK]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core
47+
48+
x86-64 and AArch64 Fuchsia targets can be enabled using the following
49+
configuration.
50+
51+
In `config.toml`, add:
52+
53+
```toml
54+
[build]
55+
target = ["<host_platform>", "aarch64-fuchsia", "x86_64-fuchsia"]
56+
57+
[target.x86_64-fuchsia]
58+
llvm-libunwind = "in-tree"
59+
60+
[target.aarch64-fuchsia]
61+
llvm-libunwind = "in-tree"
62+
```
63+
64+
Additionally, the following environment variables must be configured (for
65+
example, using a script like `config-env.sh`):
66+
67+
```sh
68+
# Configure this environment variable to be the path to the downloaded SDK
69+
export SDK_PATH="<SDK path goes here>"
70+
71+
export CFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include"
72+
export CXXFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include"
73+
export LDFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -L${SDK_PATH}/arch/arm64/lib"
74+
export CARGO_TARGET_AARCH64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/arm64/sysroot -Lnative=${SDK_PATH}/arch/arm64/sysroot/lib -Lnative=${SDK_PATH}/arch/arm64/lib"
75+
export CFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include"
76+
export CXXFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include"
77+
export LDFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -L${SDK_PATH}/arch/x64/lib"
78+
export CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/x64/sysroot -Lnative=${SDK_PATH}/arch/x64/sysroot/lib -Lnative=${SDK_PATH}/arch/x64/lib"
79+
```
80+
81+
These can be run together in a shell environment by executing
82+
`(source config-env.sh && ./x.py install)`.
83+
84+
## Building Rust programs
85+
86+
After compiling Rust binaries, you'll need to build a component, package it, and
87+
serve it to a Fuchsia device or emulator. All of this can be done using the
88+
Fuchsia SDK.
89+
90+
As an example, we'll compile and run this simple program on a Fuchsia emulator:
91+
92+
**`hello_fuchsia.rs`**
93+
```rust
94+
fn main() {
95+
println!("Hello Fuchsia!");
96+
}
97+
98+
#[test]
99+
fn it_works() {
100+
assert_eq!(2 + 2, 4);
101+
}
102+
```
103+
104+
Create a new file named `hello_fuchsia.rs` and fill out its contents with that
105+
code.
106+
107+
### Create a package
108+
109+
On Fuchsia, a package is the unit of distribution for software. We'll need to
110+
create a new package directory where we will place files like our finished
111+
binary and any data it may need. The working directory will have this layout:
112+
113+
```txt
114+
hello_fuchsia.rs
115+
hello_fuchsia.cml
116+
package
117+
┣━ bin
118+
┃ ┗━ hello_fuchsia
119+
┣━ meta
120+
┃ ┣━ package
121+
┃ ┗━ hello_fuchsia.cm
122+
┗━ hello_fuchsia.manifest
123+
```
124+
125+
Make the `package`, `package/bin`, and `package/meta` directories and create the
126+
following files inside:
127+
128+
**`package/meta/package`**
129+
```json
130+
{"name":"hello_fuchsia","version":0}
131+
```
132+
133+
The `package` file describes our package's name and version number. Every
134+
package must contain one.
135+
136+
**`package/hello_fuchsia.manifest`**
137+
```txt
138+
bin/hello_fuchsia=package/bin/hello_fuchsia
139+
lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
140+
lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
141+
meta/package=package/meta/package
142+
meta/hello_fuchsia.cm=package/meta/hello_fuchsia.cm
143+
```
144+
145+
*Note: Relative manifest paths are resolved starting from the working directory
146+
of `pm`. Make sure to fill out `<SDK_PATH>` with the path to the downloaded
147+
SDK.*
148+
149+
The `.manifest` file will be used to describe the contents of the package by
150+
relating their location when installed to their location on the file system. You
151+
can use this to make a package pull files from other places, but for this
152+
example we'll just be placing everything in the `package` directory.
153+
154+
### Compiling a binary
155+
156+
Using your freshly compiled `rustc`, you can compile a binary for Fuchsia using
157+
the following options:
158+
159+
* `--target x86_64-fuchsia`/`--target aarch64-fuchsia`: Targets the Fuchsia
160+
platform of your choice
161+
* `-Lnative ${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from
162+
the SDK
163+
* `-Lnative ${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia kernel
164+
libraries from the SDK
165+
166+
Putting it all together:
167+
168+
```sh
169+
# Configure these for the Fuchsia target of your choice
170+
TARGET_ARCH="<x86_64-fuchsia|aarch64-fuchsia>"
171+
ARCH="<x64|aarch64>"
172+
173+
rustc --target ${TARGET_ARCH} -Lnative=${SDK_PATH}/arch/${ARCH}/lib -Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib -o package/bin/hello_fuchsia hello_fuchsia.rs
174+
```
175+
176+
### Bulding a component
177+
178+
On Fuchsia, components require a component manifest written in Fuchia's markup
179+
language called CML. The Fuchsia devsite contains an [overview of CML] and a
180+
[reference for the file format]. Here's a basic one that can run our single binary:
181+
182+
[overview of CML]: https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manifests
183+
[reference for the file format]: https://fuchsia.dev/reference/cml
184+
185+
**`hello_fuchsia.cml`**
186+
```txt
187+
{
188+
include: [ "syslog/client.shard.cml" ],
189+
program: {
190+
runner: "elf",
191+
binary: "bin/hello_fuchsia",
192+
},
193+
}
194+
```
195+
196+
Now we can compile that CML into a component manifest:
197+
198+
```sh
199+
${SDK_PATH}/tools/${ARCH}/cmc compile hello_fuchsia.cml --includepath ${SDK_PATH}/pkg -o package/meta/hello_fuchsia.cm
200+
```
201+
202+
`--includepath` tells the compiler where to look for `include`s from our CML.
203+
In our case, we're only using `syslog/client.shard.cml`.
204+
205+
### Building and publishing a package
206+
207+
Next, we'll build our package as defined by our manifest:
208+
209+
```sh
210+
${SDK_PATH}/tools/${ARCH}/pm -o hello_fuchsia -m package/hello_fuchsia.manifest build -output-package-manifest hello_fuchsia_manifest
211+
```
212+
213+
This will produce `hello_fuchsia_manifest` which is a package manifest we can
214+
publish directly to a repository. We can set up that repository with:
215+
216+
```sh
217+
${SDK_PATH}/tools/${ARCH}/pm newrepo -repo repo
218+
```
219+
220+
And then publish our new package to that repository with:
221+
222+
```sh
223+
${SDK_PATH}/tools/${ARCH}/pm publish -repo repo -lp -f <(echo "hello_fuchsia_manifest")
224+
```
225+
226+
Then we can add it to `ffx`'s package server as `hello-fuchsia` using:
227+
228+
```sh
229+
${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm repo -r hello-fuchsia
230+
```
231+
232+
### Starting the emulator
233+
234+
Start a Fuchsia emulator in a new terminal using:
235+
236+
```sh
237+
${SDK_PATH}/tools/${ARCH}/ffx product-bundle get workstation_eng.qemu-${ARCH}
238+
${SDK_PATH}/tools/${ARCH}/ffx emu start workstation_eng.qemu-${ARCH} --headless
239+
```
240+
241+
Then, once the emulator has been started:
242+
243+
```sh
244+
${SDK_PATH}/tools/${ARCH}/ffx target repository register
245+
```
246+
247+
And watch the logs from the emulator in a separate terminal:
248+
249+
```sh
250+
${SDK_PATH}/tools/${ARCH}/ffx log --since now
251+
```
252+
253+
Finally, run the component:
254+
255+
```sh
256+
${SDK_PATH}/tools/${ARCH}/ffx component run fuchsia-pkg://hello-fuchsia/hello_fuchsia#meta/hello_fuchsia.cm
257+
```
258+
259+
On reruns of the component, the `--recreate` argument may also need to be
260+
passed.
261+
262+
## Testing
263+
264+
### Running unit tests
265+
266+
Tests can be run in the same way as a regular binary, simply by passing `--test`
267+
to the `rustc` invocation and then repackaging and rerunning. The test harness
268+
will run the applicable unit tests.
269+
270+
Often when testing, you may want to pass additional command line arguments to
271+
your binary. Additional arguments can be set in the component manifest:
272+
273+
**`hello_fuchsia.cml`**
274+
```txt
275+
{
276+
include: [ "syslog/client.shard.cml" ],
277+
program: {
278+
runner: "elf",
279+
binary: "bin/hello_fuchsia",
280+
args: ["it_works"],
281+
},
282+
}
283+
```
284+
285+
This will pass the argument `it_works` to the binary, filtering the tests to
286+
only those tests that match the pattern. There are many more configuration
287+
options available in CML including environment variables. More documentation is
288+
available on the [Fuchsia devsite](https://fuchsia.dev/reference/cml).
289+
290+
### Running the compiler test suite
291+
292+
Running the Rust test suite on Fuchsia is [not currently supported], but work is
293+
underway to enable it.
294+
295+
[not currently supported]: https://fxbug.dev/105393

0 commit comments

Comments
 (0)