Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Building Perry

Perry is the TypeScript-to-native AOT compiler that powers Hone. It lives in a sibling directory (../perry/) and is written in Rust. This page covers building Perry itself and using it to compile Hone packages.

Prerequisites

  • Rust toolchain (install via rustup)
  • Xcode Command Line Tools (macOS) for the system linker
  • The Perry source at ../perry/ relative to the Hone repo root

Building Perry Components

The Perry Compiler

cd ../perry && CARGO_PROFILE_RELEASE_LTO=off cargo build --release -p perry

This produces the perry binary used to compile TypeScript to native code.

Perry UI Library (macOS)

cd ../perry && CARGO_PROFILE_RELEASE_LTO=off cargo build --release -p perry-ui-macos

Required for compiling any package that renders UI on macOS (hone-ide, hone-editor).

Perry Standard Library

Rebuild after changing perry-runtime source:

cd ../perry && cargo clean -p perry-runtime --release && \
  CARGO_PROFILE_RELEASE_LTO=off cargo build --release -p perry-stdlib -p perry-ui-macos -p perry

The cargo clean step is necessary because Cargo may not detect changes to the runtime’s generated code.

LTO Warning

Always use CARGO_PROFILE_RELEASE_LTO=off for all Perry Rust builds. Without this flag, Cargo defaults to thin LTO, which produces LLVM bitcode that the macOS clang linker cannot read. The build will succeed but linking Hone packages will fail with cryptic errors.

You can also set this permanently in ../perry/.cargo/config.toml:

[profile.release]
lto = false

Compiling Hone Packages

Once Perry is built, use it to compile Hone’s TypeScript packages into native binaries.

IDE

# macOS native binary
cd hone-ide && perry compile src/app.ts --output hone-ide

# iOS Simulator
cd hone-ide && perry compile src/app.ts --target ios-simulator --output Hone

# Web (WASM)
cd hone-ide && perry compile src/app.ts --target web --output hone-ide.html

Auth Server

cd hone-auth && perry compile src/app.ts --output hone-auth

Produces a ~2.8MB static binary with no runtime dependencies.

Marketplace

cd hone-marketplace && perry compile src/app.ts --output hone-marketplace

Build Server

cd hone-build && perry compile src/app.ts --output hone-build

Build Order

When building everything from scratch:

  1. Perry compilercargo build --release -p perry
  2. Perry stdlibcargo build --release -p perry-stdlib
  3. Perry UI librarycargo build --release -p perry-ui-macos (or target platform)
  4. FFI crates — Build the native crates in hone-editor/native/ and hone-terminal/native/
  5. Hone packagesperry compile each package

Steps 1-3 only need to be repeated when Perry itself changes. Step 4 is needed when FFI code changes. Step 5 is the normal development cycle.

Troubleshooting

“unknown file type” linker error: You forgot CARGO_PROFILE_RELEASE_LTO=off. Rebuild Perry with LTO disabled.

“undefined symbol _wrapper*” linker error: A function declared in package.json under perry.nativeLibrary.functions is not exported by the Rust FFI crate. Check that the #[no_mangle] pub extern "C" fn __wrapper_<name> exists and matches exactly.

“verifier error” during compilation: An FFI function uses i32 parameters. Change them to f64 (numbers) or i64 (strings/pointers).