blob: dac42503cf834e894dbc59a1c3723b8402365405 [file] [log] [blame] [view] [edit]
# Get started with the Fuchsia SDK
This guide provides step-by-step instructions on setting up the
Fuchsia SDK development environment on your host machine. The guide then walks
you through the basic workflows of building, running, debugging, and testing
Fuchsia components using [the Fuchsia SDK][using-the-sdk].
Important: The Fuchsia SDK is in active development. At the moment, Fuchsia
does not support general public usage of the Fuchsia SDK. The APIs in the
SDK are subject to change without notice.
Complete the following sections:
1. [Prerequisites](#prerequisites)
2. [Clone the SDK samples repository](#clone-the-sdk-samples-repository)
3. [Start the emulator](#start-the-emulator)
4. [Create a local package repository](#create-a-local-package-repository)
5. [Build and run the sample component](#build-and-run-the-sample-component)
6. [View symbolized logs](#view-symbolized-logs)
7. [Debug the sample component](#debug-the-sample-component)
8. [Inspect components](#inspect-components)
9. [Run tests](#run-tests)
Found an issue? Please [let us know][sdk-bug]{:.external}.
## 1. Prerequisites {:#prerequisites}
Before you begin, complete the prerequisite steps below:
* [Check host machine requirements](#check-host-machine-requirements)
* [Install dependencies](#install-dependencies)
* [Generate Fuchsia-specific SSH keys](#generate-fuchsia-specific-ssh-keys)
### Check host machine requirements {:#check-host-machine-requirements}
This guide requires that your host machine meets the following criteria:
* A Linux machine. **macOS** is not supported yet.
* Has at least 15 GB of storage space.
* Supports [KVM][kvm]{:.external} (Kernel Virtual Machine) for running a [QEMU][qemu]{:.external}-based emulator.
* IPv6 is enabled.
### Install dependencies {:#install-dependencies}
[Bazel][bazel]{:.external} and [Git][git]{:.external} need
to be installed on the host machine.
To install these dependencies, do the following:
Note: You only need to do this once on your host machine.
1. Install Git, for example:
```posix-terminal
sudo apt-get install git
```
1. To install Bazel, visit the [Installing Bazel][bazel-install]{:.external}
page and follow the installation instructions specific to your host machine.
### Generate Fuchsia-specific SSH keys {:#generate-fuchsia-specific-ssh-keys}
To be able to connect to a Fuchsia device (including a Fuchsia emulator instance),
some `ffx` commands (such as `ffx log` and `ffx target show`) require that
[Fuchsia-specific SSH keys][fuchsia-ssh-keys] are present on the host machine.
To check if your host machine already has Fuchsia-specific SSH keys, run the following command:
```posix-terminal
ls ~/.ssh | grep fuchsia
```
This command should print output displaying the `fuchsia_*` files, similar to the following:
```none {:.devsite-disable-click-to-copy}
$ ls ~/.ssh | grep fuchsia
fuchsia_authorized_keys
fuchsia_ed25519
fuchsia_ed25519.pub
```
**If you don’t see these files**, generate Fuchsia-specific SSH keys on the host machine:
Note: These Fuchsia-specific SSH keys are only used to connect to Fuchsia
devices during development. Generating these SSH keys won't alter your current
SSH settings.
1. Generate a new private and public SSH key pair:
```posix-terminal
[[ -f "${HOME}/.ssh/fuchsia_ed25519" ]] || ssh-keygen -P "" -t ed25519 -f "${HOME}/.ssh/fuchsia_ed25519" -C "${USER}@$(hostname -f) Shared SSH Key for Fuchsia"
```
1. Generate a `fuchsia_authorized_keys` file:
```posix-terminal
[[ -f "${HOME}/.ssh/fuchsia_authorized_keys" ]] || ssh-keygen -y -f "${HOME}/.ssh/fuchsia_ed25519" > "${HOME}/.ssh/fuchsia_authorized_keys"
```
1. Verify that Fuchsia-specific SSH keys are generated:
```posix-terminal
ls ~/.ssh | grep fuchsia
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ ls ~/.ssh | grep fuchsia
fuchsia_authorized_keys
fuchsia_ed25519
fuchsia_ed25519.pub
```
## 2. Clone the SDK samples repository {:#clone-the-sdk-samples-repository}
Clone the SDK samples repository on your host machine. This repository contains the
Bazel-based Fuchsia SDK and sample components.
Note: Support for installing the SDK by itself, without a samples repository, is planned. See [this ticket][ticket-01].
The tasks include:
* Bootstrap the SDK samples repository.
* Verify that you can build the sample components and run [`ffx`][ffx] commands.
Do the following:
1. In a terminal, change to your home directory:
Note: This guide uses the home directory (`$HOME`) as a base directory. This is where a new work
directory (`getting-started`) will be created for this guide. You may also select a different
base directory (for instance, `cd $HOME/my-fuchsia-project`).
```posix-terminal
cd ~
```
1. Clone the Fuchsia samples repository:
```posix-terminal
git clone https://fuchsia.googlesource.com/sdk-samples/getting-started --recurse-submodules
```
This creates a new directory named `getting-started`, which clones the content of the SDK samples
repository.
1. Go to the new directory:
```posix-terminal
cd getting-started
```
1. To verify the Fuchsia SDK environment setup, build the sample components:
Note: If it doesn't exist already, the `bazel build` command below creates the
`~/.package_repos/sdk-samples` directory on your host machine. This directory is used
for storing and serving Fuchsia packages in this guide.
```posix-terminal
bazel build --config=fuchsia_x64 //src/hello_world:pkg --publish_to=$HOME/.package_repos/sdk-samples
```
The first build may take a few minutes to download dependencies,
such as [Clang][clang]{:.external} and [Fuchsia IDK][fuchsia-idk] (which
includes the `ffx` tool).
When finished successfully, it prints output similar to the following in the end:
```none {:.devsite-disable-click-to-copy}
$ bazel build --config=fuchsia_x64 //src/hello_world:pkg --publish_to=$HOME/.package_repos/sdk-samples
...
INFO: Elapsed time: 70.715s, Critical Path: 1.87s
INFO: 43 processes: 28 internal, 13 linux-sandbox, 2 local.
INFO: Build completed successfully, 43 total actions
```
1. To verify that you can use the `ffx` tool in your environment,
run the following command:
```posix-terminal
tools/ffx version -v
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx version -v
ffx:
build-version: 2022-04-12T01:17:14+00:00
integration-commit-hash: 19cd0be96c90e3083efc4a17db9ae4171527cab4
integration-commit-time: Tue, 12 Apr 2022 01:17:14 +0000
daemon:
build-version: 2022-04-12T01:17:14+00:00
integration-commit-hash: 19cd0be96c90e3083efc4a17db9ae4171527cab4
integration-commit-time: Tue, 12 Apr 2022 01:17:14 +0000
```
At this point, you only need to confirm that you can run this `ffx` command
without any errors.
Note: To ensure that you’re using the right version of `ffx` (which needs to
match the version of the SDK), consider updating your `PATH` to include the
SDK's `tools` directory where `ffx` is located (for instance,
`export PATH="$PATH:$HOME/getting-started/tools"`). However, if you don't
wish to update your `PATH`, ensure that you specify the relative path to
this `ffx` tool (`tools/ffx`) whenever you run `ffx` commands.
## 3. Start the emulator {:#start-the-emulator}
Start the Fuchsia emulator on the host machine.
The tasks include:
* Configure your network environment for the Fuchsia emulator.
* Download one of Fuchsia's prebuilt images from Google Cloud Storage.
* Start the Fuchsia emulator to run the downloaded Fuchsia prebuilt image.
* Set the emulator instance as the default target device.
* Verify that various `ffx` commands can connect to the emulator instance.
Do the following:
1. Configure Tun/Tap:
Note: You only need to do this once. However, if you run it again, it harmlessly
fails with a `Device or resource busy` message. You can safely ignore this error.
```posix-terminal
sudo ip tuntap add dev qemu mode tap user $USER && sudo ip link set qemu up
```
1. Download the latest Fuchsia Workstation prebuilt image for the emulator
(`workstation.qemu-x64`):
```posix-terminal
tools/ffx product-bundle get workstation.qemu-x64
```
This command may take a few minutes to download the image and product metadata.
1. (Optional) Stop all running emulator instances:
```posix-terminal
tools/ffx emu stop --all
```
1. Start a new Fuchsia emulator instance (and name it `walkthrough-emu`):
```posix-terminal
tools/ffx emu start --net tap --headless --name walkthrough-emu workstation.qemu-x64
```
This command starts a headless emulator instance running a Fuchsia prebuilt
image.
When the instance is up and running, the command prints output similar to the
following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx emu start --net tap --headless --name walkthrough-emu workstation.qemu-x64
Logging to "/home/alice/.local/share/Fuchsia/ffx/emu/instances/walkthrough-emu/emulator.log"
Waiting for Fuchsia to start (up to 60 seconds)...........
Emulator is ready.
```
1. Verify that an emulator instance named `walkthrough-emu` is running:
```posix-terminal
tools/ffx emu list
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx emu list
[Active] walkthrough-emu
```
1. Verify that the emulator instance is detected as a device:
```posix-terminal
tools/ffx target list
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx target list
NAME SERIAL TYPE STATE ADDRS/IP RCS
walkthrough-emu <unknown> Unknown Product [fe80::d4e3:9a5b:c2e:2534%qemu] Y
```
1. Set this emulator instance to be the default device:
```posix-terminal
tools/ffx target default set walkthrough-emu
```
This command exits silently without output.
1. Verify that the default device is set:
```
tools/ffx target default get
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx target default get
walkthrough-emu
```
1. To verify that you can establish an SSH connection to the emulator instance,
run the following command:
Note: To retrieve detailed device information, the `ffx target show` command uses
[Fuchsia-specific SSH keys](#generate-fuchsia-specific-ssh-keys) to make an SSH
connection to the device.
```posix-terminal
tools/ffx target show
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx target show
Target:
Name: "walkthrough-emu"
SSH Address: "[fe80::9597:e5fb:4746:a7b1%3]:22"
Board:
Name: "default-board"
Revision: "1"
Instruction set: "x64"
Device:
...
Build:
Version: "7.20220330.2.1"
Product: "workstation"
Board: "qemu-x64"
Commit: "2022-03-30T14:02:43+00:00"
Last Reboot:
Graceful: "false"
Reason: "Cold"
```
The example output above shows that the target device is running a `workstation.qemu-x64`
prebuilt image whose version is `7.20220330.2.1` (which indicates that this image was
built and published on March 30, 2022).
1. Verify that you can stream the device logs:
```posix-terminal
tools/ffx log
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx log
...
[33.698][core/cobalt][cobalt,fidl_service,core][I] LocalAggregation: Enabling local aggregation.
[33.698][core/cobalt][cobalt,fidl_service,core][I] ClearcutV1ShippingManager: Disabling observation uploading.
[34.818][core/network/netstack][netstack,DHCP][W] client.go(692): ethp0004: recv timeout waiting for dhcpOFFER; retransmitting dhcpDISCOVER
[34.818][core/network/netstack][netstack,DHCP][I] client.go(891): ethp0004: send dhcpDISCOVER from :68 to 255.255.255.255:67 on NIC:2 (broadcast_flag=false ciaddr=false)
[35.654][core/remote-control][remote_control,remote-control][I] attempting to connect hub_path="/discovery_root/children/bootstrap/resolved/expose/fuchsia.diagnostics.LogSettings"
...
```
Press `CTRL+C` to exit.
## 4. Create a local package repository {:#create-a-local-package-repository}
Create a local [Fuchsia package repository][fuchsia-package-repo] and register it to
a Fuchsia device. This package repository is used for storing and serving Fuchsia
packages in this guide.
The tasks include:
* Configure your environment to enable the Fuchsia package server features.
* Create a new Fuchsia package repository.
* Start the Fuchsia package server.
* Register the new repository to the target device (that is, the emulator instance).
Do the following:
1. Enable the new `ffx repository` server features:
Note: You only need to do this once.
```posix-terminal
tools/ffx config set repository.server.mode ffx
```
1. For the new `ffx` settings to take effect, stop the `ffx` daemon:
```posxi-terminal
tools/ffx daemon stop
```
A new instance of the `ffx` daemon starts the next time you run a `ffx` command.
1. Create a new Fuchsia package repository (and map it to the
`~/.package_repos/sdk-samples` directory):
Note: The `~/.package_repos/sdk-samples` directory is created on your host
machine when you run the `bazil build` command for the first time in the
[Clone the SDK samples repository](#clone-the-sdk-samples-repository) section.
```posix-terminal
tools/ffx repository add-from-pm -r fuchsiasamples.com ~/.package_repos/sdk-samples
```
This command exits silently without output.
1. Verify that the new package repository (`fuchsiasamples.com`) is created:
```posix-terminal
tools/ffx repository list
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx repository list
+----------------------+------+-----------------------------------------------+
| NAME | TYPE | EXTRA |
+======================+======+===============================================+
| fuchsiasamples.com | pm | /home/alice/.package_repos/sdk-samples |
+----------------------+------+-----------------------------------------------+
| workstation.qemu-x64 | pm | /home/alice/.local/share/Fuchsia/.../packages |
+----------------------+------+-----------------------------------------------+
```
The `workstation.qemu-x64` repository is created when you run the
`ffx product-bundle get` command (previously in the
[Start the emulator](#start-the-emulator) section above). This repository
contains additional system packages for the `workstation.qemu-x64` prebuilt image.
1. Start the Fuchsia package server:
```posix-terminal
tools/ffx repository server start
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx repository server start
server is listening on [::]:8083
```
1. Register the `fuchsiasamples.com` repository to the target device
(that is, the emulator instance):
```posix-terminal
tools/ffx target repository register -r fuchsiasamples.com
```
This command exits silently without output.
1. Register the `workstation.qemu-x64` repository to the target device
as `fuchsia.com`:
```posix-terminal
tools/ffx target repository register -r workstation.qemu-x64 --alias fuchsia.com
```
This command exits silently without output.
## 5. Build and run the sample component {:#build-and-run-the-sample-component}
Build and run the C++ Hello World component included in the SDK samples
repository. [Components][fuchsia-component] are the basic unit of executable software
on Fuchsia.
The tasks include:
* Build and publish the sample Hello World component.
* Run the component.
* Make a change to the component.
* Repeat the build and run steps.
* Verify the change.
Do the following:
1. Build the sample component:
```posix-terminal
bazel build --config=fuchsia_x64 //src/hello_world:pkg --publish_to=$HOME/.package_repos/sdk-samples
```
When the build is successful, it publishes the build artifacts to the
`~/.package_repos/sdk-samples` directory, which is associated with
your new [local Fuchsia package repository](#create-a-local-package-repository).
1. Run the sample component:
```posix-terminal
tools/ffx component run "fuchsia-pkg://fuchsiasamples.com/hello_world#meta/hello_world.cm"
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx component run "fuchsia-pkg://fuchsiasamples.com/hello_world#meta/hello_world.cm"
URL: fuchsia-pkg://fuchsiasamples.com/hello_world#meta/hello_world.cm
Moniker: /core/ffx-laboratory:hello_world
Creating component instance...
Starting component instance...
```
1. Check the status of the `hello_world` component:
```posix-terminal
tools/ffx component show hello_world
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx component show hello_world
Moniker: /core/ffx-laboratory:hello_world
URL: fuchsia-pkg://fuchsiasamples.com/hello_world#meta/hello_world.cm
Type: CML dynamic component
Component State: Resolved
Incoming Capabilities: fuchsia.logger.LogSink
pkg
Merkle root: b44de670cf30c77c55823af0fea67d19e0fabc86ddd0946646512be12eeb8dc0
Execution State: Stopped
```
The output shows that the `hello_world` component has run and is now terminated (`Stopped`).
1. Verify the `Hello, World!` message in the device logs:
```posix-terminal
tools/ffx log --filter hello_world dump
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx log --filter hello_world dump
...
[1702.331][core/pkg-resolver][pkg-resolver][I] Fetching blobs for fuchsia-pkg://fuchsiasamples.com/hello_world: []
[1702.331][core/pkg-resolver][pkg-resolver][I] resolved fuchsia-pkg://fuchsiasamples.com/hello_world as fuchsia-pkg://fuchsiasamples.com/hello_world to dbdc177180730f521849484c7a0e11dbe763b75804a7d1b97158a668b463526c with TUF
[1702.405][core/ffx-laboratory:hello_world][][I] Hello, World!
```
1. Use a text editor to edit the `src/hello_world/hello_world.cc` file, for example:
```posix-terminal
nano src/hello_world/hello_world.cc
```
1. Change the message to `"Hello again, World!"`.
The `main()` method should look like below:
```none {:.devsite-disable-click-to-copy}
int main() {
std::cout << "Hello again, World!\n";
return 0;
}
```
1. Save the file and exit the text editor.
1. Build the sample component again:
```posix-terminal
bazel build --config=fuchsia_x64 //src/hello_world:pkg --publish_to=$HOME/.package_repos/sdk-samples
```
1. Run the sample component again (notice the `--recreate` flag this time):
```posix-terminal
tools/ffx component run "fuchsia-pkg://fuchsiasamples.com/hello_world#meta/hello_world.cm" --recreate
```
1. Verify the `Hello again, World!` message in the device logs:
```posix-terminal
tools/ffx log --filter hello_world dump
```
This command prints output similar to the following;
```none {:.devsite-disable-click-to-copy}
$ tools/ffx log --filter hello_world dump
...
[2013.380][core/pkg-resolver][pkg-resolver][I] Fetching blobs for fuchsia-pkg://fuchsiasamples.com/hello_world: []
[2013.380][core/pkg-resolver][pkg-resolver][I] resolved fuchsia-pkg://fuchsiasamples.com/hello_world as fuchsia-pkg://fuchsiasamples.com/hello_world to da1c95e829ec32f78e7b4e8eb845b697679d9cb82432da3cc85763dbc3269395 with TUF
[2013.418][core/ffx-laboratory:hello_world][][I] Hello again, World!
```
## 6. View symbolized logs {:#view-symbolized-logs}
Examine the [symbolized logs][symbolize-logs] (that is, human readable
stack traces) of a crashed component.
The tasks include:
* Update the sample component to crash when it's started.
* Build the sample component, which generates and registers the debug symbols
of the component.
* Run the updated sample component.
* Verify that the crashed component's logs are in symbolized format.
Do the following:
1. Use a text editor to edit the `src/hello_world/hello_world.cc` file, for example:
```posix-terminal
nano src/hello_world/hello_world.cc
```
1. Just above the line `return 0;`, add the following line:
```
abort();
```
The `main()` method should look like below:
```none {:.devsite-disable-click-to-copy}
int main() {
std::cout << "Hello again, World!\n";
abort();
return 0;
}
```
This update will cause the component to crash immediately after printing a message.
1. Save the file and exit the text editor.
1. Rebuild the sample component:
```posix-terminal
bazel build --config=fuchsia_x64 //src/hello_world:pkg --publish_to=$HOME/.package_repos/sdk-samples
```
Building a component automatically generates and registers the component’s debug
symbols in your development environment.
1. Run the updated sample component:
```posix-terminal
tools/ffx component run "fuchsia-pkg://fuchsiasamples.com/hello_world#meta/hello_world.cm" --recreate
```
1. Verify that the sample component's crash stack is symbolized in the kernel logs:
```posix-terminal
tools/ffx log --kernel dump
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx log --kernel dump
...
[174978.449][klog][klog][I] [[[ELF module #0x6 "libzircon.so" BuildID=5679a47f32c6fa7b 0x422808b26000]]]
[174978.449][klog][klog][I] [[[ELF module #0x7 "libc.so" BuildID=1c3e8dded0fc94eb 0x428049099000]]]
[174978.450][klog][klog][I] #0 0x00004280490fd74b in abort() ../../zircon/third_party/ulib/musl/src/exit/abort.c:7 <libc.so>+0x6474b sp 0x11d191bcf70
[174978.450][klog][klog][I] #1 0x000001d56b552047 in main() src/hello_world/hello_world.cc:9 <<VMO#32996646=blob-a4c56246>>+0x2047 sp 0x11d191bcf80
[174978.450][klog][klog][I] #2 0x00004280490fcef2 in start_main(const start_params*) ../../zircon/third_party/ulib/musl/src/env/__libc_start_main.c:140 <libc.so>+0x63ef2 sp 0x11d191bcfa0
[174978.450][klog][klog][I] #3 0x00004280490fd145 in __libc_start_main(zx_handle_t, int (*)(int, char**, char**)) ../../zircon/third_party/ulib/musl/src/env/__libc_start_main.c:215 <libc.so>+0x64145 sp 0x11d191bcff0
[174978.450][klog][klog][I] #4 0x000001d56b552011 in _start(zx_handle_t) ../../zircon/system/ulib/c/Scrt1.cc:7 <<VMO#32996646=blob-a4c56246>>+0x2011 sp 0x42d5c7089fe0
[174978.450][klog][klog][I] #5 0x0000000000000000 is not covered by any module sp 0x42d5c7089ff0
[174978.457][klog][klog][I] KERN: terminating process 'hello_world.cm' (32996655)
```
Verify that the lines in the kernel logs show the exact filenames and line numbers (for example,
`main() src/hello_world/hello_world.cc:9`) that might've caused the component to crash.
## 7. Debug the sample component {:#debug-the-sample-component}
Launch the [Fuchsia debugger][fuchsia-debugger] (`zxdb`) for debugging the sample
component, which is now updated to crash when it's started.
The tasks include:
* Start the Fuchsia debugger and connect it to the emulator instance.
* Attach the debugger to the sample component.
* Set a breakpoint.
* Run the sample component and step through the code.
Do the following:
1. Start the Fuchsia debugger:
```posix-terminal
tools/ffx debug connect
```
This command automatically connects the debugger to the default target
device, which is the emulator instance.
When connected to the device, this command starts the `zxdb` terminal, for example:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx debug connect
Connecting (use "disconnect" to cancel)...
Connected successfully.
👉 To get started, try "status" or "help".
[zxdb]
```
1. In the `zxdb` terminal, attach the debugger to the `hello_world.cm` component:
<pre class="devsite-click-to-copy">
<span class="no-select">[zxdb] </span>attach hello_world.cm
</pre>
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
[zxdb] attach hello_world.cm
Waiting for process matching "hello_world.cm".
Type "filter" to see the current filters.
```
1. In the `zxdb` terminal, set a breakpoint at the `main()` method:
<pre class="devsite-click-to-copy">
<span class="no-select">[zxdb] </span>break main
</pre>
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
[zxdb] break main
Created Breakpoint 1 @ main
Pending: No current matches for location. It will be matched against new
processes and shared libraries.
```
1. In a different terminal, run the sample component:
Note: In this new terminal, make sure that you change to the same work
directory (for instance, `cd $HOME/getting-started`).
```posix-terminal
tools/ffx component run "fuchsia-pkg://fuchsiasamples.com/hello_world#meta/hello_world.cm" --recreate
```
In the `zxdb` terminal, the sample component is paused
at the breakpoint:
```none {:.devsite-disable-click-to-copy}
Attached Process 1 state=Running koid=17658651 name=hello_world.cm
Downloading symbols...
Breakpoint 1 now matching 1 addrs for main
Could not load symbols for "<vDSO>" because there was no mapping for build ID "1dbd2861a642d61b".
Symbol downloading complete. 0 succeeded, 1 failed.
🛑 on bp 1, 2 main() • hello_world.cc:8
6
7 int main() {
▶ 8 std::cout << "Hello again, World!\n";
9 abort();
10 return 0;
[zxdb]
```
1. In the new terminal, monitor device logs for the `hello_world` component:
```posix-terminal
tools/ffx log --filter hello_world
```
This comment prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx log --filter hello_world
...
[5538.385][core/pkg-resolver][pkg-resolver][I] Fetching blobs for fuchsia-pkg://fuchsiasamples.com/hello_world: []
[5538.385][core/pkg-resolver][pkg-resolver][I] resolved fuchsia-pkg://fuchsiasamples.com/hello_world as fuchsia-pkg://fuchsiasamples.com/hello_world to 940cbd84428125a90e1fbeba7033af7cb0f857f8f0bb2879d6b07cd1001f2225 with TUF
[5538.408][core/pkg-resolver][pkg-resolver][I] Fetching blobs for fuchsia-pkg://fuchsiasamples.com/hello_world: []
[5538.409][core/pkg-resolver][pkg-resolver][I] resolved fuchsia-pkg://fuchsiasamples.com/hello_world as fuchsia-pkg://fuchsiasamples.com/hello_world to 940cbd84428125a90e1fbeba7033af7cb0f857f8f0bb2879d6b07cd1001f2225 with TUF
```
Notice the `Hello again, World!` line is not printed yet.
1. In the `zxdb` terminal, use `next` to step through the code:
<pre class="devsite-click-to-copy">
<span class="no-select">[zxdb] </span>next
</pre>
In the `zxdb` terminal, the code get executed line by line, for
example:
```none {:.devsite-disable-click-to-copy}
...
🛑 on bp 1 main() • hello_world.cc:8
6
7 int main() {
▶ 8 std::cout << "Hello again, World!\n";
9 abort();
10 return 0;
[zxdb] next
🛑 main() • hello_world.cc:9
7 int main() {
8 std::cout << "Hello again, World!\n";
▶ 9 abort();
10 return 0;
11 }
```
In the device logs terminal, verify that the `Hello again, World!` line is
now printed:
```none {:.devsite-disable-click-to-copy}
[5694.479][core/ffx-laboratory:hello_world][][I] Hello again, World!
```
1. To exit the `zxdb` terminal, type `exit` or press `Ctrl-D`.
This causes the component to finish the execution of the rest of the code.
Note: For more information on usages and best practices on `zxdb`, see the
[zxdb user guide][zxdb-user-guide].
## 8. Inspect components {:#inspect-components}
Retrieve a component's data exposed by Fuchsia's Inspect API. This data can be any
set of specialized information that a Fuchsia component is programmed to collect
while it is running on the device.
Note: For a component to collect and expose inspect data, the implementation
of inspect operations and data types must be placed in the component’s code.
Developers use this inspect feature to collect and expose information that will be
helpful for debugging the component or the system. For details,
see [Fuchsia component inspection overview][inspect-overview].
The tasks include:
* Scan the list of components on the device that expose inspect data (for
example, the `bootstrap/archivist` component).
* Scan the list of selectors provided by the `bootstrap/archivist` component.
* Inspect a specific set of data from the `bootstrap/archivist` component.
Do the following:
1. View the list of components on the device that expose inspect data:
```posix-terminal
tools/ffx inspect list
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx inspect list
<component_manager>
audio_core.cmx
bootstrap/archivist
bootstrap/driver_manager
bootstrap/fshost
...
core/wlandevicemonitor
core/wlanstack
crash_reports.cmx
feedback_data.cmx
httpsdate_time_source.cmx
scenic.cmx
timekeeper.cmx
```
Notice that the `bootstrap/archivist` component is on the list.
1. View all available selectors for the `bootstrap/archivist` component:
```posix-terminal
tools/ffx inspect selectors bootstrap/archivist
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx inspect selectors bootstrap/archivist
bootstrap/archivist:root/archive_accessor_stats/all/inspect/batch_iterator/get_next:errors
bootstrap/archivist:root/archive_accessor_stats/all/inspect/batch_iterator/get_next:requests
bootstrap/archivist:root/archive_accessor_stats/all/inspect/batch_iterator/get_next:responses
...
```
Each of these selects represents a different type of data you can inspect.
1. Inspect the `bootstrap/archivist` component for the recent events data:
```posix-terminal
tools/ffx inspect show bootstrap/archivist:root/events/recent_events
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx inspect show bootstrap/archivist:root/events/recent_events
bootstrap/archivist:
metadata:
filename = fuchsia.inspect.Tree
component_url = fuchsia-boot:///#meta/archivist.cm
timestamp = 531685168169295
payload:
root:
events:
recent_events:
319:
@time = 7730479794
event = log_sink_requested
moniker = core/memory_monitor
320:
@time = 7782621023
event = log_sink_requested
moniker = core/bt-a2dp
321:
...
516:
@time = 5538432236492
event = log_sink_requested
moniker = core/ffx-laboratory:hello_world
517:
@time = 5825449627765
event = component_stopped
moniker = debug_agent_channel.cmx:1064825
518:
@time = 5825475597828
event = component_stopped
moniker = core/ffx-laboratory:hello_world
```
This data records all the events triggered by components on the device so far.
## 9. Run tests {:#run-tests}
Run tests on the device by launching test components, which are included
in the SDK samples repository.
The tasks include:
* Build and run the sample test components.
* Verify that the tests are passing.
* Update one of the tests to fail.
* Verify the failure in the test results.
Do the following:
1. Build the sample test components:
```posix-terminal
bazel build --config=fuchsia_x64 //src/hello_world:test_pkg --publish_to=$HOME/.package_repos/sdk-samples
```
When the build is successful, this command prints output similar to the following
in the end:
```none {:.devsite-disable-click-to-copy}
$ bazel build --config=fuchsia_x64 //src/hello_world:test_pkg --publish_to=$HOME/.package_repos/sdk-samples
...
INFO: Elapsed time: 5.027s, Critical Path: 4.53s
INFO: 98 processes: 44 internal, 52 linux-sandbox, 2 local.
INFO: Build completed successfully, 98 total actions
```
1. Verify that the basic `hello_test` passes:
```posix-terminal
tools/ffx test run "fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_test.cm"
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx test run "fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_test.cm"
Running test 'fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_test.cm'
[RUNNING] main
[stdout - main]
Hello Test!
[PASSED] main
1 out of 1 tests passed...
fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_test.cm completed with result: PASSED
```
1. Verify that the [GoogleTest][google-test]{:.external} (`gtest`) test passes:
```posix-terminal
tools/ffx test run "fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_gtest.cm"
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx test run "fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_gtest.cm"
Running test 'fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_gtest.cm'
[RUNNING] HelloTest.BasicAssertions
[stdout - HelloTest.BasicAssertions]
Running main() from gmock_main.cc
[PASSED] HelloTest.BasicAssertions
1 out of 1 tests passed...
fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_gtest.cm completed with result: PASSED
```
1. Use a text editor to edit the `src/hello_world/hello_gtest.cc` file, for example:
```posix-terminal
nano src/hello_world/hello_gtest.cc
```
1. Replace `EXPECT_STRNE()` with `EXPECT_STREQ()`:
The test should look like below:
```none {:.devsite-disable-click-to-copy}
TEST(HelloTest, BasicAssertions)
{
// Expect two strings not to be equal.
EXPECT_STREQ("hello", "world");
// Expect equality.
EXPECT_EQ(7 * 6, 42);
}
```
This change will cause the `gtest` test to fail.
1. Save the file and exit the text editor.
1. Rebuild the sample test components:
```posix-terminal
bazel build --config=fuchsia_x64 //src/hello_world:test_pkg --publish_to=$HOME/.package_repos/sdk-samples
```
1. Verify that the `gtest` test now fails:
```posix-terminal
tools/ffx test run "fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_gtest.cm"
```
This command prints output similar to the following:
```none {:.devsite-disable-click-to-copy}
$ tools/ffx test run "fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_gtest.cm"
Running test 'fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_gtest.cm'
[RUNNING] HelloTest.BasicAssertions
[stdout - HelloTest.BasicAssertions]
Running main() from gmock_main.cc
src/hello_world/hello_gtest.cc:11: Failure
Expected equality of these values:
"hello"
"world"
[FAILED] HelloTest.BasicAssertions
Failed tests: HelloTest.BasicAssertions
0 out of 1 tests passed...
fuchsia-pkg://fuchsiasamples.com/hello_test#meta/hello_gtest.cm completed with result: FAILED
One or more test runs failed.
Tests failed
```
**Congratulations! You're now all set with the Fuchsia SDK!**
## Next steps {:#next-steps}
Learn more about the Fuchsia platform and tools in [Fuchsia SDK Fundamentals][fundamentals].
## Appendices
### Clean up the environment before and after walkthrough {:#clean-up-the-environment-before-and-after-walkthrough}
This section provides instructions on how to clean up your development environment
(that is, newly created directories, build artifacts, symlinks, configuration
settings, and more) after finishing this guide, if necessary.
Remove the local package repository created in this guide:
```posix-terminal
tools/ffx repository server stop
```
```posix-terminal
tools/ffx repository remove fuchsiasamples.com
```
```posix-terminal
tools/ffx repository remove workstation.qemu-x64
```
```posix-terminal
rm -rf ~/.package_repos/sdk-samples
```
Remove the `getting-started` directory and its artifacts:
```posix-terminal
rm -rf ~/getting-started
```
```posix-terminal
bazel shutdown && rm -rf ~/.cache/bazel
```
Other clean up commands:
```posix-terminal
bazel clean --expunge
```
```posix-terminal
killall ffx
```
```posix-terminal
killall pm
```
### Update the firewall rules {:#update-the-firewall-rules}
When you launch the sample component (for instance, using the command
`tools/ffx component run "fuchsia-pkg://fuchsiasamples.com/hello_world#meta/hello_world.cm"`),
you might run into an issue where the command hangs for a long time and
eventually fails with the following error:
```none {:.devsite-disable-click-to-copy}
Lifecycle protocol could not start the component instance: InstanceCannotResolve
```
In that case, you may need to update the firewall rules on your host machine.
If you’re using the `ufw` firewall, run the following commands:
```posix
sudo ufw allow proto tcp from fe80::/10 to any port 8083 comment 'Fuchsia Package Server'
```
```posix
sudo ufw allow proto tcp from fc00::/7 to any port 8083 comment 'Fuchsia Package Server'
```
However, for other non-`ufw`-based firewalls, you will need to ensure that port 8083
is available for the Fuchsia package server.
<!-- Reference links -->
[using-the-sdk]: /docs/development/sdk/index.md
[sdk-bug]: https://bugs.fuchsia.dev/p/fuchsia/issues/entry?template=Bazel
[kvm]: https://www.linux-kvm.org/page/Main_Page
[qemu]: https://www.qemu.org/
[bazel]: https://bazel.build/docs
[git]: https://git-scm.com/
[bazel-install]: https://bazel.build/install
[fuchsia-ssh-keys]: /docs/development/sdk/ffx/create-ssh-keys-for-devices.md
[ticket-01]: https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=97909
[clang]: https://clang.llvm.org/
[fuchsia-idk]: /docs/development/idk/README.md
[fuchsia-package-repo]: /docs/development/sdk/ffx/create-a-package-repository.md
[symbolize-logs]: /docs/development/sdk/ffx/symbolize-logs.md
[fuchsia-component]: /docs/concepts/components/v2/README.md
[fuchsia-debugger]: /docs/development/sdk/ffx/start-the-fuchsia-debugger.md
[zxdb-user-guide]: /docs/development/debugger/README.md
[inspect-overview]: /docs/development/diagnostics/inspect/README.md
[google-test]: https://google.github.io/googletest/
[ffx]: https://fuchsia.dev/reference/tools/sdk/ffx
[fundamentals]: /docs/get-started/sdk/learn/README.md