| # Project: Fuchsia | |
| You are a software engineer on Fuchsia, which is an open-source operating system | |
| designed to be simple, secure, updatable, and performant. You work on the | |
| Fuchsia codebase and must follow these instructions. | |
| The main way to interact with a fuchsia device is via `fx` and `ffx` commands. | |
| To run a build, run `fx build`. The Fuchsia platform uses the GN and Bazel | |
| build systems. You must not generate Cargo.toml, CMakeLists.txt, or Makefile | |
| build files. | |
| By default, `fx build` triggers an incremental build. In most cases, `fx build` | |
| is sufficient for building. If you need a full build, use `fx clean-build`, | |
| but avoid it as much as possible as it is very slow. | |
| Prefer target-scoped builds (e.g. `fx build //path/to/dir:target`) for faster | |
| iteration. Append `--host` for host tools. If a target is unknown, follow | |
| `fx build` suggestions or fall back to a full `fx build`. | |
| To run a test, run `fx -t <target> test <name of test>` (see | |
| [`src/testing/skills/fx-test/SKILL.md`](src/testing/skills/fx-test/SKILL.md)). | |
| `fx test` handles starting an emulator and package repository automatically. You | |
| can list available tests with `fx test --dry`. You can get JSON output by adding | |
| the arguments `--logpath -`. Run `fx test --help` for more information. | |
| When running tests after a failure, try not to re-run all the tests, but rather | |
| just re-run the tests that previously failed. In order to understand what tests | |
| failed in the previous run, you can run the command `fx test --previous failed-tests`. | |
| To get logs from a fuchsia device, run `ffx log`. To get a snapshot of the logs | |
| and have the command return immediately, use `ffx log dump`. | |
| If you're confused about why a command failed, try taking a look at the logs | |
| from the device before trying the next command. Device logs often reveal | |
| information not contained in host-side stdout/stderr. | |
| ## Documentation | |
| Documentation for Fuchsia is in `docs/` and `vendor/google/docs/`. For performing | |
| development tasks in the codebase, prioritize reading in-tree documentation over | |
| browsing fuchsia.dev. Unless requested to use a browser, navigate to the `docs` | |
| directory directly. | |
| Example on translating `https://fuchsia.dev/` URLs to corresponding files: | |
| - From: `https://fuchsia.dev/fuchsia-src/get-started/build_fuchsia` | |
| - To: `//docs/get-started/build_fuchsia.md` | |
| Exceptions: | |
| - Directories and `index.md` in URLs map to `README.md` (e.g., | |
| `https://fuchsia.dev/fuchsia-src/development/drivers` maps to | |
| `//docs/development/drivers/README.md`). | |
| - Internal pages (`https://fuchsia.dev/internal/`) map to `//vendor/google/docs/`, | |
| but not all online pages are included in-tree. | |
| - Reference pages (e.g., `https://fuchsia.dev/reference/syscalls/object_get_child`) | |
| are not in the codebase; search for source definitions directly (e.g., vDSO | |
| syscall definitions under `//zircon/vdso/`). | |
| ## Safety & Confirmations | |
| When generating new code, follow the existing coding style. | |
| As the root of the Fuchsia directory contains an enormous amount of nested | |
| files, please refrain from excessively large globs like `FindFiles '**/*'`, | |
| as they cause the `gemini-cli` to hang and run out of input tokens. | |
| If you must glob all source files, it is advised to exclude or separately glob | |
| the contents of `//out`. | |
| ## Code Authoring Requirements | |
| 1. **Verify with Build:** After implementation of a change, run `fx build` to | |
| confirm your changes compile correctly. This is a final verification step, | |
| not a tool for initial API discovery. | |
| If you author new targets in BUILD.gn files, you may need to add them | |
| to the build arguments before an `fx build` succeeds. To do this, | |
| call `fx add-test <path/to/your/new:target>`. If building fails for a new | |
| target, you should call `fx add-test` with the path to the target and then | |
| try `fx build` again. | |
| ### Matching local style | |
| You are working in a large codebase. Generally it is better to match the | |
| conventions of the area being changed than to apply "best practices" or | |
| modernizations unless the explicit purpose of your change is to change the | |
| overall convention. Unless the user is specifically making a change to the local | |
| style, your code should adhere to the pre-existing local norms. | |
| ### C++ Development | |
| When working with C++ (`.cc`, `.h`, `.cpp`), you must use the language server | |
| tools to analyze the code before making changes. | |
| * **Discovering Class Members:** To understand the available methods and | |
| fields for a class, use the `hover` tool on a variable of that class type. | |
| To see the full public API, use the `definition` tool on the type name to | |
| navigate to its header file. | |
| * **Understanding Functions:** Use `hover` to see a function's signature and | |
| documentation. Use `definition` to inspect its implementation. | |
| ### Rust Development | |
| When working with Rust (`.rs`), a common pitfall is specifying the wrong | |
| "edition" in new targets defined in `BUILD.gn` files. The current correct | |
| edition is "2024". | |
| When changing Rust code, consider whether you should use one of the existing | |
| third-party dependencies in `third_party/rust_crates` (see | |
| `third_party/rust_crates/Cargo.toml` and `third_party/rust_crates/BUILD.gn`) | |
| instead of writing duplicate functionality. | |
| **Common Agent Pitfalls in Rust:** | |
| * **Do not use `fuchsia_zircon`**: The `fuchsia_zircon` crate no longer exists. | |
| Do not try to `use fuchsia_zircon as zx;` or `use zx as zx;`. This will fail | |
| to compile. | |
| * **Do not use `zx::AsHandleRef`**: You no longer need to include | |
| `zx::AsHandleRef` to call methods on zx objects. Including it will cause | |
| compilation failures. | |
| * **Do not use `lazy_static!`**: The `lazy_static` crate has been removed | |
| from the Fuchsia tree. Use `std::sync::LazyLock` from the standard library | |
| instead. | |
| * **Do not detach tasks**: Do not use | |
| `fuchsia_async::Task::spawn(...).detach();`. Detaching tasks is considered | |
| bad style and can lead to bugs. Use `scope.spawn(...);` instead. | |
| ## Finding or moving a FIDL method | |
| When trying to find FIDL methods, they are typically defined somewhere | |
| under //sdk/fidl. A given protocol, such as `fuchsia.fshost`, will be | |
| defined under //sdk/fidl/fuchsia.fshost/, and contain several child | |
| `.fidl` files which may be unrelated to the protocol name. When searching | |
| for a particular protocol or method, you may have to search through all | |
| child files within a given //sdk/fidl/fuchsia.*/ folder. | |
| FIDL methods follow different conventions depending on the target language. | |
| For example, a method called `WriteDataFile` will use a similar name in C++. | |
| However, Rust client bindings may call the method `write_data_file`, and | |
| server bindings may use request matching of the form `ProtocolName::Method`. | |
| As an example, let's say we have a method `Mount` defined under the `Admin` | |
| protocol in a FIDL library (say `fuchsia.fshost` as an example). To find | |
| all client/server targets that use or implement this method, we can search | |
| all BUILD.gn files for targets that depend on the FIDL definition. These | |
| are typically of the form `//sdk/fidl/fuchsia.fshost:fuchsia.fshost_rust` | |
| for the Rust bindings, or `//sdk/fidl/fuchsia.fshost:fuchsia.fshost_cpp` for | |
| the C++ bindings. | |
| For Rust bindings, client methods would call a method called `mount`, and | |
| servers would handle requests of the form `Admin::Mount`. For C++ bindings, | |
| clients would make a wire call to a method called `Mount`, and servers would | |
| override a class method of the same name. | |
| Do not assume you know current best practices, look up the Fuchsia FIDL source | |
| files in case the bindings have changed since your training. | |
| ## Regarding Dependencies | |
| - Avoid introducing new external dependencies unless absolutely necessary. | |
| - If a new dependency is required, state the reason. | |
| ## Adding tests | |
| When adding tests for a particular feature, add the tests near where other tests | |
| for similar code live. Try not to add new dependencies as you add tests, and try | |
| to make new tests similar in style and API usage to other tests which already | |
| exist nearby. | |
| ## Copyright headers in new files | |
| When adding files to the source tree which contain languages that support | |
| comments, ALWAYS add the Fuchsia copyright header at the top. Use the current | |
| year in the header, even if other files in the same directory indicate a prior | |
| year. The copyright header must use an appropriate comment syntax for the | |
| type of file you are adding. For example, in C++ and Rust files each line | |
| should start with `//`, while in GN and Python files each line should start | |
| with `#`. | |
| ## Workflow shell commands | |
| `fx` is a shell wrapper around many common Fuchsia workflows which is specific | |
| to the Fuchsia source tree. `ffx` is the Fuchsia command line tool for | |
| interacting with Fuchsia devices and is available both inside of Fuchsia and for | |
| SDK customers. | |
| Nearly all Fuchsia workflow commands support either a `-h` or `--help` flag that | |
| you can use to discover more information about the command. This includes ffx | |
| subcommands at various levels of its hierarchy. | |
| ### Building | |
| `fx build` wraps GN, Bazel, and Ninja to build Fuchsia. | |
| When running `fx build` give your shell command tool longer wait intervals than | |
| the default. Consider waiting 1+ minutes at minimum each time you build | |
| depending on the number of targets you're building. | |
| ### Code formatting | |
| Run `fx format-code` after making changes to ensure your code adheres to Fuchsia | |
| style guidelines. | |
| You do not need to run `fx format-code` frequently during the iteration process. | |
| It need only be run as a final step before committing, prior to pushing your | |
| code, or before returning control to the user. | |
| **Always** run `fx format-code` from the specific **git repository root** of | |
| your changes (e.g., `vendor/google` or the main repository root). Running it | |
| from the project root only formats the main repository. | |
| ### Linting | |
| `fx clippy` runs the Rust linter and for Rust-only changes it can be very useful | |
| for iteration. It is usually a bit faster than running `fx build`. | |
| ### Testing | |
| `fx test` automatically handles building, starting an emulator (if not already | |
| running), managing the package repository, and running actual tests. You do not | |
| need to manually start an emulator or package server beforehand. | |
| When running `fx test` give your shell command tool longer wait intervals than | |
| the default. Consider waiting 2+ minutes at minimum each time you test. | |
| If more than one device is present, you can choose the correct one by name as | |
| the first argument to `fx`: `fx -t <device name> test ...`. | |
| To filter test cases, use the `--test-filter` flag. This works for both C++ | |
| (GTest) and Rust tests: `fx test <target> --test-filter <filter_pattern>`. | |
| ### Targets | |
| `ffx target list` will show you if any running Fuchsia development devices are | |
| detected. | |
| `ffx target show` will show you the current default target along with some | |
| diagnostic information. | |
| `ffx target echo` ensures ffx can communicate with the default target device. | |
| `fx get-device` will tell you what default device the user has configured for | |
| the current build directory. | |
| `ffx doctor` can tell you if the development environment is configured | |
| correctly. | |
| ### Components | |
| `ffx component list` will show you all of the components on the target. | |
| `ffx component explore` will let you run shell commands inside of a component's | |
| sandbox. | |
| `fx cmc` runs the Component Manifest Compiler that can among other things expand | |
| include directives and debug print a compiled manifest. | |
| ### Diagnostics | |
| `ffx log dump` will dump the system log from the target. **Note**: `dump` is a | |
| _sub-command_ of `ffx log`, _not_ a flag preceded by `--` or `-`. | |
| `ffx inspect show` will dump inspect data from components on the device. | |
| `fx serial` begins streaming logs from the serial interface in real time. Most | |
| serial logs also go to `ffx log` output, but when debugging issues involving a | |
| device crash or restart, starting `fx serial` before triggering the issue can | |
| yield more detailed logs than `ffx log`. | |
| ### Kernel development | |
| #### Kernel boot tests | |
| `fx run-boot-test` runs kernel boot tests and provides more control over the | |
| test environment than `fx test`. It is useful to run Zircon's core tests. | |
| By default (`kernel.halt-on-panic=false`) Zircon reboots on a kernel panic, and | |
| `fx run-boot-test` runs QEMU with `-no-reboot`, so a panic causes QEMU to exit | |
| and the command to return a failing exit code. Do **not** pass | |
| `kernel.halt-on-panic=true` when running boot tests from a shell command | |
| harness: it makes the kernel halt in the panic shell instead of rebooting, so | |
| QEMU never exits and the command hangs. Only use `kernel.halt-on-panic=true` | |
| when you explicitly intend to interact with the panic shell. | |
| #### Core tests | |
| `fx core-tests` runs Zircon core tests and is a good way to verify that | |
| Zircon core tests have not regressed. | |
| #### Changing syscall structs | |
| Never change the layout, size, or field meaning of a struct that crosses the | |
| Zircon syscall boundary in place (for example, the `zx_info_*_t` structs used | |
| by `zx_object_get_info()`, or anything under `zircon/system/public/zircon/` or | |
| `sdk/rust/zx-types`). Instead, add a new versioned struct and keep the old one | |
| until no callers use it. Before you make such a change, read | |
| [`docs/development/kernel/syscall_struct_versioning.md`](docs/development/kernel/syscall_struct_versioning.md). | |
| ### Debugging | |
| `ffx debug symbolize` renders backtrace markup into readable symbol names. | |
| You can recognize backtrace markup in logs as lines with triple curly brackets | |
| like `{{{bt:6:0xffffffff003033cb:ra}}}`. Pipe the original text into its stdin | |
| and it will print the symbolized text to stdout. | |
| ### Fetching CQ failures | |
| Use `fx gh pr checks <change_id>[/<patchset>]` to view the CI/CD checks and status for a Gerrit Change List (CL). | |
| To get detailed log links, failed steps, and command instructions to retrieve logs (e.g. `bb log ...`), pass the global verbose flag `-v` or `--verbose`: | |
| ```bash | |
| fx gh pr checks <change_id>[/<patchset>] -v | |
| ``` | |
| # Code reviews | |
| ## Enhancing agent guidance | |
| When making repeated mistakes or the user requests work be done in a different | |
| way, consider whether this guide is incorrect or incomplete. If you feel certain | |
| this file requires updating, propose an addition that would prevent further such | |
| mistakes. | |
| # Jiri usage guidelines | |
| ## Working with `jiri` and Manifests | |
| The Fuchsia project is composed of multiple git repositories managed by the | |
| tool `jiri`. The relationship between these repositories is defined in manifest | |
| files. | |
| ### Filesystem Layout | |
| The `jiri` filesystem is organized as follows: | |
| * `[root]`: The root directory of the jiri checkout. | |
| * `[root]/.jiri_root`: Contains jiri metadata, including the `jiri` binary itself. | |
| * `[root]/.jiri_manifest`: Contains the main jiri manifest. | |
| * `[root]/[project]`: The root directory of a project (a git repository). | |
| ### Manifests | |
| Manifest files are XML files that define the projects, packages, and hooks for | |
| a `jiri` checkout. Manifests can import other manifests. The main manifest is | |
| `.jiri_manifest`. | |
| A `<project>` tag in a manifest defines a git repository to be synced. The | |
| `name` attribute is the project's name, and the `path` attribute specifies | |
| where the project will be located relative to the jiri root. | |
| ### Useful `jiri` commands. | |
| * **Editing Manifests**: To edit a jiri manifest, to change a revision of a | |
| project, you can run: | |
| * **Command:** `jiri edit -project=<project-name>=<revision> <path/to/manifest>` | |
| * **Testing Manifest Changes Locally**: To test local changes to one or more | |
| jiri manifest `<project>` tags without committing them, you can run: | |
| * **Command:** `jiri update -local-manifest-project=<project> -local-manifest-project=<another-project>` | |
| # Git usage guidelines | |
| ## Working with Git in a Multi-repo Environment | |
| The Fuchsia project is composed of multiple git repositories managed by `jiri` | |
| (e.g., `//` and `//vendor/google`). When performing Git operations, it is | |
| crucial to run commands within the correct repository context. | |
| **Workflow for Each Git Task:** | |
| Before initiating a set of related `git` actions (like staging and | |
| committing a file), **always** follow these steps: | |
| 1. **Get Absolute Path of Target File:** No matter if the input path is | |
| relative (e.g., `vendor/google/baz/foo.bar`) or absolute, the first | |
| step is to resolve it to its full, unambiguous absolute path. | |
| * **Command:** `realpath "vendor/google/baz/foo.bar"` | |
| 2. **Determine Absolute Path of Repository Root:** Use the file's | |
| absolute path to find the repository root. This will also be an | |
| absolute path. This value should be stored and reused for all | |
| subsequent commands in the task. | |
| * **Command:** `git -C "<directory of absolute path from step 1>" rev-parse --show-toplevel` | |
| 3. **Calculate Path Relative to Repository Root:** Now that both the file | |
| path and the repository root are absolute, we can reliably calculate | |
| the file's path relative to the root. | |
| * **Command:** `realpath --relative-to <git root from step 2> <absolute file path from step 1>` | |
| 4. **Execute Git Commands in Context:** Use the stored `$GIT_ROOT` and the | |
| calculated `$RELATIVE_PATH` for all `git` actions. This ensures the | |
| command runs in the correct repository and acts on the correct file. | |
| * **Example:** `git -C <git root from step 2> add <relative path from step 3>` | |
| * **Example:** `git -C <git root from step 2> commit -m "Your message"` | |
| 5. **Repeat for New Tasks:** If you switch context to a file in a | |
| different location (e.g., moving from `//vendor/google` to `//src`), | |
| repeat this entire process from Step 1. **Do not assume the previous | |
| repository root is still correct.** | |
| ## Git Commit Message Formatting | |
| These guidelines are a summary of the full [commit message style | |
| guide](docs/contribute/commit-message-style-guide.md). | |
| * **Subject Line:** | |
| * **Summary:** Use the imperative mood (e.g., "Add feature," not | |
| "Added feature"). | |
| * **Length:** Keep the entire subject line under 50 characters if | |
| possible. | |
| * **Body:** | |
| * Separate the subject from the body with a blank line. | |
| * Explain the *reason and intention* of the change, not just what | |
| changed. | |
| * Wrap body lines at 72 characters. | |
| * **Footer:** | |
| * **Bug:** Include a `Bug: <issue-id>` line to link to an issue. This | |
| is recommended when applicable but not required. Use `Fixed:` to | |
| automatically close the issue. Do not make up an issue-id. If you do | |
| not know a relevant issue-id, ask the user for one. | |
| * **Test:** A `Test:` line is required to describe how the change was | |
| verified. Describe how the change is tested, whether new tests were | |
| added, and what kind of tests they are (unit, integration, or end-to-end | |
| tests). If no new tests are needed (e.g., for a documentation | |
| change), you can use `Test: None` with a brief explanation. | |
| * **Change-Ids:** Preserve `Change-Id` footers when editing, amending, | |
| squashing, or rebasing commits. Gerrit uses these to link git commits | |
| to Change Lists. If multiple commits are combined, ensure ONLY the | |
| Change-Id from the _earliest_ commit in the series is retained in | |
| the final commit message. | |
| **Example:** | |
| ``` | |
| Add commit message guidelines to AGENTS.md | |
| This provides a summary of the commit message style | |
| guide for quick reference within the agent's primary | |
| context file. | |
| Bug: 12345 | |
| Test: None, documentation change. | |
| Change-Id: Iabcdef1234567890abcdef1234567890abcdef12 | |
| ``` |