Fuchsia development#
pw_bluetooth_sapphire: Battle-tested Bluetooth with rock-solid reliability
//pw_bluetooth_sapphire/fuchsia currently contains the Fuchsia build
targets for building, running, and testing the bt-host and
bt-hci-virtual packages.
Fuchsia’s Sapphire Bluetooth stack integration uses the bt-host core
package which is built from Pigweed CI, uploaded to CIPD, and rolled
automatically. The bt-host package is assembled into products in any
Fuchsia build which uses Bluetooth. The bt-hci-virtual package is included
in some builds for testing. See bt-host README
for more details on product assembly.
Note
Every bazelisk invocation needs --config=fuchsia whenever the target
is a fuchsia-specific target.
These fuchsia-specific targets are disabled (marked incompatible with the
target platform) by default to avoid polluting/conflicting with non-fuchsia
pigweed builds.
Specifying --config=fuchsia also allows @fuchsia_sdk backends to be
specified for Pigweed dependencies.
Accessing ffx from a Pigweed environment#
The ffx command is available as a subcommand of pw:
pw ffx help
Testing#
Running tests#
First, ensure the emulator is running or hardware running Fuchsia is connected. Then run a test package with:
bazelisk run --config=fuchsia //pw_bluetooth_sapphire/fuchsia/host/l2cap:test_pkg
Flags can also be passed to the test binary:
bazelisk run --config=fuchsia //pw_bluetooth_sapphire/fuchsia/host/l2cap:test_pkg \
-- --gtest_filter="*Example" --severity=DEBUG
Note
If the test is unable to connect to the emulator, run pw ffx target
remove --all first to clean your machine’s target list.
You can also run the presubmit step that will start an emulator and run all tests, but this is slow:
pw presubmit --step bthost_package
Emulator#
To start the emulator, use the following command:
bazelisk run --config=fuchsia @fuchsia_products//:core.x64.emu -- --headless
To stop the running emulator, use the following command:
pw ffx emu stop --all
Building#
Note
See the main Building section for instructions on building for your host machine (producing Linux/macOS test binaries).
To build the bt-host package, use one of the following commands:
bazelisk build --config=fuchsia //pw_bluetooth_sapphire/fuchsia/bt_host:pkg.arm64
bazelisk build --config=fuchsia //pw_bluetooth_sapphire/fuchsia/bt_host:pkg.x64
The bt-host.far package will end up in a Bazel build directory that will be
printed in the command output. For example:
bazel-out/aarch64-fastbuild-e2b/bin/pw_bluetooth_sapphire/fuchsia/bt_host/bt-host.far.
Note that bazel-out is symlinked from the root Pigweed directory.
Deploy to a Fuchsia checkout#
fuchsia.git developers can use the pw bluetooth bt-host-deploy command to
automatically build and deploy the bt-host package and its debug symbols to
a local Fuchsia checkout.
pw bluetooth bt-host-deploy [--local-fuchsia-sdk] [fuchsia_checkout]
If the fuchsia_checkout path is omitted, the command will use the
persistently configured path. This command builds and deploys the
bt-host package and its debug symbols for both arm64 and x64.
Use the --local-fuchsia-sdk flag to build the local Fuchsia SDK (by running
fx build //sdk:final_fuchsia_sdk) and use it for the build. This is
necessary if you have made changes to the Fuchsia SDK itself (e.g., modifying
FIDL definitions in a local fuchsia.git checkout).
You can set the checkout path once using:
pw bluetooth set-fuchsia-checkout /path/to/fuchsia/checkout
This command builds the package and its debug symbols, then copies the package
to the correct prebuilt location in the Fuchsia checkout (e.g.,
//prebuilt/connectivity/bluetooth/bt-host/<arch>/bt-host) and sets the
necessary permissions.
Using a local Fuchsia SDK#
If you are making changes to the Fuchsia SDK itself (e.g., modifying FIDL
definitions in a local fuchsia.git checkout), you should use the
pw bluetooth bt-host-deploy command described in the previous section with
the --local-fuchsia-sdk flag.
This command automatically handles building the local SDK (by running
fx build //sdk:final_fuchsia_sdk), setting the complex Bazel flags required
to override the SDK repository, and setting the Fuchsia API level to HEAD to
ensure experimental features (like those marked @available(added=NEXT)) are
included.
Manual local SDK build (Advanced)#
If you need to build manually with a local SDK without deploying, follow these steps:
Build the SDK in your Fuchsia checkout:
fx build //sdk:final_fuchsia_sdkFind the canonical name of the SDK repository:
bazelisk mod dump_repo_mapping "" | grep fuchsia_sdk | python -m json.tool | jq .fuchsia_sdkOverride the SDK repository and set the API level:
Use the
--override_repositoryflag with the canonical name found in step 2 and an absolute path:bazelisk build --config=fuchsia \ --@fuchsia_sdk//flags:fuchsia_api_level=HEAD \ --override_repository=<CANONICAL_NAME>=/home/user/code/fuchsia/out/default/obj/sdk/final_fuchsia_sdk \ //pw_bluetooth_sapphire/fuchsia/bt_host:pkg.x64
Working with devices#
Inspect#
To query the current state of the bt-host component Inspect hierarchy, run:
pw ffx inspect list | grep bt-hostto find the component’s<moniker>pw ffx inspect show "<moniker>"Note that the full moniker from step 2 should be in quotations, e.g.
pw ffx inspect show "core/bluetooth-core/bt-host-collection\:bt-host_000".Wildcards can be passed into the selector as needed, e.g.
pw ffx inspect show "core/bluetooth-core/bt-host-collection*".
Editor configuration#
Clangd setup#
to enable C/C++ code intelligence in your editor, Generate commands databases
(compile_commands.json) with the following command:
$ bazelisk run //:refresh_compile_commands_for_fuchsia_sdk
This will create a .compile_commands directory with a number of
subdirectories. For example:
k8-fastbuild: The default host configuration (linux), used when you run a test likebazelisk test //pw_status:status_test. For macOS hosts, this is nameddarwin_arm64-fastbuild.k8-opt-exec: Host “exec” configuration. This is used to build tools likeprotocthat are required for various stages of the build. For macOS hosts, this is nameddarwin_arm64-opt-exec.fuchsia_x64-fastbuild-ST-89a3eb73aaef: Code intelligence for Fuchsia targets inpw_bluetooth_sapphire.
Each of these directories provide a different view of the build graph. This
ensures #if conditions and defines correctly match the configuration, giving
you the most accurate code intelligence possible.
Note
Not all configurations cover the same libraries, tests, and binaries. For
example, the //:update_host_googletest_compile_commands command will
cover much more of Pigweed (and pw_bluetooth_proxy), but is configured
specifically for host+Googletest.
Select one of these configurations by directing clangd to use the associated
directory:
--compile-commands-dir=/path/to/pigweed/.compile_commands/fuchsia_x64-fastbuild-ST-89a3eb73aaef
Note
b/469437909 The hex sequence at the end of the Fuchsia platform name is unfortunately unstable, and can change whenever different flags are passed to Bazel.
Infrastructure#
Run Fuchsia presubmit tests#
Presubmits for bt-host are captured in a dedicated separate builder,
pigweed-linux-bazel-bthost, rather than existing ones such as
pigweed-linux-bazel-noenv.
On the builder invocation console, there are a number of useful artifacts for examining the environment during test failures. Here are some notable examples:
bt_host_packagestdout: Combinedstdout/stderrof the entire test orchestration and execution.subrunner.log: Combined teststdout/stderrof test execution only.target.log: Theffxtarget device’s logs.ffx_config.txt: Theffxconfiguration used for provisioning and testing.ffx.log: Theffxhost logs.ffx_daemon.log: Theffxdaemon’s logs.env.dump.txt: The environment variables when test execution started.ssh.log: The SSH logs when communicating with the target device.
These presubmits can be also be replicated locally with the following command:
bazelisk run --config=fuchsia //pw_bluetooth_sapphire/fuchsia:infra.test_all
Note
Existing package servers must be stopped before running this command. To
check for any existing package servers run lsof -i :8083 and make sure
each of those processes are killed.
Note
You do not need to start an emulator beforehand to to run all tests this way. This test target will automatically provision one before running all tests.
Add a test to presubmit#
Fuchsia test packages are those defined with a Fuchsia SDK rule like
fuchsia_unittest_package. All Fuchsia test packages need to be added to the
Fuchsia presubmit step or they will not be tested.
To add new Fuchsia test packages to presubmit, add the test package targets to
//pw_bluetooth_sapphire/fuchsia/BUILD.bazel.
Example:
# pw_bluetooth_sapphire/fuchsia/BUILD.bazel
qemu_tests = [
"//pw_bluetooth_sapphire/fuchsia/bt_host:integration_test_pkg",
...
]
Uploading to CIPD#
Pigweed infrastructure uploads bt-host artifacts to
fuchsia/prebuilt/bt-host and fuchsia/prebuilt/bt-hci-virtual via the
pigweed-linux-bazel-bthost builder by building the top level infra target:
# Ensure all dependencies are built.
bazelisk build --config=fuchsia //pw_bluetooth_sapphire/fuchsia:infra
# Get builder manifest file.
bazelisk build --config=fuchsia --output_groups=builder_manifest //pw_bluetooth_sapphire/fuchsia:infra
The resulting file contains a cipd_manifests JSON field which references a
sequence of JSON files specifying the CIPD package path and package file
contents.
Using Zxdb: the Fuchsia debugger#
Zxdb is a console-mode debugger for native code running on Fuchsia.
To run Zxdb in pw_bluetooth_sapphire:
Start the emulator.
Run:
# Connect to the debugger $ pw ffx debug connect # Attach test package from test output url (e.g. fuchsia-pkg://bazel.test.pkg.publish.anonymous/bt_host_fidl_tests_bazel#meta/fidl_test.cm) $ [zxdb] attach <test-package> (e.g. attach fidl_test.cm) # Set a breakpoint $ [zxdb] break <file.cc>:<line-number> (e.g. break fidl/profile_server.cc:384)
Run your test in a new terminal:
$ bazelisk run --config=fuchsia //pw_bluetooth_sapphire/fuchsia/host/fidl:test_pkg
Once you have successfully connected to the debugger, see further capabilities.