|
1 | 1 | # pebble.nix
|
2 | 2 |
|
3 |
| -Tools for building Pebble apps on Nix systems |
| 3 | + |
4 | 4 |
|
5 |
| -## Quickstart |
| 5 | +A collection of tools for setting up Pebble app development environments, and building Pebble apps/watchfaces, using |
| 6 | +[Nix](https://nixos.org/). |
6 | 7 |
|
7 |
| -**Recommended:** Install [Cachix](https://cachix.org/) and use the `pebble` |
8 |
| -cache. Using Cachix is highly recommended, as building some required derivations |
9 |
| -(qemu-pebble, the ARM toolchain) locally can take a long time. Cachix provides |
10 |
| -prebuilt, binary backages so you don't have to do the building. |
| 8 | +## Getting Started |
11 | 9 |
|
12 |
| -On non-NixOS systems: |
| 10 | +### Step 1: Install Nix |
| 11 | + |
| 12 | +Nix is the build system that underlies pebble.nix - you'll need to have it installed on your system to use it. There's a |
| 13 | +few ways to install Nix out there - if you don't have an install, I recommend one of the following: |
| 14 | + |
| 15 | +- [Lix Installer](https://lix.systems/install/#on-any-other-linuxmacos-system) |
| 16 | +- [Determinate Nix Installer](https://github.com/DeterminateSystems/nix-installer#install-nix) |
| 17 | + |
| 18 | +There's very little difference between the two - Lix is [a fork of Nix](https://lix.systems/about/) focused on language |
| 19 | +stability and improving the developer experience, while still remaining compatible with upstream Nix (which is what the |
| 20 | +Determinate Nix Installer sets up). pebble.nix fully supports both implementations, so take your pick! |
| 21 | + |
| 22 | +### Step 2: Install Cachix (optional, but recommended) |
| 23 | + |
| 24 | +The job of pebble.nix is to give Nix instructions on how to build and compile all the pieces needed to get a full Pebble |
| 25 | +SDK and developer tool setup. Compiling everything can take a very long time on some systems, so to cut down on initial |
| 26 | +setup time, you can use [Cachix](https://cachix.org) to download prebuilt versions of tools from a binary cache, instead |
| 27 | +of compiling everything on your system. |
| 28 | + |
| 29 | +If you're on NixOS, you can install Cachix through the usual mechanisms there. Otherwise, Cachix can be installed by |
| 30 | +running: |
13 | 31 | ```shell
|
14 |
| -nix-env -i cachix |
| 32 | +nix-env -iA cachix |
15 | 33 | ```
|
16 | 34 |
|
17 |
| -On NixOS, add `cachix` to `environment.systemPackages` in your configuration. |
18 |
| - |
19 |
| -Finally, to use the pebble.nix cache (you might need to run this command with |
20 |
| -`sudo` if your user isn't a trusted user in the Nix daemon): |
| 35 | +Once it's installed, you'll need to use it to add the binary cache to your Nix setup. On non-NixOS systems, you just |
| 36 | +need to run the following command: |
21 | 37 | ```shell
|
22 | 38 | cachix use pebble
|
23 | 39 | ```
|
24 | 40 |
|
25 |
| -After setting up Cachix, reboot the system. This is required to restart the Nix |
26 |
| -daemon so that it uses the new binary cache. |
| 41 | +On NixOS systems, that command will add the cache to your NixOS configuration - make sure you rebuild the system for the |
| 42 | +change to take effect. |
27 | 43 |
|
28 |
| -### Development Shell |
| 44 | +### Step 3: Create a new project |
29 | 45 |
|
30 |
| -A development shell provides you with a shell containing the `pebble` tool and |
31 |
| -the Pebble emulator. To set it up in your project, create a `shell.nix` file |
32 |
| -with the following content in the root of your project: |
| 46 | +Normally, to create a new Pebble project, you'd run `pebble new-project <name>`. But we don't have the Pebble tools |
| 47 | +installed yet - instead, we need to run the Pebble tool from pebble.nix. `nix run` allows you to run any program in a |
| 48 | +Nix derivation defined in a GitHub repo without installing it - we can use it to bootstrap a new project. In the folder |
| 49 | +you want to keep your project in, run the following command: |
33 | 50 |
|
34 |
| -```nix |
35 |
| -(import |
36 |
| - (builtins.fetchTarball https://github.com/Sorixelle/pebble.nix/archive/main.tar.gz) |
37 |
| -).pebbleEnv { } |
| 51 | +```shell |
| 52 | +nix run github:Sorixelle/pebble.nix#pebble-tool -- new-project <project name> |
38 | 53 | ```
|
39 | 54 |
|
40 |
| -Then, run `nix-shell` to open up a shell with all the tools for Pebble |
41 |
| -development. |
| 55 | +You now have a new Pebble app project, in a folder with the same name as the project name! The `nix run` command |
| 56 | +effectively acts as a substitute for the `pebble` command, where everything after `--` gets passed as arguments to |
| 57 | +`pebble`. For example, if you wanted to list all the available Pebble SDK versions, you could run: |
42 | 58 |
|
43 |
| -### Build for App Store |
44 |
| - |
45 |
| -`pebble.nix` can build your watchapp or watchface, and package it in a bundle |
46 |
| -ready for deployment to the Rebble App Store. Create a `default.nix` file in the |
47 |
| -root of your project with the following content, and change the properties for |
48 |
| -your project: |
49 |
| - |
50 |
| -```nix |
51 |
| -(import |
52 |
| - (builtins.fetchTarball https://github.com/Sorixelle/pebble.nix/archive/main.tar.gz) |
53 |
| -).buildPebbleApp { |
54 |
| - name = "App Name"; |
55 |
| - src = ./.; |
56 |
| - type = "watchface"; |
57 |
| -
|
58 |
| - description = '' |
59 |
| - Your app description here. |
60 |
| - ''; |
61 |
| -
|
62 |
| - releaseNotes = '' |
63 |
| - Initial release. |
64 |
| - ''; |
65 |
| -
|
66 |
| - screenshots = { |
67 |
| - aplite = [ "assets/screenshots/aplite/screenshot.png" ]; |
68 |
| - basalt = [ "assets/screenshots/basalt/screenshot.png" ]; |
69 |
| - chalk = [ "assets/screenshots/chalk/screenshot.png" ]; |
70 |
| - diorite = [ "assets/screenshots/diorite/screenshot.png" ]; |
71 |
| - }; |
72 |
| -} |
| 59 | +```shell |
| 60 | +nix run github:Sorixelle/pebble.nix#pebble-tool -- sdk list |
73 | 61 | ```
|
74 | 62 |
|
75 |
| -To build the bundle, run `nix-build`. The bundle will be output to |
76 |
| -`result/appstore-bundle.tar.gz`. |
| 63 | +Having to type out that full command every time is a bit annoying, though. Also, trying to build the app doesn't work, |
| 64 | +since there's no ARM compiler setup. We can fix both of those problems by using a development shell. |
77 | 65 |
|
78 |
| -### Flake Support |
| 66 | +### Step 4: Create a development shell |
79 | 67 |
|
80 |
| -`pebble.nix` can be consumed as a flake, if you're using flakes in your project. |
81 |
| -You can use it with a `flake.nix` similar to the following: |
| 68 | +Development shells are a feature of Nix, that let you specify a list of packages that you want to temporarily install. |
| 69 | +You can then "enter" that development shell by running `nix develop`, which will run a new shell process that has all of |
| 70 | +the packages you specified installed and ready to use. As soon as you `exit` the development shell, all those packages |
| 71 | +are removed from your shell session, until you enter the development shell again. |
82 | 72 |
|
| 73 | +In Nix, development shells are specified in a flake. Without going into too much detail, a flake is a `flake.nix` file |
| 74 | +at the root of your project that defines all the Nix-related bits of your project - the development shell, any Nix |
| 75 | +packages you create, plus a bunch of other things that aren't important to us. What we want is a development shell that |
| 76 | +has everything we'll want when writing a Pebble app. pebble.nix has a function called `pebbleEnv` that has all of that |
| 77 | +stuff included - we just need to create a flake that tells Nix to use `pebbleEnv` for our project's devshell. |
| 78 | + |
| 79 | +Paste the following into a file at the root of your project, called `flake.nix`: |
83 | 80 | ```nix
|
84 | 81 | {
|
85 |
| - inputs.pebble.url = github:Sorixelle/pebble.nix; |
86 |
| -
|
87 |
| - outputs = { self, pebble }: { |
88 |
| - devShell.${system} = pebble.pebbleEnv.${system} { }; |
89 |
| -
|
90 |
| - defaultPackage.${system} = pebble.buildPebbleApp.${system} { ... }; |
| 82 | + inputs = { |
| 83 | + pebble.url = "github:Sorixelle/pebble.nix"; |
| 84 | + flake-utils.url = "github:numtide/flake-utils"; |
91 | 85 | };
|
| 86 | +
|
| 87 | + outputs = |
| 88 | + { pebble, flake-utils, ... }: |
| 89 | + flake-utils.lib.eachDefaultSystem (system: { |
| 90 | + devShell = pebble.pebbleEnv.${system} { }; |
| 91 | + }); |
92 | 92 | }
|
93 | 93 | ```
|
94 | 94 |
|
95 |
| -### Pinning |
| 95 | +Once that file is created, run `nix develop` in the project. You'll be dropped into a new shell session, that has |
| 96 | +everything you need to build Pebble apps - the `pebble` tool, the emulator, and an ARM compiler! You can use the |
| 97 | +`pebble` tool exactly like you would in a normal install while you're in here. |
| 98 | + |
| 99 | +You'll notice a `flake.lock` file was created after running `nix develop`. That file makes sure none of the flake's |
| 100 | +inputs (such as pebble.nix) update out of nowhere and potentially break your setup, similarly to things like npm's |
| 101 | +`package-lock.json`. If you do want to update, you can use `nix flake update` to get the latest versions of your flake's |
| 102 | +inputs. If you make a Git repo in your project, don't forget to commit the `flake.lock` file! |
| 103 | + |
| 104 | +### Step 5: Setup nix-direnv (optional, but recommended) |
| 105 | + |
| 106 | +Having to run `nix develop` every time you want to use the Pebble tools is a bit annoying. In the Nix ecosystem, there's |
| 107 | +a tool called [direnv](https://direnv.net/) that automatically sets up environment variables when you `cd` into a |
| 108 | +directory. [nix-direnv](https://github.com/nix-community/nix-direnv) integrates direnv with Nix development shells, |
| 109 | +letting you enter and exit a development shell just by `cd`ing in and out of the folder - no more forgetting to `nix |
| 110 | +develop`! |
| 111 | + |
| 112 | +First, setup direnv using their [install guide](https://direnv.net/docs/installation.html) (don't forget the shell hook |
| 113 | +step!). Once it's setup, we can create a `.envrc` file in our project that tells direnv what to do when we enter the |
| 114 | +directory. We want it to open the development shell, which we can do by pasting the following shell script into the |
| 115 | +file: |
| 116 | +``` shell |
| 117 | +# Make sure nix-direnv is setup |
| 118 | +if ! has nix_direnv_version || ! nix_direnv_version 3.0.6; then |
| 119 | + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.6/direnvrc" "sha256-RYcUJaRMf8oF5LznDrlCXbkOQrywm0HDv1VjYGaJGdM=" |
| 120 | +fi |
| 121 | + |
| 122 | +# Activate the developer shell |
| 123 | +use flake |
| 124 | +``` |
96 | 125 |
|
97 |
| -Using `builtins.fetchTarball` only caches a tarball for an hour by default. If |
98 |
| -you don't want to have to redownload pebble.nix every hour, you can pin to a |
99 |
| -specific commit. |
| 126 | +After saving that file, direnv will prompt you to allow it to run in that folder (it's a security mechanism, to make |
| 127 | +sure you don't unwittingly run potentially malicious code by entering a folder you downloaded with a `.envrc` file) by |
| 128 | +running `direnv allow`. Once done, the development shell will be active, and all the Pebble tools will be ready to go as |
| 129 | +soon as you open your project! |
100 | 130 |
|
101 |
| -```nix |
102 |
| -builtins.fetchTarball { |
103 |
| - # Get the desired commit hash at https://github.com/Sorixelle/pebble.nix/commits |
104 |
| - url = https://github.com/Sorixelle/pebble.nix/archive/<commitHash>.tar.gz; |
105 |
| - # Get the hash by running "nix-prefetch-url --unpack <url>" on the tarball url |
106 |
| - sha256 = "<tarballHash>"; |
107 |
| -} |
108 |
| -``` |
| 131 | +Most code editors have a direnv plugin available (eg. |
| 132 | +[VSCode](https://marketplace.visualstudio.com/items?itemName=mkhl.direnv), [Vim](https://github.com/direnv/direnv.vim), |
| 133 | +[Emacs](https://github.com/wbolster/emacs-direnv)), so you can use the Pebble tools in your editor's integrated |
| 134 | +build/debug support. |
| 135 | + |
| 136 | +### Step 6: Build your project with Nix (optional) |
109 | 137 |
|
110 |
| -This is unnecessary if you're using flakes - flakes pin other flakes |
111 |
| -automatically. |
| 138 | +TODO |
112 | 139 |
|
113 | 140 | ## Usage
|
114 | 141 |
|
115 | 142 | ### Development shells
|
116 | 143 |
|
117 |
| -Development shells can be configured by specifying the following arguments to |
118 |
| -`pebbleEnv`: |
| 144 | +Development shells can be configured by specifying the following arguments to `pebbleEnv`: |
119 | 145 |
|
120 |
| -- `devServerIP`: The default development server IP. You can find this in the |
121 |
| - Pebble app. |
| 146 | +- `devServerIP`: The default development server IP. You can find this in the Pebble app. |
122 | 147 | - `emulatorTarget`: The default target to start the Pebble emulator for.
|
123 |
| -- `cloudPebble`: Whether to connect via a CloudPebble connection. Requires |
124 |
| - logging into Rebble via `pebble login`. |
| 148 | +- `cloudPebble`: Whether to connect via a CloudPebble connection. Requires logging into Rebble via `pebble login`. |
125 | 149 | - `nativeBuildInputs`: Any extra tools to use during development.
|
126 | 150 | - `CFLAGS`: Extra flags to pass to the compiler during app builds.
|
127 | 151 |
|
128 | 152 | ### App Store Builds
|
129 | 153 |
|
130 |
| -`buildPebbleApp` requires a few specific attributes to create the metadata YAML |
131 |
| -file the Rebble App Store uses to create your app's page. |
| 154 | +`buildPebbleApp` requires a few specific attributes to create the metadata YAML file the Rebble App Store uses to create |
| 155 | +your app's page. |
132 | 156 |
|
133 | 157 | - `name`: The name of your app.
|
134 | 158 | - `type`: The type of app. Must be either `watchapp` or `watchface`.
|
135 | 159 | - `description`: A description of your app.
|
136 | 160 | - `releaseNotes`: The release notes for this version of your app.
|
137 |
| -- `category`: The category of your app. Only needed for watchapps. The valid |
138 |
| - values are: |
| 161 | +- `category`: The category of your app. Only needed for watchapps. The valid values are: |
139 | 162 | - Daily
|
140 | 163 | - Tools & Utilities
|
141 | 164 | - Notifications
|
142 | 165 | - Remotes
|
143 | 166 | - Health & Fitness
|
144 | 167 | - Games
|
145 |
| -- `banner`: Path to a 720x320 image that will be displayed as the banner for |
146 |
| - your app. Optional for watchfaces. |
| 168 | +- `banner`: Path to a 720x320 image that will be displayed as the banner for your app. Optional for watchfaces. |
147 | 169 | - `smallIcon`: Path to a 48x48 icon for your app. Optional for watchfaces.
|
148 | 170 | - `largeIcon`: Path to a 144x144 icon for your app. Optional for watchfaces.
|
149 | 171 | - `homepage`: A URL to the homepage for your app. Optional.
|
150 | 172 | - `sourceUrl`: A URL to the source code of your app. Optional.
|
151 |
| -- `screenshots`: An attribute set containing screenshots of your app on Pebble |
152 |
| - watches. Each attribute contains a list of paths to screenshots. At least 1 |
153 |
| - screenshot in total must be provided. The following attributes are valid: |
| 173 | +- `screenshots`: An attribute set containing screenshots of your app on Pebble watches. Each attribute contains a list |
| 174 | + of paths to screenshots. At least 1 screenshot in total must be provided. The following attributes are valid: |
154 | 175 | - `aplite`: Screenshots for the aplite platform (Pebble, Pebble Steel)
|
155 |
| - - `basalt`: Screenshots for the basalt platform (Pebble Time, Pebble Time |
156 |
| - Steel) |
| 176 | + - `basalt`: Screenshots for the basalt platform (Pebble Time, Pebble Time Steel) |
157 | 177 | - `chalk`: Screenshots for the chalk platform (Pebble Time Round)
|
158 | 178 | - `diorite`: Screenshots for the diorite platform (Pebble 2, Pebble 2 HR)
|
159 | 179 | - `all`: Screenshots to be used for all platforms.
|
160 | 180 |
|
161 | 181 | Other options relating to the build process:
|
162 | 182 |
|
163 |
| -- `src`: Path to the project root. Usually `./.` (the same folder your Nix |
164 |
| - expression is in). |
| 183 | +- `src`: Path to the project root. Usually `./.` (the same folder your Nix expression is in). |
165 | 184 | - `nativeBuildInputs`: Any extra tools/dependencies to be used at build time.
|
0 commit comments