tree: e17e6b315717fdf6894fde3c2a970c6f580c4e05 [path history] [tgz]
  1. backends/
  2. cmd/
  3. scripts/
  4. testdata/
  6. c_family.go
  7. names.go
  9. readme.go
  11. zither_golden_files.gni
  12. zither_ir.go
  13. zither_ir_test.go
  14. zither_library.gni


zither is a collection of FIDL backends busyboxed into a single tool. These backends are united around two related aims: to aide in the modeling of memory formats in FIDL - especially those of significance to the Fuchsia platform (e.g., syscall and ZBI data layouts) - streamlining their use among supported platform languages; to generate various transformations of the syscall interface for the purposes of the interface's definition in the kernel, the vDSO, in documentation, as well as in various tooling contexts.


fx run-in-build-dir $(fx list-build-artifacts --expect-one --name zither tools) --help

for information on zither's command line interface.

Supported backends

The supported backends correspond to top-level subdirectories under backends/, each defining a package of the name${name}. The main export of each such package is a function, NewGenerator(), that creates a type implementing the following interface, defined in zither's main:

// generator represents an abstract generator of bindings.
type generator interface {
  // DeclOrder gives the declaration order desired by the backend.
  DeclOrder() zither.DeclOrder

  // DeclCallback is a callback intended to be passed to zither.Summarize()
  // which will be called on each Decl in topological 'dependency' order. This
  // can be used to build up additional, backend-specific information during
  // the main phase of FIDL declaration processing.
  DeclCallback() func(zither.Decl)

  // Generate generates bindings into the provided output directory, returning
  // the list of outputs emitted.
  Generate(summary zither.LibrarySummary, outputDir string) ([]string, error)

See backends/${name}/ for more information about a particular backend.


zither's testing strategy is three-fold.

Build-time golden tests

We run golden tests at build-time, leveraging the golden_files() GN machinery. Executing tests at build-time can be significantly more convenient than at runtime: ninja executes them with maximal parallelism, testing is a side-effect of building and not something that requires complex packaging - and GN specification - of golden and generated files (which will quickly grow to be quite numerous). Per the underling machinery, the update of golden files will occur automatically during building if the update_goldens GN arg is set (which is highly recommended) or otherwise via cp commands emitted in build failures. The updating in either case can be streamlined by fx check-goldens.

An individual test cases correspond to a test FIDL library, for which the goldens are the generated outputs for each appropriate zither backend. The test cases and goldens are organized as follows, under the testdata subdirectory:

testdata/<case name>/
    <case library `zither.${case_name}` (with s/_/.)>

        <backend name>/
            <the files generated by this backend from the associated library>

Note that since underscores are not a permitted within a FIDL library name, we expect to derive a library name from a case name with a substitution of ‘_’ with ‘.’.

See zither_golden_test() for how a test case is specified.

Compilation integration tests

Testing that code was emitted as expected can only be part of the strategy; one needs to further verify that the generated code is actually valid and compiles. This is covered by another form of build-time testing that aims to do exactly that for each of the supported backends. This happens automatically in zither_golden_test() instances.

Basic unit-testing

Finally, pieces of the generation logic of sufficient modularity and complexity will be conventionally unit-tested. This in particular includes the translation from FIDL‘s IR to another of zither’s.