]> git.lizzy.rs Git - rust.git/blob - src/doc/rustc/src/platform-support/fuchsia.md
Rollup merge of #98801 - joshtriplett:file-create-new, r=thomcc
[rust.git] / src / doc / rustc / src / platform-support / fuchsia.md
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
58 Additionally, the following environment variables must be configured (for
59 example, using a script like `config-env.sh`):
60
61 ```sh
62 # Configure this environment variable to be the path to the downloaded SDK
63 export SDK_PATH="<SDK path goes here>"
64
65 export CFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include"
66 export CXXFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include"
67 export LDFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -L${SDK_PATH}/arch/arm64/lib"
68 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"
69 export CFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include"
70 export CXXFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include"
71 export LDFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -L${SDK_PATH}/arch/x64/lib"
72 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"
73 ```
74
75 These can be run together in a shell environment by executing
76 `(source config-env.sh && ./x.py install)`.
77
78 ## Building Rust programs
79
80 After compiling Rust binaries, you'll need to build a component, package it, and
81 serve it to a Fuchsia device or emulator. All of this can be done using the
82 Fuchsia SDK.
83
84 As an example, we'll compile and run this simple program on a Fuchsia emulator:
85
86 **`hello_fuchsia.rs`**
87 ```rust
88 fn main() {
89     println!("Hello Fuchsia!");
90 }
91
92 #[test]
93 fn it_works() {
94     assert_eq!(2 + 2, 4);
95 }
96 ```
97
98 Create a new file named `hello_fuchsia.rs` and fill out its contents with that
99 code.
100
101 ### Create a package
102
103 On Fuchsia, a package is the unit of distribution for software. We'll need to
104 create a new package directory where we will place files like our finished
105 binary and any data it may need. The working directory will have this layout:
106
107 ```txt
108 hello_fuchsia.rs
109 hello_fuchsia.cml
110 package
111 ┣━ bin
112 ┃  ┗━ hello_fuchsia
113 ┣━ meta
114 ┃  ┣━ package
115 ┃  ┗━ hello_fuchsia.cm
116 ┗━ hello_fuchsia.manifest
117 ```
118
119 Make the `package`, `package/bin`, and `package/meta` directories and create the
120 following files inside:
121
122 **`package/meta/package`**
123 ```json
124 {
125   "name": "hello_fuchsia",
126   "version": "0"
127 }
128 ```
129
130 The `package` file describes our package's name and version number. Every
131 package must contain one.
132
133 **`package/hello_fuchsia.manifest`**
134 ```txt
135 bin/hello_fuchsia=package/bin/hello_fuchsia
136 lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
137 lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
138 meta/package=package/meta/package
139 meta/hello_fuchsia.cm=package/meta/hello_fuchsia.cm
140 ```
141
142 *Note: Relative manifest paths are resolved starting from the working directory
143 of `pm`. Make sure to fill out `<SDK_PATH>` with the path to the downloaded
144 SDK.*
145
146 The `.manifest` file will be used to describe the contents of the package by
147 relating their location when installed to their location on the file system. You
148 can use this to make a package pull files from other places, but for this
149 example we'll just be placing everything in the `package` directory.
150
151 ### Compiling a binary
152
153 Using your freshly compiled `rustc`, you can compile a binary for Fuchsia using
154 the following options:
155
156 * `--target x86_64-fuchsia`/`--target aarch64-fuchsia`: Targets the Fuchsia
157   platform of your choice
158 * `-Lnative ${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from
159   the SDK
160 * `-Lnative ${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia kernel
161   libraries from the SDK
162
163 Putting it all together:
164
165 ```sh
166 # Configure these for the Fuchsia target of your choice
167 TARGET_ARCH="<x86_64-fuchsia|aarch64-fuchsia>"
168 ARCH="<x64|aarch64>"
169
170 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
171 ```
172
173 ### Bulding a component
174
175 On Fuchsia, components require a component manifest written in Fuchia's markup
176 language called CML. The Fuchsia devsite contains an [overview of CML] and a
177 [reference for the file format]. Here's a basic one that can run our single binary:
178
179 [overview of CML]: https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manifests
180 [reference for the file format]: https://fuchsia.dev/reference/cml
181
182 **`hello_fuchsia.cml`**
183 ```txt
184 {
185     include: [ "syslog/client.shard.cml" ],
186     program: {
187         runner: "elf",
188         binary: "bin/hello_fuchsia",
189     },
190 }
191 ```
192
193 Now we can compile that CML into a component manifest:
194
195 ```sh
196 ${SDK_PATH}/tools/${ARCH}/cmc compile hello_fuchsia.cml --includepath ${SDK_PATH}/pkg -o package/meta/hello_fuchsia.cm
197 ```
198
199 `--includepath` tells the compiler where to look for `include`s from our CML.
200 In our case, we're only using `syslog/client.shard.cml`.
201
202 ### Building and publishing a package
203
204 Next, we'll build our package as defined by our manifest:
205
206 ```sh
207 ${SDK_PATH}/tools/${ARCH}/pm -o hello_fuchsia -m package/hello_fuchsia.manifest build -output-package-manifest hello_fuchsia_manifest
208 ```
209
210 This will produce `hello_fuchsia_manifest` which is a package manifest we can
211 publish directly to a repository. We can set up that repository with:
212
213 ```sh
214 ${SDK_PATH}/tools/${ARCH}/pm newrepo -repo repo
215 ```
216
217 And then publish our new package to that repository with:
218
219 ```sh
220 ${SDK_PATH}/tools/${ARCH}/pm publish -repo repo -lp -f <(echo "hello_fuchsia_manifest")
221 ```
222
223 Then we can add it to `ffx`'s package server as `hello-fuchsia` using:
224
225 ```sh
226 ${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm repo -r hello-fuchsia
227 ```
228
229 ### Starting the emulator
230
231 Start a Fuchsia emulator in a new terminal using:
232
233 ```sh
234 ${SDK_PATH}/tools/${ARCH}/ffx product-bundle get workstation_eng.qemu-${ARCH}
235 ${SDK_PATH}/tools/${ARCH}/ffx emu start workstation_eng.qemu-${ARCH} --headless
236 ```
237
238 Once the emulator is running, start a package repository server to serve our
239 package to the emulator:
240
241 ```sh
242 ${SDK_PATH}/tools/${ARCH}/ffx repository server start
243 ```
244
245 Once the repository server is up and running, register our repository:
246
247 ```sh
248 ${SDK_PATH}/tools/${ARCH}/ffx target repository register --repository hello-fuchsia
249 ```
250
251 And watch the logs from the emulator in a separate terminal:
252
253 ```sh
254 ${SDK_PATH}/tools/${ARCH}/ffx log --since now
255 ```
256
257 Finally, run the component:
258
259 ```sh
260 ${SDK_PATH}/tools/${ARCH}/ffx component run fuchsia-pkg://hello-fuchsia/hello_fuchsia#meta/hello_fuchsia.cm
261 ```
262
263 On reruns of the component, the `--recreate` argument may also need to be
264 passed.
265
266 ```sh
267 ${SDK_PATH}/tools/${ARCH}/ffx component run --recreate fuchsia-pkg://hello-fuchsia/hello_fuchsia#meta/hello_fuchsia.cm
268 ```
269
270 ## Testing
271
272 ### Running unit tests
273
274 Tests can be run in the same way as a regular binary, simply by passing `--test`
275 to the `rustc` invocation and then repackaging and rerunning. The test harness
276 will run the applicable unit tests.
277
278 Often when testing, you may want to pass additional command line arguments to
279 your binary. Additional arguments can be set in the component manifest:
280
281 **`hello_fuchsia.cml`**
282 ```txt
283 {
284     include: [ "syslog/client.shard.cml" ],
285     program: {
286         runner: "elf",
287         binary: "bin/hello_fuchsia",
288         args: ["it_works"],
289     },
290 }
291 ```
292
293 This will pass the argument `it_works` to the binary, filtering the tests to
294 only those tests that match the pattern. There are many more configuration
295 options available in CML including environment variables. More documentation is
296 available on the [Fuchsia devsite](https://fuchsia.dev/reference/cml).
297
298 ### Running the compiler test suite
299
300 Running the Rust test suite on Fuchsia is [not currently supported], but work is
301 underway to enable it.
302
303 [not currently supported]: https://fxbug.dev/105393