## Install

Pick the install pattern that matches how you'll use roar:

| Setting | Command | Why |
|---|---|---|
| Interactive workstation | `uv tool install roar-cli` *(or `pipx install roar-cli`)* | Always on PATH, project-independent. |
| Container / CI / single-Python environment | `uv pip install roar-cli` *(or `pip install roar-cli`)* | One Python; install ABI matches traced ABI by construction. |
| Contributing to roar | `bash scripts/install-dev.sh` | Editable Python install + builds the Rust tracer binaries — see [Building from source](#building-from-source). |

### Interactive workstation

```bash
uv tool install roar-cli
```

Installs roar as an isolated CLI tool. `roar` lives on PATH and is available from any directory regardless of which venv is active.

To pin the Python `roar` itself runs under — useful when you want it to match the Python you'll be tracing on this machine and avoid cross-ABI surprises — pass `--python`:

```bash
uv tool install --python python3.12 roar-cli
```

### Container / CI

```bash
uv pip install roar-cli      # into the active venv or system Python
# or, with plain pip:
pip install roar-cli
```

This puts roar in the same Python environment that runs your code. In a container or CI runner with a single Python, that's the simplest pattern — roar's bundled deps match the traced Python's ABI by construction, and there are no runtime fetches.

```Dockerfile
FROM python:3.12-slim
RUN pip install roar-cli
```

> **Note on `uv pip install -e .`.** Editable install from a roar source checkout doesn't produce a working tool on its own — the Rust tracer binaries live in separate cargo crates outside the maturin manifest. For contributing to roar, use `bash scripts/install-dev.sh`. See [Building from source](#building-from-source) below.

## Prerequisites

- **Python 3.10+**.
- **Linux** (x86_64 or aarch64) or **macOS** (x86_64 or arm64). Windows is not supported yet.

## Platforms

| Platform | Status |
|---|---|
| Linux x86_64 | Full support — all three tracer backends. |
| Linux aarch64 | Full support — all three tracer backends. |
| macOS (arm64 / x86_64) | Preload backend only — see [macOS notes](#macos-notes) below. |
| Windows | Not yet. |

PyPI wheels ship with pre-built tracer binaries for Linux (x86_64, aarch64) and macOS (x86_64, arm64). If `pip` falls through to the source distribution (e.g., a platform without a wheel, or a constrained installer), the sdist needs to compile the tracers locally — see [Building from source](#building-from-source).

## Tracer backends and prerequisites

`roar run` needs a tracer binary to observe file I/O. Three backends ship; `roar tracer` shows you which one is active.

| Backend | Platform | Extra prerequisites |
|---|---|---|
| `eBPF` (fastest) | Linux ≥ 5.8 with BTF | `CAP_BPF` (or root). Run `roar tracer enable ebpf` once to apply the capability. |
| `preload` | Linux, macOS | None on Linux. On macOS, can't trace SIP-protected binaries — see below. |
| `ptrace` | Linux | `kernel.yama.ptrace_scope` ≤ 1 (or `CAP_SYS_PTRACE` if it's 2). |

By default `roar` picks `auto` mode — eBPF if it preflights cleanly, then preload, then ptrace. Inspect and change with:

```bash
roar tracer                  # readiness table for all three backends
roar tracer use <mode>       # pin to auto | ebpf | preload | ptrace
roar tracer check <mode>     # deep preflight for one backend
roar tracer enable ebpf      # one-shot host config (applies CAP_BPF)
```

For the full backend story (when each is the right choice, cloud-platform compatibility, limitations), see [Tracers](/docs/tracers).

## macOS notes

`roar` on macOS uses the **preload** backend, which injects via `DYLD_INSERT_LIBRARIES`. macOS System Integrity Protection (SIP) silently blocks library injection into Apple-signed platform binaries — anything under `/usr/bin/`, `/bin/`, `/sbin/`, `/System/`. When this happens, `roar run` completes successfully but captures no file I/O events.

**Practical impact:** use a non-Apple Python. Homebrew, Conda, `uv`, `pyenv`, and Nix all work; the system `/usr/bin/python3` doesn't.

```bash
# This works:
brew install python3
roar run python3 train.py                  # /opt/homebrew/bin/python3

# This silently captures nothing (SIP blocks it):
roar run /usr/bin/python3 train.py
```

`roar` prints a warning when it detects zero events from a SIP-protected binary.

## Building from source

If `pip install` couldn't find a matching wheel — or you're contributing to `roar` — the sdist includes the Rust tracer source but no pre-built binaries. You'll need:

- A C toolchain (`gcc` or `clang`).
- Rust toolchain (`rustup`).
- A few minutes to compile (`cargo build --release` runs across the tracer crates).

For a one-shot dev install that handles everything:

```bash
git clone https://github.com/treqs/roar.git
cd roar
bash scripts/install-dev.sh
```

`install-dev.sh` runs `uv pip install -e ".[dev]"` (or `pip` as a fallback) and then builds the Rust tracer binaries (`roar-tracer`, `roar-tracer-preload`, `roar-tracer-ebpf`, `roard`, `roar-proxy`) and stages them into `roar/bin/`. A bare `pip install -e .` does *not* build the tracer binaries — they live in separate cargo crates outside the maturin manifest, so `roar run` would fail with "No tracer binary found" until the script runs.

If you'd rather build individual backends manually:

```bash
cd rust

# eBPF (Linux)
cargo build --release -p roar-tracer-ebpf

# preload (macOS & Linux)
cargo build --release -p roar-tracer-preload

# ptrace (Linux)
cargo build --release -p roar-tracer
```
