84 lines
3.1 KiB
Markdown
84 lines
3.1 KiB
Markdown
# Integrating Local Binary Extensions with `uv`
|
|
|
|
This guide explains how we packaged the local `pyzed` binary extension (originally from a system installation) so that `uv` can manage it as a project dependency.
|
|
|
|
## The Problem
|
|
|
|
The ZED SDK installs its Python wrapper (`pyzed`) as a system-level package (often in `/usr/local/lib/...`). It consists of compiled extensions (`.so` or `.sl` files) and Python bindings.
|
|
|
|
`uv` strictly manages virtual environments and dependencies. It cannot directly "see" or import packages from the global system site-packages unless explicitly configured to use system site-packages (which reduces isolation). Furthermore, a raw `.so` file or a bare directory without metadata isn't a valid package source for `uv`.
|
|
|
|
## The Solution: A Local Package Wrapper
|
|
|
|
To make `pyzed` compatible with `uv`, we wrapped the raw library files into a proper, minimally compliant Python package located at `libs/pyzed_pkg`.
|
|
|
|
### 1. Directory Structure
|
|
|
|
We organized the files into a standard package layout:
|
|
|
|
```text
|
|
libs/pyzed_pkg/
|
|
├── pyproject.toml # Package metadata (CRITICAL)
|
|
└── pyzed/ # The actual importable package
|
|
├── __init__.py
|
|
├── sl.cpython-312-x86_64-linux-gnu.so # The compiled extension
|
|
└── ...
|
|
```
|
|
|
|
### 2. The Local `pyproject.toml`
|
|
|
|
We created a `pyproject.toml` inside `libs/pyzed_pkg` to tell build tools how to handle the files.
|
|
|
|
Key configuration points:
|
|
1. **Build System**: Uses `setuptools` to bundle the files.
|
|
2. **Package Discovery**: Explicitly lists `pyzed`.
|
|
3. **Package Data**: **Crucially**, configures `setuptools` to include binary files (`*.so`, `*.pyi`) which are usually ignored by default.
|
|
|
|
```toml
|
|
[project]
|
|
name = "pyzed"
|
|
version = "0.1.0"
|
|
description = "Wrapper for ZED SDK"
|
|
requires-python = ">=3.12"
|
|
dependencies = []
|
|
|
|
[build-system]
|
|
requires = ["setuptools", "wheel"]
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
[tool.setuptools]
|
|
packages = ["pyzed"]
|
|
|
|
# IMPORTANT: Ensure the binary extension is included in the build
|
|
[tool.setuptools.package-data]
|
|
pyzed = ["*.so", "*.pyi"]
|
|
```
|
|
|
|
## Configuring the Main Project
|
|
|
|
In the root `pyproject.toml` of your application, we used **`[tool.uv.sources]`** to redirect the `pyzed` dependency to our local path.
|
|
|
|
```toml
|
|
[project]
|
|
dependencies = [
|
|
"pyzed", # Declared as a normal dependency
|
|
"cupy-cuda12x",
|
|
"numpy",
|
|
]
|
|
|
|
# uv-specific configuration
|
|
[tool.uv.sources]
|
|
pyzed = { path = "libs/pyzed_pkg" }
|
|
```
|
|
|
|
## How `uv` Processes This
|
|
|
|
1. **Resolution**: When you run `uv sync` or `uv run`, `uv` sees `pyzed` in the dependencies.
|
|
2. **Source Lookup**: It checks `tool.uv.sources` and finds the local path `libs/pyzed_pkg`.
|
|
3. **Build/Install**:
|
|
* `uv` treats the directory as a source distribution.
|
|
* It uses the `build-system` defined in `libs/pyzed_pkg/pyproject.toml` to build a temporary wheel.
|
|
* This wheel (containing the `.so` file) is installed into the project's virtual environment (`.venv`).
|
|
|
|
This ensures that your application works seamlessly with `import pyzed.sl` while maintaining a clean, isolated, and reproducible environment managed by `uv`.
|