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