This doc will guide you through some of the features of
ffx. For an overview
of the design and components of
ffx, see the ffx overview.
Contacting the ffx team
If you discover possible bugs or have questions or suggestions, file a bug.
To follow the examples in this doc, you'll need a Fuchsia device running. If you
don't have a physical device connected, you can use an emulator with networking
Tip: To start a headless emulator, run
fx emu --headless --software-gpu -N.
Your device must be running a
or a product configuration that extends
core (such as
Optionally, you can run
fx log, which will provide some additional information
about the interactions between
ffx and your Fuchsia target device.
After following all the prerequisites, run the following in a terminal:
fx ffx help
This will list all of the available
ffx subcommands. You'll see something
Usage: ffx [-c <config>] [-e <env>] [-t <target>] [<command>] [<args>] Fuchsia's developer tool Options: -c, --config override default configuration -e, --env override default environment settings -t, --target apply operations across single or multiple targets --help display usage information Commands: component Discover and manage components config View and switch default and user configurations daemon Interact with/control the ffx daemon diagnostic Run diagnostic tests on Fuchsia targets docs View suite of docs for ffx and for Fuchsia doctor Run common checks for the ffx tool and host environment emulator Start and manage Fuchsia emulators overnet Interact with the Overnet mesh package Create and publish Fuchsia packages sdk Modify or query the installed SDKs target Interact with a target device or emulator vendor Run partner plugins version Print out ffx tool and daemon versions
You can use
fx ffx help <subcommand> or
fx ffx <subcommand> --help to see
more about any subcommand.
Interacting with target devices
In a terminal, run the following:
fx ffx target list
You'll see a list of devices that
ffx has discovered. For example, with a
single emulator running, output looks like:
NAME TYPE STATE ADDRS/IP AGE CS fuchsia-5254-0063-5e7a Unknown Unknown [fe80::5054:ff:fe63:5e7a%4] 0m0s N
NOTE: Ignore the
STATE columns - they have no values besides
UNKNOWN right now.
A couple of columns are worth explanation:
AGE: This is the time since
ffxwas last able to reach the device.
RCS: Indicates whether there is a reachable instance of the Remote Control Service (RCS) running on the device.
In order to get
ffx to automatically connect to a device, you must either have
set the target's nodename to be the default target, or attempt to interact with the
To set the target to be the default, run:
fx ffx target default set $NODENAME
If the default target has been set prior to starting the daemon, waiting a few seconds
should yield a change to the
RCS status to show
If the default target has been set after starting the daemon, attempting to interact with the target should be sufficient to kick off a connection, like the following
fx ffx component list
NOTE: if the default target has been set, and you are unable to run that command
against the target, reach out to the
Then the next time you list targets you should see that an
$ fx ffx target list NAME TYPE STATE ADDRS/IP AGE RCS fuchsia-5254-0063-5e7a Unknown Unknown [fe80::5054:ff:fe63:5e7a%4] 0m6s Y
If a target has been set as default there will be a
* next to it.
If you had
fx log running, you should also see something like the following in
[00009.776170][remote-control, remote_control_bin] INFO: published remote control service to overnet
NOTE: if the
RCS column remains
N for an extended amount of time and you have
already set this target's nodename to
target.default before initially starting
ffx, reach out to the
On Default Targets
Above we covered setting the default target using the command
fx ffx target default set
It is also possible to set the default target on a per-command basis using the
--target flag like so.
fx ffx --target $NODENAME component list
Interacting with multiple devices
TODO: fill this out.
Controlling the state of target devices
You can use the
target off and
target reboot subcommands to power-off or
reboot a device, respectively.
See documentation for the config command.
Interacting with Components
ffx commands that use components take selectors as a parameter. You can read more about selectors and their syntax
in component selector documentation.
Inspecting the component topology
You can use the
component select command to
* inspect services in the
* search for components that expose a service.
For example, the following command will display all services offered by components v1 :
$ fx ffx component select moniker 'core/appmgr:out:*'` core/appmgr | --out | --chromium.cast.ApplicationConfigManager --fuchsia.bluetooth.avrcp.PeerManager --fuchsia.bluetooth.avrcp.test.PeerManagerExt --fuchsia.bluetooth.bredr.Profile --fuchsia.bluetooth.control.Control --fuchsia.bluetooth.gatt.Server --fuchsia.bluetooth.le.Central --fuchsia.bluetooth.le.Peripheral --fuchsia.bluetooth.snoop.Snoop --fuchsia.bluetooth.sys.Access --fuchsia.bluetooth.sys.HostWatcher --fuchsia.boot.Arguments --fuchsia.boot.FactoryItems --fuchsia.boot.Items --fuchsia.boot.ReadOnlyLog --fuchsia.boot.RootJobForInspect --fuchsia.boot.RootResource [truncated]
The following command will display all components that expose
$ fx ffx component select capability diagnostics ./bootstrap/archivist ./bootstrap/driver_manager ./bootstrap/fshost ./bootstrap/power_manager ./core/appmgr ./core/detect ./core/last_reboot ./core/log-stats ./core/pkg-cache ./core/sampler ./core/system-update-committer
Verifying a service is up
You can use the
component knock command to verify that a service starts
knock will open a channel to the service and return success if
and only if the channel isn't closed.
The component framework will start the component that provides the service on-demand.
$ fx ffx component knock 'core/appmgr:out:fuchsia.hwinfo.P*' Success: service is up. Connected to 'core/appmgr:out:fuchsia.hwinfo.Product'. $ fx ffx component knock 'core/appmgr:out:not.a.real.service' Failed to connect to service: NoMatchingServices
Running a CML component
ffx can run CML components in an isolated realm given their package URL. Currently, this isolated
realm provides the following capabilities:
devdirectory: the root device tree of the system
bootdirectory: the full bootfs filesystem used by the system during bootup
CML components are run with the
ffx component run subcommand. These components are automatically
destroyed when they stop.
Here's an example of running the Rust hello-world component. First, you'll need the hello-world package in your universe:
$ fx set <product>.<board> --with //examples/hello_world/rust:hello-world-rust && fx build ... $ fx ffx component run fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world-rust.cm Created component instance: hello-world-rust ... $ fx ffx component show hello-world-rust Moniker: ./core/ffx-laboratory:hello-world-rust URL: fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world-rust.cm Type: v2 dynamic component Execution State: Running Job ID: 50775 Process ID: 50819 ...
Running a CMX component
ffx can run CMX components on a device given their package URL and arguments.
CMX components are run with the
ffx component run-legacy subcommand.
be streamed to the corresponding descriptor on the host terminal.
Here's an example of running the Dart hello-world component. First, you'll need the hello-world package in your universe:
$ fx set <product>.<board> --with //examples/hello_world && fx build ... $ fx ffx component run-legacy fuchsia-pkg://fuchsia.com/hello-world#meta/hello-world-dart.cmx Hello, world!
Resolving connectivity issues
If you're experiencing problems communicating with a target device using
you can use the
doctor command to diagnose and attempt to resolve them. If you
file a bug that involves a target device, we'll typically ask for the output
ffx doctor to provide information about where the problem is.
doctor will attempt to communicate with the ffx daemon, killing
and restarting it if needed. If this is successful, it will attempt to SSH into
a target device and start the Remote Control Service.
If you try running
ffx doctor under normal circumstances, you should see:
$ fx ffx doctor Checking for a running daemon...none running. Attempting to kill any zombie daemons...killed at least one daemon. Starting a new daemon instance...success Attempting to connect to the daemon. This may take a couple seconds...success Attempting to communicate with the daemon...success Attempting to list targets...success Attempting to get an RCS connection...success Attempting to communicate with RCS...success SUCCESS. You should be able to run ffx commands now.
doctor fails, it will try to suggest a resolution to the problem. It will
also provide a link to the Monorail component in which you can file a bug if you
persistently have problems. For example, if
doctor is unable to start the RCS,
you would see the following:
$ fx ffx doctor Checking for a running daemon...found Attempting to connect to the daemon. This may take a couple seconds...success Attempting to communicate with the daemon...success Attempting to list targets...success Attempting to get an RCS connection...success Attempting to communicate with RCS...FAILED. Timed out. Attempt 2 of 3 Attempting to list targets...success Attempting to get an RCS connection...success Attempting to communicate with RCS...FAILED. Timed out. Attempt 3 of 3 Attempting to list targets...success Attempting to get an RCS connection...success Attempting to communicate with RCS...FAILED. Timed out. Connecting to RCS failed after maximum attempts. To resolve this issue, try rebooting your device. If this persists, please file a bug at the link below and include 1) all output above and 2) device syslog if available.Bug link: ...