Building from source
One Rust workspace: one command to build, one command to test, and a packaging script or command for each platform.
Requirements
- Rust
- 1.97.1, 2024 edition. The version is pinned by
rust-toolchain.tomlat the repository root, and local builds, continuous integration and release builds all use it; with rustup installed, it is picked up as you enter the repository. - A C toolchain
- The cryptography library
ring, used by TLS, and the proxy script engine QuickJS compile some C code for the host. On macOS, the Xcode command line tools are enough; on Windows, use the MSVC toolchain (targetx86_64-pc-windows-msvc). - Linux system libraries
- Development packages for windows, keyboards and file dialogs; see below.
- Python 3
- Runs the law’s frozen cores and the conformance comparisons, with the standard library alone.
- Foundry
- Used to test the registry contract and recompute its code hash.
On Debian or Ubuntu, install the build dependencies first:
sudo apt install build-essential pkg-config libxkbcommon-dev libxkbcommon-x11-0 \
libwayland-dev libx11-dev libxcursor-dev libxrandr-dev libxi-dev libgl1-mesa-dev \
xdg-desktop-portal xdg-desktop-portal-gtkOn Linux the system file dialog goes through the desktop portal, so at run time xdg-desktop-portal and a backend are needed; without a portal, drag files straight into the window. Dropping goes through X11: with an X display (XWayland on a Wayland desktop included) the window runs on X11, so dropping files needs a session with an X display.
At build time, crates/app/build.rs runs cargo metadata --locked --offline to generate the third-party licence list for the target platform from Cargo.lock, and the app carries it; if the list cannot be generated, the build fails. When dependencies change, the list follows by itself. The workspace’s release profile checks integer overflow, stopping by name on one; tests and continuous integration run release builds, so what is tested is what ships.
On macOS the window is drawn through Metal by wgpu; on Windows and Linux through OpenGL. A macOS build records SDK 26 at link time (crates/app/macos_sdk.rs), so from macOS 26 the window corners and controls follow the system’s new style; the oldest macOS it runs on is MACOSX_DEPLOYMENT_TARGET, or 11.0 on arm64 when unset.
Build and test
tar -xzf zikaron-0.1.5-src.tar.gz
cd zikaron-0.1.5
cargo build --release --locked
cargo test --workspace --release --locked--locked makes the build use exactly the dependency versions pinned in Cargo.lock, as the release packages do. The outputs:
| Program | What it is |
|---|---|
target/release/app | The desktop window, packaged as ZIKARON.app on macOS, zikaron-desk on Linux and zikaron-desk.exe on Windows |
target/release/zikaron | The command line; see Command line |
zk1, zkk, zks, zka, zkg | Helper programs for testing and conformance comparison |
zikaron-pack | The packaging tool: generates the third-party licence list (notices), strips the build machine’s details from packages (hfs-owners, dmg-names, elf-comment), gives the path mapping and checks the output carries neutral path names alone (rustflags, no-paths), checks the pinned AppImage runtime (appimage-runtime), and lays out the Windows package (windows) |
On every push to main and every pull request, the repository’s .github/workflows/test.yml runs cargo build --workspace --locked --release and cargo test --workspace --locked --no-fail-fast --release on macOS, Linux and Windows; the macOS and Linux cells must pass, and the Windows cell becomes required once it has passed on a Windows machine. The macOS and Linux cells take one more step: a release build with the packaging scripts’ path mapping, then zikaron-pack no-paths to check the output carries neutral path names alone.
Packaging
| Script or command | Output |
|---|---|
packaging/macos/build.sh [--identity NAME] | ZIKARON.app, in a .dmg and a .pkg (macOS) |
packaging/linux/build.sh | Built natively on Linux: a .deb and an AppImage on x86_64; on aarch64 the .deb alone, the AppImage step stopping by name because that architecture still awaits a pinned runtime. Needs dpkg-deb and mksquashfs; the AppImage runtime is fetched over the network, or taken from a local file named by APPIMAGE_RUNTIME, and checked against its pinned bytes |
packaging/linux/cross-build.sh | The same Linux x86_64 packages from another host, using zig and cargo-zigbuild, targeting glibc 2.31; also needs mksquashfs, python3 and curl; the AppImage runtime is checked against its pinned bytes here too |
cargo run --release --locked -p zikaron-pack -- windows --out dist | The folder of the Windows x86_64 package, dist/ZIKARON-<version>-windows-x86_64/: zikaron-desk.exe, zikaron.exe, LICENSE.txt and THIRD-PARTY-LICENSES.txt. Built on Windows with MSVC, with the C runtime linked statically so users need no separate runtime; .github/workflows/package-windows.yml runs exactly this when triggered by hand. A Windows program from a plain cargo build links the C runtime dynamically and needs the VC++ runtime installed |
The macOS and Linux packages land in dist/, each with a SHA256SUMS-<system>-<arch>.txt; the Windows command lays out the folder alone, and the zip on the release page is made from that folder. Every package carries a THIRD-PARTY-LICENSES.txt generated for its target, and the user name, owner, host and system version in every package are made neutral: each packaging script first takes the path mapping from zikaron-pack rustflags (the home folder, Cargo’s and rustup’s folders, and the repository and build folders each mapped to one fixed name), then checks the build with no-paths and stops before packaging if anything is left. With --identity left out, the macOS script signs ad hoc (-); release packages are signed with Kaptonia’s certificate; see Releasing.
The deb declares these run-time dependencies: libc6, libdbus-1-3, libgcc-s1, libxkbcommon0, libxkbcommon-x11-0, libwayland-client0, libx11-6, libxcursor1, libxrandr2, libxi6 and libgl1; it recommends xdg-desktop-portal and xdg-desktop-portal-gtk.
Contract tests
cd base/zikaron-core/contracts
forge testThe law’s cores
cd base/zikaron-conformance
./criterion-digest.sh
./criterion-digest-kit.shTo run a candidate implementation against the conformance corpus, see Testing an implementation.
Trying it with separate data
On macOS and Linux the app finds its machine folder from HOME, and the key store lives there alone. Point HOME at an empty directory and start the app, and the machine folder, key store and ledgers all land inside it, apart from your everyday data:
T=$(mktemp -d)
HOME=$T ./target/release/appOn Windows USERPROFILE is read first: point it at an empty folder and start the app, and machine data lands in its AppData\Local\ZIKARON\, kept apart in the same way. The command line finds the machine folder by the same rule (for --home, the credential, the adoption and handoff lists and cli-sent/), so give it the same HOME or USERPROFILE for a trial. The environment variable ZIKARON_CLI_LINK_DIR moves where “Enable the zikaron command” writes.
For a trial, choose “Custom” in the wizard and pick Sepolia testnet under “Preset” in Settings › Network › Edit nodes; or use “New identity” and choose “Sepolia testnet” under “Network”; see Networks in the Wiki. Generate test keys on the spot with zikaron keygen and discard them afterwards.
Embedded fonts
The interface’s Latin face, Inter (regular, medium and semibold), and the monospace face, JetBrains Mono, are embedded in the app; Latin letters, figures and signs in medium and strong text take Inter’s matching weight, and Chinese then comes from each role’s own face. Chinese uses the system’s PingFang on macOS; on Windows, the system’s Microsoft YaHei UI (with its own bold), falling back to the embedded Noto Sans SC; and on Linux the embedded Noto Sans SC; so Noto Sans SC is embedded in the Windows and Linux builds alone. The embedded fonts are all released under the SIL OFL 1.1, with the licence texts in crates/zikaron-ui/fonts/.