How to Compile the Swift CLI for vphone-cli: Complete Build Guide

Use ./scripts/build.sh to compile the Swift CLI for vphone-cli, which automates the full build pipeline: Swift release compilation, Git hash injection, ad-hoc code signing with private PV=3 entitlements, and macOS app bundle creation.

The vphone-cli project provides a command-line interface for managing virtualized iOS environments on macOS. Written in Swift 6.0, the executable requires specialized handling due to its reliance on Apple's private virtualization entitlements. This guide walks through compiling the Swift CLI from source, referencing the actual implementation in the Lakr233/vphone-cli repository.

Prerequisites for Building vphone-cli

Before compiling, ensure your environment meets these requirements:

  • macOS 15 or later – Required for private virtualization APIs
  • Xcode with Swift 6.0 toolchain – For release builds
  • Homebrew – To install supporting tools

Install all host dependencies via Homebrew:

brew install python@3.13 aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone cmake libusb ipsw zstd

These tools provide the Python runtime, download utilities, code signing tools, and libraries used by both the build scripts and the compiled application.

Step 1: Clone the Repository with Submodules

The vphone-cli build depends on external components. Clone with submodules to retrieve all required sources:

git clone --recurse-submodules https://github.com/Lakr233/vphone-cli.git
cd vphone-cli

The scripts/setup_tools.sh script then builds the external C/C++ toolchain (including trustcache, insert_dylib, and other helpers) and creates a Python virtual environment:

./scripts/setup_tools.sh

Step 2: Compile and Sign with build.sh

The scripts/build.sh file is the single entry point for building the Swift CLI. According to the source code at lines 36-44, this script performs:

  1. Swift compilation – swift build -c release
  2. Version injection – Writes the current Git commit hash into sources/vphone-cli/VPhoneBuildInfo.swift
  3. Code signing – Applies ad-hoc signature with sources/vphone.entitlements
  4. Bundle creation – Copies the signed binary into .build/vphone-cli.app
  5. Guest daemon compilation – Cross-compiles vphoned for iOS arm64 (unless disabled)

Run the complete build:

./scripts/build.sh

Skip the Guest Daemon Build

On machines lacking an iOS arm64 toolchain, omit the guest daemon as shown at lines 27-34:

./scripts/build.sh --no-vphoned

Understanding the Code Signing Requirements

The vphone-cli binary requires private entitlements for PV=3 (Apple's private virtualization mode). macOS rejects unsigned binaries requesting these capabilities.

The build script handles this in two phases:

  • Binary signing – codesign --sign - applies an ad-hoc signature with sources/vphone.entitlements
  • Bundle re-signing – After adding Resources (scripts, helpers, and vphoned), the entire .app bundle is re-signed to seal the directory

The entitlements file at sources/vphone.entitlements contains the private keys enabling VM functionality.

Verify the Compiled Binary

Confirm successful compilation by running:

./.build/vphone-cli.app/Contents/MacOS/vphone-cli --help

Display the embedded version information:

./.build/vphone-cli.app/Contents/MacOS/vphone-cli version

One-Command Build Pipeline

Execute the complete workflow from clone to running CLI:

git clone --recurse-submodules https://github.com/Lakr233/vphone-cli.git && \
cd vphone-cli && \
brew install python@3.13 aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone cmake libusb ipsw zstd && \
./scripts/setup_tools.sh && \
./scripts/build.sh && \
./.build/vphone-cli.app/Contents/MacOS/vphone-cli --help

Key Source Files

File Purpose
scripts/build.sh Central build orchestration – compilation, signing, bundling
sources/vphone.entitlements Private PV=3 entitlements required for virtualization
sources/vphone-cli/VPhoneBuildInfo.swift Auto-generated file storing Git commit for version display
scripts/setup_tools.sh Toolchain setup and Python environment creation
scripts/vphoned/Makefile iOS arm64 cross-compilation for guest daemon

Summary

  • Use ./scripts/build.sh as the single entry point to compile the Swift CLI for vphone-cli
  • Run with --no-vphoned when cross-compilation for iOS arm64 is unavailable
  • Ad-hoc code signing with private entitlements is mandatory for macOS to launch the VM
  • Version information is injected at build time via Git commit hash in VPhoneBuildInfo.swift

Frequently Asked Questions

What macOS version is required to compile vphone-cli?

macOS 15 or later is required. The private virtualization APIs (PV=3) used by vphone-cli are only available on recent macOS versions, and the Swift 6.0 toolchain assumes modern SDK features.

Can I build vphone-cli without an iOS development setup?

Yes. Pass the --no-vphoned flag to ./scripts/build.sh to skip cross-compiling the guest daemon. This produces a functional CLI for host-side operations, though full VM guest management requires the complete build.

Why does the build script sign the binary twice?

The first signing applies private entitlements to the bare executable. After bundling Resources (which modifies the app structure), the entire .app bundle must be re-signed to create a valid, sealed package that macOS will execute.

Where is the version information stored in the compiled binary?

The Git commit hash is written to sources/vphone-cli/VPhoneBuildInfo.swift during the build process, then compiled into the binary. Use the version subcommand to display this identifier at runtime.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →