How to Build vphone-cli from Source Code on macOS
Building vphone-cli from source requires macOS 15+, Xcode 16, Python 3.11, and a single make build command after setting up the Python virtual environment.
vphone-cli is a Swift-based macOS application that boots a virtual iPhone using Apple's Virtualization.framework. This guide walks through building it from the Lakr233/vphone-cli repository, covering prerequisites, build steps, and key source files that control the compilation and signing process.
Prerequisites for Building vphone-cli
Before compiling, ensure your environment meets these requirements:
- macOS 15 (Sequoia) or later — SIP and AMFI must be disabled for PV=3 virtualization
- Xcode 16+ — provides Swift 6.0 toolchain
- Python 3.11 — required for firmware-patching scripts
- Homebrew (optional) — for additional tooling
The build system combines a top-level Makefile with Swift Package Manager, plus Python helpers for firmware manipulation.
Step 1: Clone the Repository
git clone https://github.com/Lakr233/vphone-cli.git
cd vphone-cli
Step 2: Set Up the Python Virtual Environment
The repository includes a Makefile target that creates .venv/ and installs required packages.
make setup_venv # Installs capstone, keystone-engine, pyimg4
source .venv/bin/activate
The Python packages are used by scripts/patchers/cfw.py for creating custom firmware (CFW) images. On Linux hosts, use setup_venv_linux.sh instead.
Step 3: Build the Swift Binary
Run the main build target:
make build
This executes several operations defined in Makefile:
swift build -c release— compiles Swift sources fromsources/vphone-cli/- Embeds Git commit hash via
VPhoneBuildInfo.swift - Codesigns the binary with private entitlements from
sources/vphone.entitlements
The resulting executable appears at:
.build/release/vphone-cli
Passing Custom Swift Flags
Override compiler flags via environment variable:
make SWIFT_FLAGS="-Xfrontend -debug-time-function-bodies" build
SWIFT_FLAGS is forwarded directly to swift build in the Makefile.
Step 4: (Optional) Build the Guest Daemon
The guest-side daemon vphoned runs inside the VM and communicates over vsock. To rebuild it:
cd scripts/vphoned
make
This compiles the Objective-C daemon, which vphone-cli automatically uses during VM boot.
Step 5: Run vphone-cli
Launch the virtual iPhone with:
./.build/release/vphone-cli boot # Normal GUI boot
# or
./.build/release/vphone-cli boot_dfu # DFU-only mode
First launch triggers fw_prepare.sh to download and patch firmware automatically.
Complete Build Script Example
Automate the entire process:
#!/usr/bin/env bash
set -euo pipefail
git clone --depth 1 https://github.com/Lakr233/vphone-cli.git
cd vphone-cli
make setup_venv
source .venv/bin/activate
make build
./.build/release/vphone-cli boot
Key Source Files in the Build Pipeline
Understanding these files helps with customization and debugging:
| File | Purpose |
|---|---|
Makefile |
Orchestrates setup, build, and boot targets |
Package.swift |
Swift Package Manager manifest with dependencies |
sources/vphone-cli/main.swift |
Entry point — parses CLI args, starts NSApplication |
sources/vphone-cli/VPhoneAppDelegate.swift |
Drives VM lifecycle, handles signals, UI setup |
sources/vphone-cli/VPhoneVirtualMachine.swift |
Configures VZVirtualMachineConfiguration |
sources/vphone.entitlements |
Private entitlements for Virtualization.framework |
scripts/patchers/cfw.py |
Python firmware patcher for CFW creation |
scripts/vphoned/Makefile |
Builds the guest-side Objective-C daemon |
Manual Re-signing After Entitlement Changes
If you modify sources/vphone.entitlements, re-sign manually:
codesign -s - --entitlements sources/vphone.entitlements \
.build/release/vphone-cli
This preserves the private entitlements required for PV=3 virtualization.
Summary
- Build vphone-cli from source using
make buildaftermake setup_venv - Requirements: macOS 15+, Xcode 16, Python 3.11, disabled SIP/AMFI
- Output: Signed binary at
.build/release/vphone-cli - Guest daemon: Build separately in
scripts/vphoned/if modifying VM communication - Entitlements: Critical signing step uses
sources/vphone.entitlementsfor virtualization access
Frequently Asked Questions
Why does vphone-cli require SIP and AMFI to be disabled?
PV=3 virtualization in Apple's Virtualization.framework needs private entitlements that are only valid when System Integrity Protection and Apple Mobile File Integrity are turned off. These restrictions are enforced by macOS at the kernel level and cannot be bypassed while security features remain active.
Can I build vphone-cli on Linux or Windows?
No. vphone-cli depends on Apple-specific frameworks: Virtualization.framework, AppKit for the GUI, and private entitlements only available on macOS. The setup_venv_linux.sh script exists for Python environment setup on Linux hosts, but the Swift binary itself requires macOS to compile and run.
How do I update the embedded Git commit hash in the binary?
The Makefile automatically regenerates VPhoneBuildInfo.swift during each make build invocation. Simply rebuild after committing changes—no manual intervention needed. The commit hash is embedded at compile time via Swift package build plugins.
What if codesign fails during build?
Ensure you're running on macOS with a valid developer certificate or use ad-hoc signing (-s -). The Makefile uses codesign -s - by default for local builds. If entitlements are rejected, verify SIP is disabled and that sources/vphone.entitlements contains the required com.apple.vm.networking and com.apple.vm.hypervisor entitlements for PV=3.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →