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