(updated Oct 29, to reflect CLI v1.14.0)

I have written a couple of toy applications in Toit and wanted to create a library for the Solder Party Keyboard FeatherWing. Following the Package quick start guidance I could not get the source to compile. The Toit team responded on Slack and got me going, so although the Toit documentation should be considered definitive, the following notes may be useful to some.

The error I made was creating and editing the .yaml and .lock files by hand!
There are at least two problems with this:

  • the Package Manager is not invoked to setup the local cache directories
  • subtle spelling/hypenation/dash mistakes result in frustrating, hard to see “Package .. not found” or “Unresolved identifier” compilation errors

So the .yaml and .lock files and the hidden .packages directories (under project root, examples and tests) were deleted and I started over using the toit pkg CLI tool, as follows.

Refering to the repository FW_Keyboard
With the erroneous files deleted, the initial code layout looked like:

fw_keyboard
|
├── CHANGELOG.md
├── examples
│   └── terminal_demo.toit
├── LICENSE
├── README.md
├── src
│   ├── bbq10keyboard.toit
│   ├── events.toit
│   └── fw_keyboard.toit
└── tests
    ├── fw_display_test.toit
    └── fw_keyboard_test.toit

In the project root directory:

1) To create a package.yaml file suitable for a library (rather than an application) run
toit pkg init --pkg

2) To declare the external dependencies of the library src code, run
toit pkg install color-tft
toit pkg install pixel-display
(these are shortcuts for
toit pkg install github.com/toitware/toit-color-tft
toit pkg install github.com/toitware/toit-pixel-display
and works because there are no ambiguities)

This yields a package.yaml file in the root as:

   dependencies:
   color_tft:
       url: github.com/toitware/toit-color-tft
       version: ^1.1.0
   pixel_display:
       url: github.com/toitware/toit-pixel-display
       version: ^1.2.0

The named dependencies color_tft and pixel_display correspond to the imports in the library src, so for example in the src/fw_keyboard.toit file:

   import color_tft show ColorTft COLOR_TFT_16_BIT_MODE
   import pixel_display show TrueColorPixelDisplay

3) To fetch dependencies to the development machine disk cache, run
toit pkg install (install is an alias for fetch)

In the src directory:

4) No toit pkg actions are required.
External library dependencies are already captured in the project root package.yaml file.
Dependencies between files in the library, are captured by convention of the import statements.
For example, in fw_keyboard.toit, the BBQ10Keyboard class is imported by:
import .bbq10keyboard show BBQ10Keyboard
The compiler looks in src for a file named bbq10keyboard.toit

In the tests directory:

The tests directory contains code meant to test your library and would not be called by other developers. As application code, a package.lock file is required and is specific to the directory.

5) To create a package.lock, run
toit pkg init --app

6) To populate the dependencies, run
toit pkg install --local --name=fw_keyboard ..
toit pkg install color-tft
toit pkg install pixel-display
Dependency to the library code under construction is declared in the first line.
Dependencies to external graphics libraries is declared in the next lines, as might dependencies to say a test framework.

7) Dependencies are fetched to cache by running
toit pkg install

8) From the test directory, run a test:
toit device run fw_keyboard_test.toit

In the examples directory:

9) To create a package.lock, run
toit pkg init --app

10) To populate the dependencies, run
toit pkg install --local --name=fw_keyboard ..

11) Dependencies are fetched to cache by running
toit pkg install

12) Create an .yaml application specification (by hand) for your example code, following the documentation.

13) From the example directory, run the example:
toit device deploy demo.yaml

14) Add a .gitignore file in the project root directory, as the (hidden) package directories must not versioned into the repository. Looks like:

.packages/
examples/.packages
tests/.packages

The final library code structure looks like:

.
├── CHANGELOG.md
├── examples
│   ├── terminal_demo.toit
│   ├── demo.yaml           <-- created in 12
│   ├── package.lock        <-- created in 9, populated in 10
│   ├── .packages           <-- created in 9 (truncated view)
│   └── package.yaml
├── .gitignore              <-- created in 14
├── LICENSE
├── package.lock
├── .packages               <-- created in 1 (truncated view)
│   ├── github.com
│   └── README.md
├── package.yaml            <-- created in 1, populated in 2
├── README.md
├── src
│   ├── bbq10keyboard.toit
│   ├── events.toit
│   ├── fw_keyboard.toit
│   └── touch_controller.toit
└── tests
    ├── fw_display_test.toit
    ├── fw_keyboard_test.toit
    ├── package.lock        <-- created in 5, populated in 6
    ├── .packages           <-- created in 5 (truncated view)
    └── package.yaml

The code compiles and runs.

Lesson learned … use the Toit Package Manager, toit pkg, as you layout your project and declare code dependencies.