| # 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. While `fx clean && fx build` or `fx clean-build` will |
| trigger a full Fuchsia build, it is slow and you should avoid using it. Always |
| ask the user before running `fx clean` or `fx clean-build` and avoid running it |
| as much as possible. |
| |
| To run a test, run `fx test <name of test>`. 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`. You should use the `--dump` |
| argument if you want the command to return immediately and not wait for more |
| logs. |
| |
| 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. |
| |
| Always ask for confirmation before running `fx set` or otherwise changing the |
| users build settings and before running destructive commands like `ffx target |
| flash`. |
| |
| Documentation for Fuchsia is in the `docs/` subdirectory and the |
| `vendor/google/docs/` subdirectory. You should read the documentation if you're |
| struggling with a concept. Additional documentation is at https://fuchsia.dev if |
| the in-tree documentation doesn't solve your problem. |
| |
| 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". |
| |
| **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. |
| |
| ALWAYS prefix your GN labels with `//` on the command-line (e.g. |
| `fx build //path/to:executable`). If you pass an unprefixed path to `fx build` |
| (like `fx build path/to:executable`) it will interpret it as a path relative |
| to the out directory, fail to build the designated target, and fall back to |
| building the entire tree without a specific target, which is a lot slower. |
| |
| ### 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` wraps building, running a package server, and running actual tests. |
| |
| 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 `fx test` fails because there are no devices, prompt the user to |
| either attach a device or start an emulator. Verify that the device is |
| connected using `fx ffx target list`. |
| |
| 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 ...`. |
| |
| ### 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 emu start` will start an emulator using whatever image has been built. |
| You'll need to run `fx build` to generate a fresh image. The `--headless` flag |
| may be necessary for some environments where a graphical desktop is unavailable. |
| |
| `ffx emu stop` will stop the emulator. |
| |
| `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. |
| |
| `ffx inspect show` will dump inspect data from components on the device. |
| |
| ### 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. |
| |
| Note that by default Zircon drops into a panic shell if the kernel panics, but |
| this may be difficult for your shell command harness. Unless you explicitly |
| intend to interact with the panic shell, consider passing |
| `--cmdline kernel.halt-on-panic=true` to get a failing exit code if Zircon |
| panics. |
| |
| ### 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. |
| |
| ### Buganizer |
| |
| Fuchsia tracks bugs and feature requests using Buganizer. If the user has |
| `bugged` installed you can run `bugged help` to learn how to read bug state. |
| |
| ### Fetching Change List (CL) diffs |
| |
| Use `fx fetch-cl-diff --help` to see how to read the diff for a CL. |
| |
| ### Fetching Change List (CL) comments |
| |
| Use `fx fetch-cl-comments --help` to see how to read the comments for a CL. |
| |
| # 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>` |
| |
| * **Search across jiri projects**: To perform a grep search across all |
| jiri projects you can run: |
| * **Command:** `jiri grep <text>`: Search across projects. |
| |
| # 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:** |
| * **Tag:** The subject **must** begin with a `[tag]` to categorize |
| the change. |
| * The tag should be a short keyword relevant to the change's |
| scope (e.g., `[docs]`, `[test]`, `[fidl]`). |
| * Multiple tags can be used for more specificity (e.g., |
| `[net][dhcp]`). |
| * To choose a good tag, check the commit history for the files |
| you are editing. |
| * **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. |
| |
| **Example:** |
| ``` |
| [docs] Add commit message guidelines to GEMINI.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 |
| ``` |