# How to Build vphone-cli from Source Code on macOS

> Learn to build vphone-cli from source code on macOS. Follow simple steps using Xcode and Python to compile this command-line tool. Get started now.

- Repository: [Lakr/vphone-cli](https://github.com/Lakr233/vphone-cli)
- Tags: how-to-guide
- Published: 2026-09-06

---

**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

```bash
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.

```bash
make setup_venv        # Installs capstone, keystone-engine, pyimg4

source .venv/bin/activate

```

The Python packages are used by [`scripts/patchers/cfw.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw.py) for creating custom firmware (CFW) images. On Linux hosts, use [`setup_venv_linux.sh`](https://github.com/Lakr233/vphone-cli/blob/main/setup_venv_linux.sh) instead.

## Step 3: Build the Swift Binary

Run the main build target:

```bash
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`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneBuildInfo.swift)
3. **Codesigns** the binary with private entitlements from `sources/vphone.entitlements`

The resulting executable appears at:

```bash
.build/release/vphone-cli

```

### Passing Custom Swift Flags

Override compiler flags via environment variable:

```bash
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:

```bash
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:

```bash
./.build/release/vphone-cli boot        # Normal GUI boot

# or

./.build/release/vphone-cli boot_dfu    # DFU-only mode

```

First launch triggers [`fw_prepare.sh`](https://github.com/Lakr233/vphone-cli/blob/main/fw_prepare.sh) to download and patch firmware automatically.

## Complete Build Script Example

Automate the entire process:

```bash
#!/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`](https://github.com/Lakr233/vphone-cli/blob/main/Package.swift) | Swift Package Manager manifest with dependencies |
| [`sources/vphone-cli/main.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/main.swift) | Entry point — parses CLI args, starts `NSApplication` |
| [`sources/vphone-cli/VPhoneAppDelegate.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneAppDelegate.swift) | Drives VM lifecycle, handles signals, UI setup |
| [`sources/vphone-cli/VPhoneVirtualMachine.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneVirtualMachine.swift) | Configures `VZVirtualMachineConfiguration` |
| `sources/vphone.entitlements` | Private entitlements for Virtualization.framework |
| [`scripts/patchers/cfw.py`](https://github.com/Lakr233/vphone-cli/blob/main/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:

```bash
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`](https://github.com/Lakr233/vphone-cli/blob/main/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`](https://github.com/Lakr233/vphone-cli/blob/main/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.