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:
- Perry compiler —
cargo build --release -p perry - Perry stdlib —
cargo build --release -p perry-stdlib - Perry UI library —
cargo build --release -p perry-ui-macos(or target platform) - FFI crates — Build the native crates in
hone-editor/native/andhone-terminal/native/ - Hone packages —
perry compileeach 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).