Files
cell/help/cellstructure.md
2025-12-09 23:19:25 -06:00

4.9 KiB

Cell structure

Cell doesn't have the notion of a file system; it has packages. Each package is a directory with a cell.toml file. You cannot have nested packages.

A package is a collection of actors, modules, and other files.

Packages are stored in a cell shop, in a development environment, located at ~/.cell.

Inside the shop there is .cell/packages/

A package can be a gitea url, like gitea.pockle.world/john/prosperon, which effectively clones to ~/.cell/packages/gitea.pockle.world/john/prosperon

Or it can be a local absolute path (on computers with a file system), like .cell/packages/User/john/work/prosperon, which is a symlink to the actual directory.

Cell itself is stored as a package in .cell/packages/, where is specified in shop.toml (e.g., core = "bootstrap" for local development, or core = "gitea.pockle.world/john/cell" for a remote package). Updating cell involves getting cell from somewhere, and rebuilding it. The cell core is itself a package.

When an actor or module is requested, it's loaded first from the package, if not found, it checks in packages (via aliases in cell.toml dependencies), and if not found there, it checks in the core package.

Packages can declare aliases for packages, so the "accio" package can say "prosperon = gitea.pockle.world/john/prosperon", and then load "prosperon/sprite". A module in prosperon can simply load "sprite" to load its own sprite.

the "cell upgrade" command is a command to upgrade the cell version in a shop.

commands

cell update - update all packages in the shop, and builds their code for local use cell install - install a package cell remove - remove a package cell build - build the package in the current directory into a cell executable cell version - the version of cell being used

building

cell builds itself from source on your compuer!

all source for every single part of a cell program are located in the cell shop.

the cell shop looks like this: .cell packages core <--- this is the core cell gitea.pockle.world/john/cell <---- core contents. this is linked to core gitea.pockle.world/john/prosperon cell.toml <--- the manifest of the package mod1.cm mod2.cm actor1.ce addon.c <--- a C file for compiling into the cell executable etc gitea.pockle.world/john/accio /Users/john/work/prosperon ... link.toml - temporary links for this cell shop lock.toml - manifest of installed packages lib cache build - content addressed hash fajfola214o12 90823tjoag ...

getting a module or actor

When a module <name/mod> is requested, from a within package ..

  1. cell looks within package for a folder and loads <name/mod>, if present
  2. cell looks for a package with a top level
  3. cell looks in the core for <name/mod>

The core can be set and have something else linked into it, if you want to break your cell build

cell build

cell build compiles all c into the appropriate binaries. All object files are stored in the .cell/cache

there are two ways to build a cell program: as a shared library, or as a static binary.

Cell script files are simply compiled into built objects

Then, all C files in the package are compiled.

If you have a file like fd.c and fd_playdate.c, that is a signal to cell to compile fd.c usually, but then for the playdate target, compile fd_playdate.c instead.

files name "main.c" are not compiled.

each cell.toml in a package

shared library

this is more suitable for development. firstly, the cell core must build a shared library for the platform.

Then, each package compiles, linking to the cell core shared library. Modules are written to include the cell core headers.

Shared libraries are stored in the build directory, hashed with the content hash

When update is run, it copies the dynamic libraries into .cell/shared, with their package name; ie, the dynamic library for the gitea.pockle.world/john/prosperon would be at .cell/shared/gitea_pockle_world_john_prosperon.dylib.

There will be commands to gather them all together; so you can request "all dylibs for platform x", and it will give you a folder of them.

bootstrapping cell

after the cell shared libraries are all compiled, the main.c of the cell core is compiled against the cell core shared library, creating a thin cell runner. However, even on subsequent updates to cell, this runner is not updated; only for bootstrapping.

static binary

For static binaries, rather than going through and compiling each dynamic library for a package, a static binary is created for a particular package, based on its dependencies. All C symbols, plus the main.c runner from the cell core, are packaged into one binary. It works just like the basic cell program.

However, you can also specify an entry point for this binary, for example, a particular actor. When the binary is run, that particular actor runs.