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:

  1. swift build -c release — compiles Swift sources from sources/vphone-cli/
  2. Embeds Git commit hash via VPhoneBuildInfo.swift
  3. 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 build after make 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.entitlements for 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:

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 →