(updated Oct 29, to reflect CLI v1.14.0)
(updated Dec 22, to reflect CLI v1.17.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:
-
To create a package.yaml file suitable for a library (rather than an application) run
~~toit pkg init --pkg
~~ v1.14.0
toit pkg init --project-root .
v1.17.0 -
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
andpixel_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
-
To fetch dependencies to the development machine disk cache, run
toit pkg install
(install is an alias for fetch)
In the src directory:
- 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, theBBQ10Keyboard
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.
-
To create a package.lock, run
toit pkg init --app
-
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. -
Dependencies are fetched to cache by running
toit pkg install
-
From the test directory, run a test:
toit device run fw_keyboard_test.toit
In the examples directory:
-
To create a package.lock, run
toit pkg init --app
-
To populate the dependencies, run
toit pkg install --local --name=fw_keyboard ..
-
Dependencies are fetched to cache by running
toit pkg install
-
Create an .yaml application specification (by hand) for your example code, following the documentation.
-
From the example directory, run the example:
toit device deploy demo.yaml
-
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.