]> git.proxmox.com Git - rustc.git/blame - src/doc/rustc/src/platform-support/fuchsia.md
bump version to 1.81.0+dfsg1-2~bpo12+pve1
[rustc.git] / src / doc / rustc / src / platform-support / fuchsia.md
CommitLineData
9c376795 1# `aarch64-unknown-fuchsia` and `x86_64-unknown-fuchsia`
064997fb
FG
2
3**Tier: 2**
4
5[Fuchsia] is a modern open source operating system that's simple, secure,
6updatable, and performant.
7
064997fb
FG
8## Target maintainers
9
10The [Fuchsia team]:
11
064997fb 12- Tyler Mandry ([@tmandry](https://github.com/tmandry))
064997fb 13- David Koloski ([@djkoloski](https://github.com/djkoloski))
31ef2f64
FG
14- Julia Ryan ([@P1n3appl3](https://github.com/P1n3appl3))
15- Erick Tryzelaar ([@erickt](https://github.com/erickt))
064997fb
FG
16
17As the team evolves over time, the specific members listed here may differ from
18the members reported by the API. The API should be considered to be
19authoritative if this occurs. Instead of pinging individual members, use
20`@rustbot ping fuchsia` to contact the team on GitHub.
21
f2b60f7d
FG
22## Table of contents
23
241. [Requirements](#requirements)
251. [Walkthrough structure](#walkthrough-structure)
261. [Compiling a Rust binary targeting Fuchsia](#compiling-a-rust-binary-targeting-fuchsia)
27 1. [Targeting Fuchsia with rustup and cargo](#targeting-fuchsia-with-rustup-and-cargo)
28 1. [Targeting Fuchsia with a compiler built from source](#targeting-fuchsia-with-a-compiler-built-from-source)
291. [Creating a Fuchsia package](#creating-a-fuchsia-package)
30 1. [Creating a Fuchsia component](#creating-a-fuchsia-component)
31 1. [Building a Fuchsia package](#building-a-fuchsia-package)
321. [Publishing a Fuchsia package](#publishing-a-fuchsia-package)
33 1. [Creating a Fuchsia package repository](#creating-a-fuchsia-package-repository)
34 1. [Publishing Fuchsia package to repository](#publishing-fuchsia-package-to-repository)
351. [Running a Fuchsia component on an emulator](#running-a-fuchsia-component-on-an-emulator)
36 1. [Starting the Fuchsia emulator](#starting-the-fuchsia-emulator)
37 1. [Watching emulator logs](#watching-emulator-logs)
38 1. [Serving a Fuchsia package](#serving-a-fuchsia-package)
39 1. [Running a Fuchsia component](#running-a-fuchsia-component)
401. [`.gitignore` extensions](#gitignore-extensions)
411. [Testing](#testing)
42 1. [Running unit tests](#running-unit-tests)
43 1. [Running the compiler test suite](#running-the-compiler-test-suite)
441. [Debugging](#debugging)
45 1. [`zxdb`](#zxdb)
46 1. [Attaching `zxdb`](#attaching-zxdb)
47 1. [Using `zxdb`](#using-zxdb)
48 1. [Displaying source code in `zxdb`](#displaying-source-code-in-zxdb)
49
064997fb
FG
50## Requirements
51
f2b60f7d
FG
52This target is cross-compiled from a host environment. You will need a recent
53copy of the [Fuchsia SDK], which provides the tools, libraries, and binaries
54required to build and link programs for Fuchsia.
064997fb 55
f2b60f7d 56Development may also be done from the [source tree].
064997fb 57
f2b60f7d 58Fuchsia targets support `std` and follow the `sysv64` calling convention on
064997fb
FG
59x86_64. Fuchsia binaries use the ELF file format.
60
f2b60f7d
FG
61## Walkthrough structure
62
63This walkthrough will cover:
64
651. Compiling a Rust binary targeting Fuchsia.
661. Building a Fuchsia package.
671. Publishing and running a Fuchsia package to a Fuchsia emulator.
68
9c376795 69For the purposes of this walkthrough, we will only target `x86_64-unknown-fuchsia`.
f2b60f7d
FG
70
71## Compiling a Rust binary targeting Fuchsia
72
73Today, there are two main ways to build a Rust binary targeting Fuchsia
74using the Fuchsia SDK:
751. Allow [rustup] to handle the installation of Fuchsia targets for you.
761. Build a toolchain locally that can target Fuchsia.
77
78### Targeting Fuchsia with rustup and cargo
79
80The easiest way to build a Rust binary targeting Fuchsia is by allowing [rustup]
81to handle the installation of Fuchsia targets for you. This can be done by issuing
82the following commands:
83
84```sh
9c376795
FG
85rustup target add x86_64-unknown-fuchsia
86rustup target add aarch64-unknown-fuchsia
f2b60f7d
FG
87```
88
89After installing our Fuchsia targets, we can now compile a Rust binary that targets
90Fuchsia.
91
9c376795 92To create our Rust project, we can use [`cargo`][cargo] as follows:
f2b60f7d
FG
93
94**From base working directory**
95```sh
96cargo new hello_fuchsia
97```
98
99The rest of this walkthrough will take place from `hello_fuchsia`, so we can
100change into that directory now:
101
102```sh
103cd hello_fuchsia
104```
105
106*Note: From this point onwards, all commands will be issued from the `hello_fuchsia/`
107directory, and all `hello_fuchsia/` prefixes will be removed from references for sake of brevity.*
108
109We can edit our `src/main.rs` to include a test as follows:
110
111**`src/main.rs`**
112```rust
113fn main() {
114 println!("Hello Fuchsia!");
115}
116
117#[test]
118fn it_works() {
119 assert_eq!(2 + 2, 4);
120}
121```
122
123In addition to the standard workspace created, we will want to create a
124`.cargo/config.toml` file to link necessary libraries
125during compilation:
126
127**`.cargo/config.toml`**
128```txt
9c376795 129[target.x86_64-unknown-fuchsia]
f2b60f7d
FG
130
131rustflags = [
132 "-Lnative=<SDK_PATH>/arch/x64/lib",
133 "-Lnative=<SDK_PATH>/arch/x64/sysroot/lib"
134]
135```
136
137*Note: Make sure to fill out `<SDK_PATH>` with the path to the downloaded [Fuchsia SDK].*
138
139These options configure the following:
140
141* `-Lnative=${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from
142 the SDK
143* `-Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia sysroot
144 libraries from the SDK
145
146In total, our new project will look like:
147
148**Current directory structure**
149```txt
150hello_fuchsia/
151┣━ src/
152┃ ┗━ main.rs
153┣━ Cargo.toml
154┗━ .cargo/
155 ┗━ config.toml
156```
157
158Finally, we can build our rust binary as:
159
160```sh
9c376795 161cargo build --target x86_64-unknown-fuchsia
f2b60f7d
FG
162```
163
9c376795 164Now we have a Rust binary at `target/x86_64-unknown-fuchsia/debug/hello_fuchsia`,
f2b60f7d
FG
165targeting our desired Fuchsia target.
166
167**Current directory structure**
168```txt
169hello_fuchsia/
170┣━ src/
171┃ ┗━ main.rs
172┣━ target/
9c376795 173┃ ┗━ x86_64-unknown-fuchsia/
f2b60f7d
FG
174┃ ┗━ debug/
175┃ ┗━ hello_fuchsia
176┣━ Cargo.toml
177┗━ .cargo/
178 ┗━ config.toml
179```
180
181### Targeting Fuchsia with a compiler built from source
182
183An alternative to the first workflow is to target Fuchsia by using
184`rustc` built from source.
064997fb
FG
185
186Before building Rust for Fuchsia, you'll need a clang toolchain that supports
187Fuchsia as well. A recent version (14+) of clang should be sufficient to compile
188Rust for Fuchsia.
189
064997fb 190x86-64 and AArch64 Fuchsia targets can be enabled using the following
487cf647 191configuration in `config.toml`:
064997fb
FG
192
193```toml
194[build]
9c376795 195target = ["<host_platform>", "aarch64-unknown-fuchsia", "x86_64-unknown-fuchsia"]
487cf647
FG
196
197[rust]
198lld = true
199
9c376795
FG
200[llvm]
201download-ci-llvm = false
202
203[target.x86_64-unknown-fuchsia]
487cf647
FG
204cc = "clang"
205cxx = "clang++"
206
9c376795 207[target.aarch64-unknown-fuchsia]
487cf647
FG
208cc = "clang"
209cxx = "clang++"
210```
211
212Though not strictly required, you may also want to use `clang` for your host
213target as well:
214
215```toml
216[target.<host_platform>]
217cc = "clang"
218cxx = "clang++"
219```
220
221By default, the Rust compiler installs itself to `/usr/local` on most UNIX
222systems. You may want to install it to another location (e.g. a local `install`
223directory) by setting a custom prefix in `config.toml`:
224
225```toml
226[install]
227# Make sure to use the absolute path to your install directory
228prefix = "<RUST_SRC_PATH>/install"
064997fb
FG
229```
230
487cf647
FG
231Next, the following environment variables must be configured. For example, using
232a script we name `config-env.sh`:
064997fb
FG
233
234```sh
235# Configure this environment variable to be the path to the downloaded SDK
236export SDK_PATH="<SDK path goes here>"
237
9c376795
FG
238export CFLAGS_aarch64_unknown_fuchsia="--target=aarch64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include"
239export CXXFLAGS_aarch64_unknown_fuchsia="--target=aarch64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include"
240export LDFLAGS_aarch64_unknown_fuchsia="--target=aarch64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -L${SDK_PATH}/arch/arm64/lib"
241export CARGO_TARGET_AARCH64_UNKNOWN_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/arm64/sysroot -Lnative=${SDK_PATH}/arch/arm64/sysroot/lib -Lnative=${SDK_PATH}/arch/arm64/lib"
242export CFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include"
243export CXXFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include"
244export LDFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -L${SDK_PATH}/arch/x64/lib"
245export CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/x64/sysroot -Lnative=${SDK_PATH}/arch/x64/sysroot/lib -Lnative=${SDK_PATH}/arch/x64/lib"
064997fb
FG
246```
247
487cf647
FG
248Finally, the Rust compiler can be built and installed:
249
250```sh
251(source config-env.sh && ./x.py install)
252```
064997fb 253
f2b60f7d
FG
254Once `rustc` is installed, we can create a new working directory to work from,
255`hello_fuchsia` along with `hello_fuchsia/src`:
064997fb 256
f2b60f7d
FG
257```sh
258mkdir hello_fuchsia
259cd hello_fuchsia
260mkdir src
261```
262
263*Note: From this point onwards, all commands will be issued from the `hello_fuchsia/`
264directory, and all `hello_fuchsia/` prefixes will be removed from references for sake of brevity.*
064997fb 265
f2b60f7d 266There, we can create a new file named `src/hello_fuchsia.rs`:
064997fb 267
f2b60f7d 268**`src/hello_fuchsia.rs`**
064997fb
FG
269```rust
270fn main() {
271 println!("Hello Fuchsia!");
272}
273
274#[test]
275fn it_works() {
276 assert_eq!(2 + 2, 4);
277}
278```
279
f2b60f7d
FG
280**Current directory structure**
281```txt
282hello_fuchsia/
283┗━ src/
284 ┗━ hello_fuchsia.rs
285```
286
287Using your freshly installed `rustc`, you can compile a binary for Fuchsia using
288the following options:
289
9c376795 290* `--target x86_64-unknown-fuchsia`/`--target aarch64-unknown-fuchsia`: Targets the Fuchsia
f2b60f7d
FG
291 platform of your choice
292* `-Lnative ${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from
293 the SDK
294* `-Lnative ${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia sysroot
295 libraries from the SDK
064997fb 296
f2b60f7d 297Putting it all together:
064997fb 298
f2b60f7d
FG
299```sh
300# Configure these for the Fuchsia target of your choice
9c376795 301TARGET_ARCH="<x86_64-unknown-fuchsia|aarch64-unknown-fuchsia>"
f2b60f7d
FG
302ARCH="<x64|aarch64>"
303
304rustc \
305 --target ${TARGET_ARCH} \
306 -Lnative=${SDK_PATH}/arch/${ARCH}/lib \
307 -Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib \
308 --out-dir bin src/hello_fuchsia.rs
309```
310
311**Current directory structure**
312```txt
313hello_fuchsia/
314┣━ src/
315┃ ┗━ hello_fuchsia.rs
316┗━ bin/
317 ┗━ hello_fuchsia
318```
319
320## Creating a Fuchsia package
321
322Before moving on, double check your directory structure:
323
324**Current directory structure**
325```txt
326hello_fuchsia/
9c376795
FG
327┣━ src/ (if using rustc)
328┃ ┗━ hello_fuchsia.rs ...
329┣━ bin/ ...
330┃ ┗━ hello_fuchsia ...
331┣━ src/ (if using cargo)
332┃ ┗━ main.rs ...
333┗━ target/ ...
334 ┗━ x86_64-unknown-fuchsia/ ...
335 ┗━ debug/ ...
336 ┗━ hello_fuchsia ...
f2b60f7d
FG
337```
338
339With our Rust binary built, we can move to creating a Fuchsia package.
064997fb
FG
340On Fuchsia, a package is the unit of distribution for software. We'll need to
341create a new package directory where we will place files like our finished
f2b60f7d
FG
342binary and any data it may need.
343
344To start, make the `pkg`, and `pkg/meta` directories:
345
346```sh
347mkdir pkg
348mkdir pkg/meta
349```
064997fb 350
f2b60f7d 351**Current directory structure**
064997fb 352```txt
f2b60f7d
FG
353hello_fuchsia/
354┗━ pkg/
355 ┗━ meta/
064997fb
FG
356```
357
f2b60f7d 358Now, create the following files inside:
064997fb 359
f2b60f7d 360**`pkg/meta/package`**
064997fb 361```json
f2b60f7d
FG
362{
363 "name": "hello_fuchsia",
364 "version": "0"
365}
064997fb
FG
366```
367
368The `package` file describes our package's name and version number. Every
369package must contain one.
370
f2b60f7d
FG
371**`pkg/hello_fuchsia.manifest` if using cargo**
372```txt
9c376795 373bin/hello_fuchsia=target/x86_64-unknown-fuchsia/debug/hello_fuchsia
f2b60f7d
FG
374lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
375lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
376meta/package=pkg/meta/package
377meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm
378```
379
380**`pkg/hello_fuchsia.manifest` if using rustc**
064997fb 381```txt
f2b60f7d 382bin/hello_fuchsia=bin/hello_fuchsia
064997fb
FG
383lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
384lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
f2b60f7d
FG
385meta/package=pkg/meta/package
386meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm
064997fb
FG
387```
388
389*Note: Relative manifest paths are resolved starting from the working directory
31ef2f64 390of `ffx`. Make sure to fill out `<SDK_PATH>` with the path to the downloaded
064997fb
FG
391SDK.*
392
393The `.manifest` file will be used to describe the contents of the package by
f2b60f7d
FG
394relating their location when installed to their location on the file system. The
395`bin/hello_fuchsia=` entry will be different depending on how your Rust binary
396was built, so choose accordingly.
064997fb 397
f2b60f7d
FG
398**Current directory structure**
399```txt
400hello_fuchsia/
401┗━ pkg/
402 ┣━ meta/
403 ┃ ┗━ package
404 ┗━ hello_fuchsia.manifest
064997fb
FG
405```
406
f2b60f7d 407### Creating a Fuchsia component
064997fb 408
f2b60f7d 409On Fuchsia, components require a component manifest written in Fuchsia's markup
064997fb
FG
410language called CML. The Fuchsia devsite contains an [overview of CML] and a
411[reference for the file format]. Here's a basic one that can run our single binary:
412
f2b60f7d 413**`pkg/hello_fuchsia.cml`**
064997fb
FG
414```txt
415{
416 include: [ "syslog/client.shard.cml" ],
417 program: {
418 runner: "elf",
419 binary: "bin/hello_fuchsia",
420 },
421}
422```
423
f2b60f7d
FG
424**Current directory structure**
425```txt
426hello_fuchsia/
427┗━ pkg/
428 ┣━ meta/
429 ┃ ┗━ package
430 ┣━ hello_fuchsia.manifest
431 ┗━ hello_fuchsia.cml
432```
433
064997fb
FG
434Now we can compile that CML into a component manifest:
435
436```sh
f2b60f7d
FG
437${SDK_PATH}/tools/${ARCH}/cmc compile \
438 pkg/hello_fuchsia.cml \
439 --includepath ${SDK_PATH}/pkg \
440 -o pkg/meta/hello_fuchsia.cm
064997fb
FG
441```
442
f2b60f7d
FG
443*Note: `--includepath` tells the compiler where to look for `include`s from our CML.
444In our case, we're only using `syslog/client.shard.cml`.*
064997fb 445
f2b60f7d
FG
446**Current directory structure**
447```txt
448hello_fuchsia/
449┗━ pkg/
450 ┣━ meta/
451 ┃ ┣━ package
452 ┃ ┗━ hello_fuchsia.cm
453 ┣━ hello_fuchsia.manifest
454 ┗━ hello_fuchsia.cml
455```
064997fb 456
f2b60f7d
FG
457### Building a Fuchsia package
458
459Next, we'll build a package manifest as defined by our manifest:
064997fb
FG
460
461```sh
31ef2f64
FG
462${SDK_PATH}/tools/${ARCH}/ffx package build \
463 --api-level $(${SDK_PATH}/tools/${ARCH}/ffx --machine json version | jq .tool_version.api_level) \
464 --out pkg/hello_fuchsia_manifest \
465 pkg/hello_fuchsia.manifest
f2b60f7d
FG
466```
467
468This will produce `pkg/hello_fuchsia_manifest/` which is a package manifest we can
469publish directly to a repository.
470
471**Current directory structure**
472```txt
473hello_fuchsia/
474┗━ pkg/
475 ┣━ meta/
476 ┃ ┣━ package
477 ┃ ┗━ hello_fuchsia.cm
478 ┣━ hello_fuchsia_manifest/
479 ┃ ┗━ ...
480 ┣━ hello_fuchsia.manifest
481 ┣━ hello_fuchsia.cml
482 ┗━ hello_fuchsia_package_manifest
064997fb
FG
483```
484
f2b60f7d
FG
485We are now ready to publish the package.
486
487## Publishing a Fuchsia package
488
489With our package and component manifests setup,
490we can now publish our package. The first step will
491be to create a Fuchsia package repository to publish
492to.
493
494### Creating a Fuchsia package repository
495
496We can set up our repository with:
064997fb
FG
497
498```sh
31ef2f64 499${SDK_PATH}/tools/${ARCH}/ffx repository create pkg/repo
064997fb
FG
500```
501
f2b60f7d
FG
502**Current directory structure**
503```txt
504hello_fuchsia/
505┗━ pkg/
506 ┣━ meta/
507 ┃ ┣━ package
508 ┃ ┗━ hello_fuchsia.cm
509 ┣━ hello_fuchsia_manifest/
510 ┃ ┗━ ...
511 ┣━ repo/
512 ┃ ┗━ ...
513 ┣━ hello_fuchsia.manifest
514 ┣━ hello_fuchsia.cml
515 ┗━ hello_fuchsia_package_manifest
516```
517
518## Publishing Fuchsia package to repository
519
520We can publish our new package to that repository with:
064997fb
FG
521
522```sh
31ef2f64
FG
523${SDK_PATH}/tools/${ARCH}/ffx repository publish \
524 --package pkg/hello_fuchsia_package_manifest \
525 pkg/repo
064997fb
FG
526```
527
f2b60f7d 528Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using:
064997fb
FG
529
530```sh
f2b60f7d 531${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \
31ef2f64
FG
532 --repository hello-fuchsia \
533 pkg/repo
f2b60f7d
FG
534```
535
536## Running a Fuchsia component on an emulator
537
538At this point, we are ready to run our Fuchsia
539component. For reference, our final directory
540structure will look like:
541
542**Final directory structure**
543```txt
544hello_fuchsia/
9c376795
FG
545┣━ src/ (if using rustc)
546┃ ┗━ hello_fuchsia.rs ...
547┣━ bin/ ...
548┃ ┗━ hello_fuchsia ...
549┣━ src/ (if using cargo)
550┃ ┗━ main.rs ...
551┣━ target/ ...
552┃ ┗━ x86_64-unknown-fuchsia/ ...
553┃ ┗━ debug/ ...
554┃ ┗━ hello_fuchsia ...
f2b60f7d
FG
555┗━ pkg/
556 ┣━ meta/
557 ┃ ┣━ package
558 ┃ ┗━ hello_fuchsia.cm
559 ┣━ hello_fuchsia_manifest/
560 ┃ ┗━ ...
561 ┣━ repo/
562 ┃ ┗━ ...
563 ┣━ hello_fuchsia.manifest
564 ┣━ hello_fuchsia.cml
565 ┗━ hello_fuchsia_package_manifest
064997fb
FG
566```
567
f2b60f7d 568### Starting the Fuchsia emulator
064997fb
FG
569
570Start a Fuchsia emulator in a new terminal using:
571
572```sh
573${SDK_PATH}/tools/${ARCH}/ffx product-bundle get workstation_eng.qemu-${ARCH}
574${SDK_PATH}/tools/${ARCH}/ffx emu start workstation_eng.qemu-${ARCH} --headless
575```
576
f2b60f7d
FG
577### Watching emulator logs
578
579Once the emulator is running, open a separate terminal to watch the emulator logs:
580
581**In separate terminal**
582```sh
583${SDK_PATH}/tools/${ARCH}/ffx log \
584 --since now
585```
586
587### Serving a Fuchsia package
588
589Now, start a package repository server to serve our
590package to the emulator:
064997fb
FG
591
592```sh
f2b60f7d 593${SDK_PATH}/tools/${ARCH}/ffx repository server start
064997fb
FG
594```
595
f2b60f7d 596Once the repository server is up and running, register it with the target Fuchsia system running in the emulator:
064997fb
FG
597
598```sh
f2b60f7d
FG
599${SDK_PATH}/tools/${ARCH}/ffx target repository register \
600 --repository hello-fuchsia
064997fb
FG
601```
602
f2b60f7d
FG
603### Running a Fuchsia component
604
064997fb
FG
605Finally, run the component:
606
607```sh
f2b60f7d
FG
608${SDK_PATH}/tools/${ARCH}/ffx component run \
609 /core/ffx-laboratory:hello_fuchsia \
610 fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm
064997fb
FG
611```
612
613On reruns of the component, the `--recreate` argument may also need to be
614passed.
615
f2b60f7d
FG
616```sh
617${SDK_PATH}/tools/${ARCH}/ffx component run \
618 --recreate \
619 /core/ffx-laboratory:hello_fuchsia \
620 fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm
621```
622
623## `.gitignore` extensions
624
625Optionally, we can create/extend our `.gitignore` file to ignore files and
626directories that are not helpful to track:
627
628```txt
629pkg/repo
630pkg/meta/hello_fuchsia.cm
631pkg/hello_fuchsia_manifest
632pkg/hello_fuchsia_package_manifest
633```
634
064997fb
FG
635## Testing
636
637### Running unit tests
638
f2b60f7d
FG
639Tests can be run in the same way as a regular binary.
640
641* If using `cargo`, you can simply pass `test --no-run`
642to the `cargo` invocation and then repackage and rerun the Fuchsia package. From our previous example,
9c376795
FG
643this would look like `cargo test --target x86_64-unknown-fuchsia --no-run`, and moving the executable
644binary path found from the line `Executable unittests src/main.rs (target/x86_64-unknown-fuchsia/debug/deps/hello_fuchsia-<HASH>)`
f2b60f7d
FG
645into `pkg/hello_fuchsia.manifest`.
646
647* If using the compiled `rustc`, you can simply pass `--test`
648to the `rustc` invocation and then repackage and rerun the Fuchsia package.
649
650The test harness will run the applicable unit tests.
064997fb
FG
651
652Often when testing, you may want to pass additional command line arguments to
653your binary. Additional arguments can be set in the component manifest:
654
f2b60f7d 655**`pkg/hello_fuchsia.cml`**
064997fb
FG
656```txt
657{
658 include: [ "syslog/client.shard.cml" ],
659 program: {
660 runner: "elf",
661 binary: "bin/hello_fuchsia",
662 args: ["it_works"],
663 },
664}
665```
666
667This will pass the argument `it_works` to the binary, filtering the tests to
668only those tests that match the pattern. There are many more configuration
669options available in CML including environment variables. More documentation is
f2b60f7d 670available on the [Fuchsia devsite].
064997fb
FG
671
672### Running the compiler test suite
673
487cf647
FG
674The commands in this section assume that they are being run from inside your
675local Rust source checkout:
676
677```sh
678cd ${RUST_SRC_PATH}
679```
680
fe692bf9
FG
681To run the Rust test suite on an emulated Fuchsia device, you'll also need to
682download a copy of the Fuchsia SDK. The current minimum supported SDK version is
31ef2f64 683[20.20240412.3.1][minimum_supported_sdk_version].
9ffffee4 684
31ef2f64 685[minimum_supported_sdk_version]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:20.20240412.3.1
487cf647
FG
686
687Fuchsia's test runner interacts with the Fuchsia emulator and is located at
31ef2f64
FG
688`src/ci/docker/scripts/fuchsia-test-runner.py`. First, add the following
689variables to your existing `config-env.sh`:
690
691```sh
692# TEST_TOOLCHAIN_TMP_DIR can point anywhere, but it:
693# - must be less than 108 characters, otherwise qemu can't handle the path
694# - must be consistent across calls to this file (don't use `mktemp -d` here)
695export TEST_TOOLCHAIN_TMP_DIR="/tmp/rust-tmp"
696
697# Keep existing contents of `config-env.sh` from earlier, including SDK_PATH
698```
699
700We can then use the script to start our test environment with:
487cf647
FG
701
702```sh
ed00b5ec 703( \
31ef2f64 704 source config-env.sh && \
ed00b5ec 705 src/ci/docker/scripts/fuchsia-test-runner.py start \
fe692bf9
FG
706 --rust-build ${RUST_SRC_PATH}/build \
707 --sdk ${SDK_PATH} \
708 --target {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia} \
31ef2f64 709 --verbose \
ed00b5ec 710)
487cf647
FG
711```
712
31ef2f64 713Where `${RUST_SRC_PATH}/build` is the `build-dir` set in `config.toml`.
487cf647
FG
714
715Once our environment is started, we can run our tests using `x.py` as usual. The
716test runner script will run the compiled tests on an emulated Fuchsia device. To
9c376795 717run the full `tests/ui` test suite:
487cf647
FG
718
719```sh
720( \
721 source config-env.sh && \
722 ./x.py \
723 --config config.toml \
724 --stage=2 \
9c376795
FG
725 test tests/ui \
726 --target x86_64-unknown-fuchsia \
9ffffee4 727 --run=always \
487cf647 728 --test-args --target-rustcflags \
9ffffee4 729 --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \
487cf647 730 --test-args --target-rustcflags \
9ffffee4 731 --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib \
487cf647 732 --test-args --target-rustcflags \
9ffffee4 733 --test-args -Clink-arg=--undefined-version \
487cf647
FG
734 --test-args --remote-test-client \
735 --test-args src/ci/docker/scripts/fuchsia-test-runner.py \
736)
737```
738
9ffffee4
FG
739By default, `x.py` compiles test binaries with `panic=unwind`. If you built your
740Rust toolchain with `-Cpanic=abort`, you need to tell `x.py` to compile test
741binaries with `panic=abort` as well:
487cf647 742
9ffffee4
FG
743```sh
744 --test-args --target-rustcflags \
745 --test-args -Cpanic=abort \
746 --test-args --target-rustcflags \
747 --test-args -Zpanic_abort_tests \
748```
749
750When finished testing, the test runner can be used to stop the test environment:
487cf647
FG
751
752```sh
753src/ci/docker/scripts/fuchsia-test-runner.py stop
754```
064997fb 755
f2b60f7d
FG
756## Debugging
757
758### `zxdb`
759
760Debugging components running on a Fuchsia emulator can be done using the
761console-mode debugger: [zxdb]. We will demonstrate attaching necessary symbol
762paths to debug our `hello-fuchsia` component.
763
764### Attaching `zxdb`
765
766In a separate terminal, issue the following command from our `hello_fuchsia`
767directory to launch `zxdb`:
768
769**In separate terminal**
770```sh
771${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
9c376795 772 --symbol-path target/x86_64-unknown-fuchsia/debug
f2b60f7d
FG
773```
774
775* `--symbol-path` gets required symbol paths, which are
776necessary for stepping through your program.
777
9ffffee4
FG
778The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)"
779section describes how you can display Rust and/or Fuchsia source code in your
780debugging session.
f2b60f7d
FG
781
782### Using `zxdb`
783
784Once launched, you will be presented with the window:
785
786```sh
787Connecting (use "disconnect" to cancel)...
788Connected successfully.
789👉 To get started, try "status" or "help".
790[zxdb]
791```
792
793To attach to our program, we can run:
794
795```sh
796[zxdb] attach hello_fuchsia
797```
798
799**Expected output**
800```sh
801Waiting for process matching "hello_fuchsia".
802Type "filter" to see the current filters.
803```
804
805Next, we can create a breakpoint at main using "b main":
806
807```sh
808[zxdb] b main
809```
810
811**Expected output**
812```sh
813Created Breakpoint 1 @ main
814```
815
816Finally, we can re-run the "hello_fuchsia" component from our original
817terminal:
818
819```sh
820${SDK_PATH}/tools/${ARCH}/ffx component run \
821 --recreate \
822 fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm
823```
824
825Once our component is running, our `zxdb` window will stop execution
826in our main as desired:
827
828**Expected output**
829```txt
830Breakpoint 1 now matching 1 addrs for main
831🛑 on bp 1 hello_fuchsia::main() • main.rs:2
832 1 fn main() {
833 ▶ 2 println!("Hello Fuchsia!");
834 3 }
835 4
836[zxdb]
837```
838
839`zxdb` has similar commands to other debuggers like [gdb].
840To list the available commands, run "help" in the
841`zxdb` window or visit [the zxdb documentation].
842
843```sh
844[zxdb] help
845```
846
847**Expected output**
848```sh
849Help!
850
851 Type "help <command>" for command-specific help.
852
853Other help topics (see "help <topic>")
854...
855```
856
857### Displaying source code in `zxdb`
858
859By default, the debugger will not be able to display
860source code while debugging. For our user code, we displayed
861source code by pointing our debugger to our debug binary via
862the `--symbol-path` arg. To display library source code in
863the debugger, you must provide paths to the source using
864`--build-dir`. For example, to display the Rust and Fuchsia
865source code:
866
867```sh
868${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
9c376795 869 --symbol-path target/x86_64-unknown-fuchsia/debug \
f2b60f7d
FG
870 --build-dir ${RUST_SRC_PATH}/rust \
871 --build-dir ${FUCHSIA_SRC_PATH}/fuchsia/out/default
872```
873
874 * `--build-dir` links against source code paths, which
875 are not strictly necessary for debugging, but is a nice-to-have
876 for displaying source code in `zxdb`.
877
878 Linking to a Fuchsia checkout can help with debugging Fuchsia libraries,
879 such as [fdio].
880
9ffffee4
FG
881### Debugging the compiler test suite
882
883Debugging the compiler test suite requires some special configuration:
884
885First, we have to properly configure zxdb so it will be able to find debug
886symbols and source information for our test. The test runner can do this for us
887with:
888
889```sh
890src/ci/docker/scripts/fuchsia-test-runner.py debug \
891 --rust-src ${RUST_SRC_PATH} \
892 --fuchsia-src ${FUCHSIA_SRC_PATH} \
893 --test ${TEST}
894```
895
896where `${TEST}` is relative to Rust's `tests` directory (e.g. `ui/abi/...`).
897
898This will start a zxdb session that is properly configured for the specific test
899being run. All three arguments are optional, so you can omit `--fuchsia-src` if
900you don't have it downloaded. Now is a good time to set any desired breakpoints,
901like `b main`.
902
903Next, we have to tell `x.py` not to optimize or strip debug symbols from our
904test suite binaries. We can do this by passing some new arguments to `rustc`
905through our `x.py` invocation. The full invocation is:
906
907```sh
908( \
909 source config-env.sh && \
910 ./x.py \
911 --config config.toml \
912 --stage=2 \
913 test tests/${TEST} \
914 --target x86_64-unknown-fuchsia \
915 --run=always \
916 --test-args --target-rustcflags \
917 --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \
918 --test-args --target-rustcflags \
919 --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib \
920 --test-args --target-rustcflags \
921 --test-args -Clink-arg=--undefined-version \
922 --test-args --target-rustcflags \
923 --test-args -Cdebuginfo=2 \
924 --test-args --target-rustcflags \
925 --test-args -Copt-level=0 \
926 --test-args --target-rustcflags \
927 --test-args -Cstrip=none \
928 --test-args --remote-test-client \
929 --test-args src/ci/docker/scripts/fuchsia-test-runner.py \
930)
931```
932
933*If you built your Rust toolchain with `panic=abort`, make sure to include the
934previous flags so your test binaries are also compiled with `panic=abort`.*
935
936Upon running this command, the test suite binary will be run and zxdb will
937attach and load any relevant debug symbols.
938
f2b60f7d
FG
939[Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json
940[Fuchsia]: https://fuchsia.dev/
941[source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build
942[rustup]: https://rustup.rs/
9c376795 943[cargo]: ../../cargo/index.html
f2b60f7d
FG
944[Fuchsia SDK]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core
945[overview of CML]: https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manifests
946[reference for the file format]: https://fuchsia.dev/reference/cml
947[Fuchsia devsite]: https://fuchsia.dev/reference/cml
064997fb 948[not currently supported]: https://fxbug.dev/105393
f2b60f7d
FG
949[zxdb]: https://fuchsia.dev/fuchsia-src/development/debugger
950[gdb]: https://www.sourceware.org/gdb/
951[the zxdb documentation]: https://fuchsia.dev/fuchsia-src/development/debugger
952[fdio]: https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/fdio/