Compare commits

..

38 Commits

Author SHA1 Message Date
Adeeb Shihadeh
21bb9ab18e raylib: fix setup.py to also trigger offscreen variant build
setup.py had its own cache check that only looked for libraylib.a,
skipping build.sh entirely when the cache had the desktop variant.
Now also checks for libraylib_offscreen.a on x86_64.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:15:59 -08:00
Adeeb Shihadeh
2341b89849 raylib: fix idempotency check to include offscreen variant
The build cache had desktop-only libraylib.a, causing build.sh to skip
the offscreen variant entirely. Now requires libraylib_offscreen.a on
x86_64 before considering the build complete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:07:25 -08:00
Adeeb Shihadeh
7d158432af raylib: bump to 5.5.0.6 (re-publish with offscreen libs)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:00:47 -08:00
Adeeb Shihadeh
c81badf4a5 raylib: install EGL/GL dev packages for offscreen variant build
The manylinux container doesn't have Mesa packages pre-installed.
Install them before building the offscreen variant and bundling GLVND.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:54:54 -08:00
Adeeb Shihadeh
122939fdf2 raylib: add PLATFORM_OFFSCREEN support (#38)
* raylib: add PLATFORM_OFFSCREEN support for headless CI rendering

- build.sh: use commaai/raylib platform-offscreen commit, build offscreen
  variant (libraylib_offscreen.a) alongside desktop for x86_64, bundle
  GLVND dispatchers (libEGL, libOpenGL, libGLdispatch) in install/lib/mesa/
- build.py: add PLATFORM_OFFSCREEN elif — uses offscreen lib + bundled
  GLVND with RPATH, links -lOpenGL -lEGL instead of -lGL -lX11
- __init__.py: auto-rebuild CFFI when RAYLIB_PLATFORM env changes
  (tracks built platform in .raylib_platform marker file)
- Bump version to 5.5.0.5

This lets openpilot CI render headlessly via EGL surfaceless + Mesa
llvmpipe without needing xvfb or any additional apt packages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* raylib: auto-detect CI and use PLATFORM_OFFSCREEN

__init__.py now auto-detects CI on Linux x86_64 and uses
PLATFORM_OFFSCREEN + LIBGL_ALWAYS_SOFTWARE=1 automatically.
No env vars needed in the consuming CI workflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:44:19 -08:00
Adeeb Shihadeh
9690fd5160 raylib: use stable ABI for CFFI extension (#37)
The CFFI extension was built with py_limited_api=False, producing
version-specific .so files (e.g., cpython-312 on Linux, cpython-314
on macOS). This caused import failures when the build Python version
didn't match the runtime version.

Switch to py_limited_api=True to produce _raylib_cffi.abi3.so which
works across Python 3.x versions.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:07:15 -08:00
Adeeb Shihadeh
c835b206c6 release: include compiled extensions (*.so) in shim package-data (#36)
The shim setup.py extracts .so files from the wheel, but the
generated pyproject.toml didn't include them in package-data, so
they were excluded when uv built a local wheel from the source.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:50:07 -08:00
Adeeb Shihadeh
70b6bf1c40 raylib: include pre-compiled CFFI extension in wheel (#35)
Build the CFFI Python extension (_raylib_cffi.so) during wheel build
instead of deferring to first import. This eliminates the need for
libgl-dev and libx11-dev on the target system.

- setup.py: run build.py after build.sh to compile CFFI extension
- pyproject.toml: include _raylib_cffi*.so in package-data, bump to 5.5.0.3
- _shim_setup.py: extract .so files from wheel alongside data directory

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:36:30 -08:00
Adeeb Shihadeh
d67b3e906e release: copy all Python sources and deps to shim branch (#34)
The shim branch was only copying __init__.py from each package,
which dropped Python source files needed for CFFI builds (build.py,
colors.py, defines.py, enums.py, version.py) and extra packages
like pyray. It also dropped project dependencies like cffi.

- Copy all .py files from the main module, not just __init__.py
- Copy extra packages listed in packages.find.include
- Preserve project dependencies in generated pyproject.toml
2026-03-01 12:04:48 -08:00
Adeeb Shihadeh
408cc4b949 add json11 package (#33)
* add libyuv package

* update libyuv to upstream 1922

* add json11 package
2026-03-01 11:29:13 -08:00
Adeeb Shihadeh
9e9a5b56ac add raylib package (#31) (#31)
Vendor raylib C library + pyray Python bindings (CFFI) from commaai's
raylib and raylib-python-cffi forks.

Supports PLATFORM_DESKTOP (X11/GL) and PLATFORM_COMMA (DRM/EGL/GLES)
backends, auto-detected via /TICI.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:08:58 -08:00
Adeeb Shihadeh
e46683e1fc add libyuv package (#32)
* add libyuv package

* update libyuv to upstream 1922
2026-03-01 10:36:21 -08:00
Adeeb Shihadeh
db4664139a add bzip2 package (#28)
Static build of bzip2 1.0.8 (libbz2.a + bzlib.h) for use as a
vendored dependency in openpilot replay/cabana tools.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 12:01:40 -08:00
Adeeb Shihadeh
8472bcb091 update readme 2026-02-27 11:57:01 -08:00
Adeeb Shihadeh
357d36a61d simplify building (#26) 2026-02-25 20:17:13 -08:00
Adeeb Shihadeh
ae529b6818 set more -fPIC 2026-02-24 18:57:54 -08:00
Adeeb Shihadeh
a3eeb36555 fix x264 finite-math and capnproto -fPIC (#22) 2026-02-24 18:34:16 -08:00
David
57b632b00a ffmpeg: build and include zlib to enable PNG support (#21)
* add zlib to ffmpeg

* checkout specific commit
2026-02-24 18:05:42 -08:00
David
e35ea9f690 add mjpeg to encoders (#20) 2026-02-24 18:02:33 -08:00
David
32c2a425b5 ffpmeg: add framehash muxer (#19)
* add framehash demuxer

* oops, muxer not demuxer
2026-02-24 18:02:26 -08:00
Adeeb Shihadeh
62d18088cc build linux wheels with manylinux_2_28 for wider glibc compat (#18)
* build linux wheels inside manylinux_2_28 for glibc 2.28 compat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* add perl-IPC-Cmd for openssl build in manylinux

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:44:07 -08:00
Adeeb Shihadeh
ec99b49198 rename openssl package to openssl3 (#17) 2026-02-24 11:20:46 -08:00
Adeeb Shihadeh
31b96deac5 add openssl package (#16)
Vendors OpenSSL 3.4.1 as static libraries (libcrypto.a, libssl.a) for
openpilot, following the same pattern as other vendored packages.

Uses module name openssl3 to avoid case-insensitive filesystem conflict
with pyOpenSSL's OpenSSL module on macOS.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:53:01 -08:00
Adeeb Shihadeh
6fe17e7b31 add libjpeg-turbo package (#15)
Vendors libjpeg-turbo 3.1.0 as a static library for openpilot, following
the same pattern as zstd/ncurses/zeromq.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:09:19 -08:00
Adeeb Shihadeh
2377af3f1f fix git-lfs on macOS 2026-02-23 22:59:08 -08:00
Adeeb Shihadeh
b9f89a5a5d disable LTO for zstd to fix cross-version linking on macOS
LTO bitcode is compiler-version-specific. The wheel built with
clang 17 produces bitcode that clang 16 (used in openpilot CI)
cannot read. Disable IPO to produce standard object files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 22:46:55 -08:00
Adeeb Shihadeh
fd4ae72793 add zstd and ncurses packages (#14) 2026-02-23 22:34:46 -08:00
Adeeb Shihadeh
dfa87aa31a add python3-dev package (#13)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 21:46:40 -08:00
Adeeb Shihadeh
71d4d1d3a1 downgrade cppcheck to 2.16.0 (#12) 2026-02-23 11:47:16 -08:00
Adeeb Shihadeh
f117a0e60d add cppcheck package (#10)
Cppcheck 2.19.1 static analysis tool, built from source. Includes
the MISRA C addon, cfg files, and platform definitions for opendbc
and panda safety analysis.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 10:18:33 -08:00
Adeeb Shihadeh
bf379a6268 add eigen package (#9)
Header-only Eigen 3.4.0 C++ linear algebra library, downloaded from
GitLab release. Exposes INCLUDE_DIR for scons integration.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 21:39:17 -08:00
Adeeb Shihadeh
fcd4d49232 better README (#5) 2026-02-22 21:34:30 -08:00
Adeeb Shihadeh
9a30c4f717 update .gitignore 2026-02-22 21:29:04 -08:00
Adeeb Shihadeh
c57efe15bc add git-lfs package (#8) 2026-02-22 21:19:16 -08:00
Adeeb Shihadeh
f67ffb5c94 add zeromq package (#7)
Static build of libzmq 4.3.5 providing headers and library for
C/C++ projects that link against zmq.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 19:45:10 -08:00
Adeeb Shihadeh
cd913d0f9f add capnp and ffmpeg (#4) 2026-02-22 19:06:33 -08:00
Adeeb Shihadeh
e66179c262 build & publish wheels on master pushes (#3) 2026-02-22 17:56:43 -08:00
Adeeb Shihadeh
453518f608 restructure CI into build + smoketest pipeline (#6) 2026-02-22 17:52:42 -08:00
79 changed files with 4537 additions and 140 deletions

103
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,103 @@
name: ci
on:
pull_request:
push:
branches: [master]
jobs:
build:
name: build (${{ matrix.platform }})
runs-on: ${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
include:
- platform: linux-x86_64
runs-on: ubuntu-latest
- platform: linux-arm64
runs-on: ubuntu-24.04-arm
- platform: macos
runs-on: macos-latest
steps:
- uses: actions/checkout@v6
- uses: actions/cache@v4
with:
key: build-cache-v1-${{ matrix.platform }}-${{ hashFiles('build.sh', 'setup.sh', '*/pyproject.toml', '*/setup.py', '*/build.sh') }}
restore-keys: build-cache-v1-${{ matrix.platform }}-
path: |
.uv-cache
*/*/install
*/*/toolchain
*/*/bin
- name: Build wheels
env:
MANYLINUX: ${{ runner.os == 'Linux' && '1' || '0' }}
UV_CACHE_DIR: ${{ github.workspace }}/.uv-cache
BUILD_SH_REUSE_MANYLINUX_ARTIFACTS: "1"
run: ./build.sh
- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.platform }}
path: dist/*.whl
test:
name: test distro (${{ matrix.image }})
needs: build
runs-on: ${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
include:
- image: debian:bookworm-slim
runs-on: ubuntu-latest
- image: ubuntu:24.04
runs-on: ubuntu-latest
- image: ubuntu:20.04
runs-on: ubuntu-latest
- image: fedora:41
runs-on: ubuntu-latest
- image: archlinux:latest
runs-on: ubuntu-latest
- image: opensuse/tumbleweed:latest
runs-on: ubuntu-latest
- image: ghcr.io/void-linux/void-glibc:latest
runs-on: ubuntu-latest
- image: debian:bookworm-slim
runs-on: ubuntu-24.04-arm
# TODO: add musl test
steps:
- uses: actions/checkout@v6
- uses: actions/download-artifact@v4
with:
name: ${{ contains(matrix.runs-on, 'arm') && 'wheels-linux-arm64' || 'wheels-linux-x86_64' }}
path: dist/
- run: ./test_wheels_in_image.sh "${{ matrix.image }}"
publish:
name: publish wheels
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
needs: [build, test]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v6
- uses: actions/download-artifact@v4
with:
pattern: wheels-*
merge-multiple: true
path: dist
- uses: actions/cache/restore@v4
with:
key: build-cache-v1-${{ matrix.platform }}-${{ hashFiles('build.sh', 'setup.sh', '*/pyproject.toml', '*/setup.py', '*/build.sh') }}
restore-keys: build-cache-v1-${{ matrix.platform }}-
path: |
.uv-cache
*/*/install
*/*/toolchain
*/*/bin
- name: Publish wheels and shims
env:
GH_TOKEN: ${{ github.token }}
run: ./release.sh --publish-only

View File

@@ -1,73 +0,0 @@
name: ./test.sh
on:
push:
branches: [master]
pull_request:
jobs:
test:
name: ${{ matrix.image || matrix.os }}
runs-on: ${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
include:
# native (no docker)
- os: macos-latest
runs-on: macos-latest
# the provided github actions runner images
# have tons of pre-installed packages. the
# goal here is to test across many vanilla setups
- image: debian:bookworm-slim
runs-on: ubuntu-latest
- image: ubuntu:24.04
runs-on: ubuntu-latest
- image: fedora:41
runs-on: ubuntu-latest
- image: archlinux:latest
runs-on: ubuntu-latest
- image: alpine:3.21 # musl libc
runs-on: ubuntu-latest
- image: opensuse/tumbleweed:latest
runs-on: ubuntu-latest
- image: ghcr.io/void-linux/void-glibc:latest
runs-on: ubuntu-latest
- image: debian:bookworm-slim
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v6
# native (macOS)
- if: ${{ !matrix.image }}
uses: actions/setup-python@v6
with:
python-version: "3.14"
- if: ${{ !matrix.image }}
name: ./test.sh
run: ./test.sh
# docker (vanilla Linux)
- if: ${{ matrix.image }}
name: install python3
run: |
docker build -t test -f - . <<'DOCKERFILE'
FROM ${{ matrix.image }}
RUN if command -v apk >/dev/null; then \
apk add --no-cache python3 py3-pip bash curl; \
elif command -v apt-get >/dev/null; then \
apt-get update && apt-get install -y --no-install-recommends python3 python3-pip python3-venv curl ca-certificates; \
elif command -v dnf >/dev/null; then \
dnf install -y python3 python3-pip curl; \
elif command -v pacman >/dev/null; then \
pacman -Sy --noconfirm python python-pip curl; \
elif command -v zypper >/dev/null; then \
zypper install -y python3 python3-pip curl; \
elif command -v xbps-install >/dev/null; then \
xbps-install -Sy python3 python3-pip bash curl; \
fi
DOCKERFILE
- if: ${{ matrix.image }}
name: ./test.sh
run: docker run --rm -v "$PWD:/work" -w /work test bash ./test.sh

18
.gitignore vendored
View File

@@ -1,10 +1,28 @@
.git/
repo/
.venv/
__pycache__/
# agents
.claude/
.context/
TASK.md
# build artifacts (applies to all packages)
build/
dist/
install/
*.egg-info/
*-src/
*.tar.gz
*.tar.xz
*.tgz
Python-*/
ncurses-*/
arm-gnu-toolchain-*/
# downloaded toolchain binaries
gcc-arm-none-eabi/gcc_arm_none_eabi/toolchain/
# downloaded git-lfs
git-lfs/git_lfs/bin/

View File

@@ -1,14 +1,23 @@
# dependencies
a central repo for managing and vendoring third party dependencies for all comma projects.
a central repo for [vendoring](https://htmx.org/essays/vendoring/) all third party dependencies for comma projects.
all of our projects are python projects, so each of these gets packaged as a pip project.
since all our projects are Python, we wrap each vendored dependency as a pip package. `git clone` and `uv sync` is all you need.
this vendoring serves a few goals:
- all dependencies are centrally managed here
- we can slim them down to only what we need
- all platforms get the same versions installed
- tighter control of distribution for fast installs (e.g. Ubuntu's `apt-get` is slow)
motivations for this approach
- `apt-get` is slow
- `apt-get` updates its packages on a schedule we don't control
- `apt-get` package versions don't match `brew` versions
- `apt-get` doesn't come with Arch Linux
- `apt-get` packages come with more than we need, bloating our project footprint
<!--
this critically adds friction to adding dependencies to our project
- `apt-get` installing a package is easy. is it 1MB, 10MB, or 100MB? no idea.
- `apt-get` installing a package is much easier than adding it here. how much do you want it?
-->
`uv`, as opposed to `apt-get`, `brew`, and friends, is fast and already used in our projects.
we target the following platforms:
- Linux x86_64
@@ -16,3 +25,37 @@ we target the following platforms:
- Darwin aarch64 (Apple Silicon)
contributions welcome for other platforms!
<!--
## packages
| package | description |
|-------------------|--------------------------------------------------------------------------|
| gcc-arm-none-eabi | builds [panda](https://github.com/commaai/panda) firmware for STM32 MCUs |
| capnproto | message serialization for openpilot |
| ffmpeg | video encode and decode for openpilot |
| git-lfs | for tracking large files in openpilot |
| zeromq | bridging the openpilot IPC between different hosts |
-->
## usage
```python
dependencies = [
# use the releases branch for pre-built wheels
"capnproto @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=capnproto",
"ffmpeg @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=ffmpeg",
# use the master branch to build the package on pip install
"capnproto @ git+https://github.com/commaai/dependencies.git@master#subdirectory=capnproto",
"ffmpeg @ git+https://github.com/commaai/dependencies.git@master#subdirectory=ffmpeg",
]
```
## workflow
to add a new package:
* start a new top-level directory as a new package
* `./test.sh` tests the building of all packages
* on pushes to `master`, wheels are built for our target platforms and pushed to a GitHub release
* the `releases` branch contains shim packages that allow pointing to a git branch and always getting the appropriate wheel for your platform

92
_shim_setup.py Normal file
View File

@@ -0,0 +1,92 @@
"""Shim setup.py: downloads pre-built wheels from GitHub Releases at install time."""
import os
import platform
import zipfile
from io import BytesIO
from urllib.request import urlopen
try:
import tomllib
except ImportError:
import tomli as tomllib
from setuptools import setup
from setuptools.command.build_py import build_py
_HERE = os.path.dirname(os.path.abspath(__file__))
with open(os.path.join(_HERE, "pyproject.toml"), "rb") as _f:
_cfg = tomllib.load(_f)
REPO_URL = _cfg["tool"]["shim"]["repo_url"]
TAG = _cfg["tool"]["shim"]["tag"]
DATADIR = _cfg["tool"]["shim"]["datadir"]
VERSION = _cfg["project"]["version"]
MODULE = _cfg["project"]["name"].replace("-", "_")
PLATFORM_MAP = {
("Linux", "x86_64"): "linux_x86_64",
("Linux", "aarch64"): "linux_aarch64",
("Darwin", "arm64"): "macosx_11_0_arm64",
}
class InstallPrebuilt(build_py):
def run(self):
module_dir = os.path.join(_HERE, MODULE)
data_dir = os.path.join(module_dir, DATADIR)
if not os.path.exists(os.path.join(data_dir, "bin")):
key = (platform.system(), platform.machine())
plat = PLATFORM_MAP.get(key)
if plat is None:
raise RuntimeError(f"unsupported platform: {key}")
whl_name = f"{MODULE}-{VERSION}-py3-none-{plat}.whl"
url = f"{REPO_URL}/releases/download/{TAG}/{whl_name}"
print(f"Downloading {url} ...")
raw = urlopen(url).read()
print(f"Extracting {DATADIR} ...")
with zipfile.ZipFile(BytesIO(raw)) as zf:
prefix = f"{MODULE}/{DATADIR}/"
alt_prefix = f"{MODULE}-{VERSION}.data/purelib/{MODULE}/{DATADIR}/"
for info in zf.infolist():
for p in (prefix, alt_prefix):
if info.filename.startswith(p):
rel = info.filename[len(p):]
if not rel:
continue
dest = os.path.join(data_dir, rel)
if info.is_dir():
os.makedirs(dest, exist_ok=True)
else:
os.makedirs(os.path.dirname(dest), exist_ok=True)
with open(dest, "wb") as f:
f.write(zf.read(info))
if info.external_attr >> 16 & 0o111:
os.chmod(dest, 0o755)
break
# Also extract compiled extension modules (.so)
ext_prefix = f"{MODULE}/"
ext_alt_prefix = f"{MODULE}-{VERSION}.data/purelib/{MODULE}/"
for info in zf.infolist():
if not info.filename.endswith('.so'):
continue
for p in (ext_prefix, ext_alt_prefix):
if info.filename.startswith(p):
rel = info.filename[len(p):]
if rel and '/' not in rel:
dest = os.path.join(module_dir, rel)
os.makedirs(os.path.dirname(dest), exist_ok=True)
with open(dest, "wb") as f:
f.write(zf.read(info))
if info.external_attr >> 16 & 0o111:
os.chmod(dest, 0o755)
break
super().run()
setup(cmdclass={"build_py": InstallPrebuilt})

73
build.sh Executable file
View File

@@ -0,0 +1,73 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$ROOT_DIR"
if [[ $# -gt 0 ]]; then
echo "usage: MANYLINUX=1 ./build.sh" >&2
exit 2
fi
USE_MANYLINUX="${MANYLINUX:-0}"
if [[ -z "${BUILD_SH_IN_MANYLINUX:-}" ]] && ! command -v uv >/dev/null 2>&1; then
./setup.sh
fi
if [[ "$USE_MANYLINUX" == "1" && -z "${BUILD_SH_IN_MANYLINUX:-}" ]]; then
UV_BIN="$(command -v uv)"
docker run --rm \
-e BUILD_SH_IN_MANYLINUX=1 \
-e BUILD_SH_REUSE_MANYLINUX_ARTIFACTS="${BUILD_SH_REUSE_MANYLINUX_ARTIFACTS:-}" \
-e HOME=/tmp \
-e UV_CACHE_DIR=/work/.uv-cache \
-e UV_PYTHON=/opt/python/cp312-cp312/bin/python3 \
-v "$ROOT_DIR:/work" \
-v "$UV_BIN:/usr/local/bin/uv:ro" \
-w /work \
"quay.io/pypa/manylinux_2_28_$(uname -m)" \
bash build.sh
exit 0
fi
if [[ -n "${BUILD_SH_IN_MANYLINUX:-}" ]]; then
export PATH="/opt/python/cp312-cp312/bin:$PATH"
./setup.sh
if [[ -z "${BUILD_SH_REUSE_MANYLINUX_ARTIFACTS:-}" ]]; then
for toml in */pyproject.toml; do
pkg="${toml%/pyproject.toml}"
module="${pkg//-/_}"
rm -rf "$pkg/$module/install" "$pkg/$module/toolchain" "$pkg/$module/bin"
done
fi
fi
echo "Building workspace packages into dist"
START_SECS=$SECONDS
uv build --all-packages --wheel --out-dir dist --no-create-gitignore --no-build-logs
if [[ -n "${BUILD_SH_IN_MANYLINUX:-}" ]]; then
VENV_DIR="$ROOT_DIR/.venv-manylinux"
else
VENV_DIR="$ROOT_DIR/.venv"
fi
echo
echo "Running smoketests"
uv venv --allow-existing --quiet "$VENV_DIR"
uv pip install --python "$VENV_DIR/bin/python" --reinstall --no-deps --quiet dist/*.whl >/dev/null
for toml in */pyproject.toml; do
module="$(basename "$(dirname "$toml")" | tr '-' '_')"
"$VENV_DIR/bin/python" -c "import $module; $module.smoketest()" >/dev/null
done
du -hs dist/* | sort -hr
echo
echo "Done in $((SECONDS - START_SECS))s"

45
bzip2/build.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="1.0.8"
INSTALL_DIR="$DIR/bzip2/install"
# Idempotent: skip if already built
if [ -f "$INSTALL_DIR/lib/libbz2.a" ]; then
echo "bzip2 already present, skipping build."
exit 0
fi
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
# Download
if [ ! -d "bzip2-src" ]; then
curl -L "https://sourceware.org/pub/bzip2/bzip2-${VERSION}.tar.gz" -o bzip2.tar.gz
mkdir -p bzip2-src
tar xzf bzip2.tar.gz -C bzip2-src --strip-components=1
rm bzip2.tar.gz
fi
# Build static library with -fPIC
cd bzip2-src
make -j"$NJOBS" libbz2.a CC="${CC:-cc}" CFLAGS="-Wall -Winline -O2 -fPIC -D_FILE_OFFSET_BITS=64"
cd "$DIR"
# Copy to package install dir
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{lib,include}
# Library
cp bzip2-src/libbz2.a "$INSTALL_DIR/lib/"
# Headers
cp bzip2-src/bzlib.h "$INSTALL_DIR/include/"
# Clean up
rm -rf bzip2-src
echo "Installed bzip2 to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

10
bzip2/bzip2/__init__.py Normal file
View File

@@ -0,0 +1,10 @@
import os
DIR = os.path.join(os.path.dirname(__file__), "install")
LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include")
def smoketest():
assert os.path.isfile(os.path.join(LIB_DIR, "libbz2.a")), "libbz2.a not found"
assert os.path.isfile(os.path.join(INCLUDE_DIR, "bzlib.h")), "bzlib.h not found"

15
bzip2/pyproject.toml Normal file
View File

@@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "bzip2"
version = "1.0.8"
description = "bzip2 compression library (static build)"
requires-python = ">=3.8"
[tool.setuptools.packages.find]
include = ["bzip2*"]
[tool.setuptools.package-data]
bzip2 = ["install/**/*"]

61
bzip2/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildBzip2(build_py):
"""Run build.sh to compile bzip2 before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "bzip2", "install", "lib", "libbz2.a")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildBzip2}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

71
capnproto/build.sh Normal file
View File

@@ -0,0 +1,71 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="1.0.1"
INSTALL_DIR="$DIR/capnproto/install"
# Idempotent: skip if already built
if [ -x "$INSTALL_DIR/bin/capnp" ]; then
echo "capnproto already present, skipping build."
exit 0
fi
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
# Clone
if [ ! -d "capnproto-src" ]; then
git clone --depth 1 --branch "v${VERSION}" https://github.com/capnproto/capnproto.git capnproto-src
fi
# Build
PREFIX="$DIR/build/prefix"
mkdir -p "$DIR/build"
cmake -S capnproto-src -B "$DIR/build" \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_C_FLAGS="-fPIC" \
-DCMAKE_CXX_FLAGS="-fPIC" \
-DWITH_OPENSSL=OFF \
-DBUILD_TESTING=OFF \
-DBUILD_SHARED_LIBS=OFF
cmake --build "$DIR/build" -j"$NJOBS"
cmake --install "$DIR/build"
# Copy to package install dir
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{bin,lib,include}
# Binaries
cp "$PREFIX/bin/capnp" "$INSTALL_DIR/bin/"
cp "$PREFIX/bin/capnpc-c++" "$INSTALL_DIR/bin/"
ln -sf capnp "$INSTALL_DIR/bin/capnpc"
# Libraries (only the ones openpilot needs)
cp "$PREFIX/lib/libcapnp.a" "$INSTALL_DIR/lib/"
cp "$PREFIX/lib/libkj.a" "$INSTALL_DIR/lib/"
# Headers
cp -r "$PREFIX/include/capnp" "$INSTALL_DIR/include/"
cp -r "$PREFIX/include/kj" "$INSTALL_DIR/include/"
# Strip binaries and libs
strip "$INSTALL_DIR/bin/capnp" "$INSTALL_DIR/bin/capnpc-c++" 2>/dev/null || true
# Strip unused kj objects from libkj.a (not needed by openpilot)
for obj in filesystem.c++.o main.c++.o test-helpers.c++.o; do
ar d "$INSTALL_DIR/lib/libkj.a" "$obj" 2>/dev/null || true
done
# Clean up
rm -rf capnproto-src "$DIR/build"
echo "Installed capnproto to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

View File

@@ -0,0 +1,44 @@
import os
import sys
DIR = os.path.join(os.path.dirname(__file__), "install")
BIN_DIR = os.path.join(DIR, "bin")
LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include")
def _run(name):
binary = os.path.join(BIN_DIR, name)
env = os.environ.copy()
# ensure sibling binaries (e.g. capnpc-c++) are findable
env["PATH"] = BIN_DIR + ":" + env.get("PATH", "")
os.execvpe(binary, [binary] + sys.argv[1:], env)
def _run_capnp():
_run("capnp")
def _run_capnpc():
# capnpc is a symlink to capnp; capnp checks argv[0] to enter compile mode
binary = os.path.join(BIN_DIR, "capnp")
env = os.environ.copy()
env["PATH"] = BIN_DIR + ":" + env.get("PATH", "")
os.execvpe(binary, ["capnpc"] + sys.argv[1:], env)
def _run_capnpc_cpp():
_run("capnpc-c++")
def smoketest():
import subprocess
capnp = os.path.join(BIN_DIR, "capnp")
capnpc = os.path.join(BIN_DIR, "capnpc")
capnpc_cpp = os.path.join(BIN_DIR, "capnpc-c++")
env = os.environ.copy()
env["PATH"] = BIN_DIR + ":" + env.get("PATH", "")
subprocess.run([capnp, "--version"], check=True, env=env)
subprocess.run([capnpc, "--version"], check=True, env=env)
subprocess.run([capnpc_cpp, "--version"], check=True, env=env)

20
capnproto/pyproject.toml Normal file
View File

@@ -0,0 +1,20 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "capnproto"
version = "1.0.1"
description = "Cap'n Proto serialization library and compiler"
requires-python = ">=3.8"
[project.scripts]
capnp = "capnproto:_run_capnp"
capnpc = "capnproto:_run_capnpc"
"capnpc-c++" = "capnproto:_run_capnpc_cpp"
[tool.setuptools.packages.find]
include = ["capnproto*"]
[tool.setuptools.package-data]
capnproto = ["install/**/*"]

61
capnproto/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildCapnproto(build_py):
"""Run build.sh to compile capnproto before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "capnproto", "install", "bin", "capnp")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildCapnproto}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

42
cppcheck/build.sh Executable file
View File

@@ -0,0 +1,42 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="2.16.0"
INSTALL_DIR="$DIR/cppcheck/install"
# Idempotent: skip if already built
if [ -x "$INSTALL_DIR/cppcheck" ]; then
echo "cppcheck already present, skipping build."
exit 0
fi
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
# Clone
if [ ! -d "cppcheck-src" ]; then
git clone --depth 1 --branch "$VERSION" https://github.com/danmar/cppcheck.git cppcheck-src
fi
# Build
cd cppcheck-src
make MATCHCOMPILER=yes CXXFLAGS="-O2" -j"$NJOBS"
cd "$DIR"
# Install
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"
cp cppcheck-src/cppcheck "$INSTALL_DIR/"
cp -r cppcheck-src/addons "$INSTALL_DIR/"
cp -r cppcheck-src/cfg "$INSTALL_DIR/"
cp -r cppcheck-src/platforms "$INSTALL_DIR/"
strip "$INSTALL_DIR/cppcheck" 2>/dev/null || true
# Clean up
rm -rf cppcheck-src
echo "Installed cppcheck to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

View File

@@ -0,0 +1,16 @@
import os
import sys
DIR = os.path.join(os.path.dirname(__file__), "install")
def _run():
binary = os.path.join(DIR, "cppcheck")
os.execvp(binary, ["cppcheck"] + sys.argv[1:])
def smoketest():
import subprocess
binary = os.path.join(DIR, "cppcheck")
result = subprocess.run([binary, "--version"], capture_output=True, text=True, check=True)
print(result.stdout.strip())

18
cppcheck/pyproject.toml Normal file
View File

@@ -0,0 +1,18 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "cppcheck"
version = "2.16.0"
description = "Cppcheck static analysis tool"
requires-python = ">=3.8"
[project.scripts]
cppcheck = "cppcheck:_run"
[tool.setuptools.packages.find]
include = ["cppcheck*"]
[tool.setuptools.package-data]
cppcheck = ["install/**/*"]

61
cppcheck/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildCppcheck(build_py):
"""Run build.sh to compile cppcheck before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "cppcheck", "install", "cppcheck")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildCppcheck}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

34
eigen/build.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="3.4.0"
INSTALL_DIR="$DIR/eigen/install"
# Idempotent: skip if already present
if [ -d "$INSTALL_DIR/eigen3/Eigen" ]; then
echo "eigen already present, skipping download."
exit 0
fi
TARBALL="eigen-${VERSION}.tar.gz"
URL="https://gitlab.com/libeigen/eigen/-/archive/${VERSION}/${TARBALL}"
echo "Downloading Eigen ${VERSION} ..."
curl -fSL -o "$TARBALL" "$URL"
echo "Extracting headers ..."
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR/eigen3"
# Extract only the Eigen/ and unsupported/Eigen/ header directories
tar --strip-components=1 -xzf "$TARBALL" -C "$INSTALL_DIR/eigen3" \
"eigen-${VERSION}/Eigen" \
"eigen-${VERSION}/unsupported"
rm -f "$TARBALL"
echo "Installed eigen to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

9
eigen/eigen/__init__.py Normal file
View File

@@ -0,0 +1,9 @@
import os
DIR = os.path.join(os.path.dirname(__file__), "install")
INCLUDE_DIR = DIR
LIB_DIR = DIR # header-only; no libraries
def smoketest():
assert os.path.isdir(os.path.join(DIR, "eigen3", "Eigen")), "Eigen headers not found"

15
eigen/pyproject.toml Normal file
View File

@@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "eigen"
version = "3.4.0"
description = "Eigen C++ linear algebra headers"
requires-python = ">=3.8"
[tool.setuptools.packages.find]
include = ["eigen*"]
[tool.setuptools.package-data]
eigen = ["install/**/*"]

61
eigen/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildEigen(build_py):
"""Run build.sh to download Eigen headers before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "eigen", "install", "eigen3", "Eigen")
if not os.path.isdir(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildEigen}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

107
ffmpeg/build.sh Executable file
View File

@@ -0,0 +1,107 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
FFMPEG_VERSION="7.1"
INSTALL_DIR="$DIR/ffmpeg/install"
# Idempotent: skip if already built
if [ -x "$INSTALL_DIR/bin/ffmpeg" ]; then
echo "ffmpeg already present, skipping build."
exit 0
fi
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
PREFIX="$DIR/build/prefix"
mkdir -p "$DIR/build"
# --- Build zlib (static) ---
if [ ! -d "zlib-src" ]; then
git clone https://github.com/madler/zlib.git zlib-src
git -C zlib-src checkout da607da739fa6047df13e66a2af6b8bec7c2a498 # pin to v1.3.2
fi
cd zlib-src
./configure --prefix="$PREFIX" --static
make -j"$NJOBS"
make install
cd "$DIR"
# --- Build x264 (static) ---
if [ ! -d "x264-src" ]; then
git clone --depth 1 --branch stable https://code.videolan.org/videolan/x264.git x264-src
fi
cd x264-src
CFLAGS="-fno-finite-math-only" ./configure \
--prefix="$PREFIX" \
--enable-static \
--disable-shared \
--disable-cli \
--disable-opencl \
--enable-pic
make -j"$NJOBS"
make install
cd "$DIR"
# --- Build FFmpeg ---
if [ ! -d "ffmpeg-src" ]; then
git clone --depth 1 --branch "n${FFMPEG_VERSION}" https://github.com/FFmpeg/FFmpeg.git ffmpeg-src
fi
cd ffmpeg-src
PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" \
./configure \
--prefix="$PREFIX" \
--enable-gpl \
--enable-static \
--disable-shared \
--enable-zlib \
--enable-libx264 \
--enable-pic \
--disable-doc \
--disable-ffplay \
--disable-autodetect \
--disable-everything \
--enable-encoder=libx264,aac,ffvhuff,rawvideo,png,mjpeg \
--enable-decoder=h264,hevc,ffvhuff,aac,rawvideo,png,mjpeg,mp3,pcm_s16le \
--enable-muxer=mpegts,matroska,mp4,hevc,rawvideo,image2,null,mov,framehash \
--enable-demuxer=hevc,matroska,mpegts,mov,rawvideo,image2,aac,concat \
--enable-parser=h264,hevc,aac,mpegaudio \
--enable-protocol=file,pipe \
--enable-filter=blend,vflip,format,scale,aformat,anull,aresample,null \
--enable-bsf=extract_extradata,h264_mp4toannexb,hevc_mp4toannexb \
--extra-cflags="-I$PREFIX/include" \
--extra-ldflags="-L$PREFIX/lib"
make -j"$NJOBS"
make install
cd "$DIR"
# Copy to package install dir
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{bin,lib,include}
# Binaries
cp "$PREFIX/bin/ffmpeg" "$INSTALL_DIR/bin/"
cp "$PREFIX/bin/ffprobe" "$INSTALL_DIR/bin/"
# Libraries
for lib in libavformat.a libavcodec.a libavutil.a libswresample.a libx264.a libz.a; do
cp "$PREFIX/lib/$lib" "$INSTALL_DIR/lib/"
done
# Headers
for dir in libavformat libavcodec libavutil libswresample; do
cp -r "$PREFIX/include/$dir" "$INSTALL_DIR/include/"
done
# Strip binaries
strip "$INSTALL_DIR/bin/ffmpeg" "$INSTALL_DIR/bin/ffprobe" 2>/dev/null || true
# Clean up
rm -rf zlib-src x264-src ffmpeg-src "$DIR/build"
echo "Installed ffmpeg to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

29
ffmpeg/ffmpeg/__init__.py Normal file
View File

@@ -0,0 +1,29 @@
import os
import sys
DIR = os.path.join(os.path.dirname(__file__), "install")
BIN_DIR = os.path.join(DIR, "bin")
LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include")
def _run(name):
binary = os.path.join(BIN_DIR, name)
os.execvp(binary, [binary] + sys.argv[1:])
def _run_ffmpeg():
_run("ffmpeg")
def _run_ffprobe():
_run("ffprobe")
def smoketest():
import subprocess
ffmpeg = os.path.join(BIN_DIR, "ffmpeg")
ffprobe = os.path.join(BIN_DIR, "ffprobe")
subprocess.run([ffmpeg, "-version"], check=True)
subprocess.run([ffprobe, "-version"], check=True)

19
ffmpeg/pyproject.toml Normal file
View File

@@ -0,0 +1,19 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "ffmpeg"
version = "7.1.0"
description = "FFmpeg media tools and libraries (minimal build for openpilot)"
requires-python = ">=3.8"
[project.scripts]
ffmpeg = "ffmpeg:_run_ffmpeg"
ffprobe = "ffmpeg:_run_ffprobe"
[tool.setuptools.packages.find]
include = ["ffmpeg*"]
[tool.setuptools.package-data]
ffmpeg = ["install/**/*"]

61
ffmpeg/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildFFmpeg(build_py):
"""Run build.sh to compile ffmpeg before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "ffmpeg", "install", "bin", "ffmpeg")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildFFmpeg}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

View File

@@ -19,3 +19,9 @@ def _run_objcopy():
def _run_size():
_run("arm-none-eabi-size")
def smoketest():
import subprocess
gcc = os.path.join(TOOLCHAIN_DIR, "bin", "arm-none-eabi-gcc")
subprocess.run([gcc, "--version"], check=True)

56
git-lfs/build.sh Executable file
View File

@@ -0,0 +1,56 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="3.6.1"
INSTALL_DIR="$DIR/git_lfs/bin"
# Idempotent: skip if already present
if [ -x "$INSTALL_DIR/git-lfs" ]; then
echo "git-lfs already present, skipping download."
exit 0
fi
OS="$(uname -s)"
ARCH="$(uname -m)"
case "${OS}-${ARCH}" in
Linux-x86_64) PLATFORM="linux-amd64" ; EXT="tar.gz" ;;
Linux-aarch64) PLATFORM="linux-arm64" ; EXT="tar.gz" ;;
Darwin-arm64) PLATFORM="darwin-arm64" ; EXT="zip" ;;
*)
echo "Unsupported platform: ${OS}-${ARCH}" >&2
exit 1
;;
esac
FILENAME="git-lfs-${PLATFORM}-v${VERSION}.${EXT}"
URL="https://github.com/git-lfs/git-lfs/releases/download/v${VERSION}/${FILENAME}"
echo "Downloading $FILENAME ..."
curl -fSL -o "$FILENAME" "$URL"
echo "Extracting ..."
mkdir -p "$INSTALL_DIR"
if [ "$EXT" = "zip" ]; then
python3 -c "
import zipfile, sys
with zipfile.ZipFile('$FILENAME') as zf:
for info in zf.infolist():
if info.filename.endswith('/git-lfs'):
with open('$INSTALL_DIR/git-lfs', 'wb') as f:
f.write(zf.read(info))
break
"
else
tar --strip-components=1 -xzf "$FILENAME" -C "$INSTALL_DIR" --wildcards '*/git-lfs'
fi
chmod +x "$INSTALL_DIR/git-lfs"
rm -f "$FILENAME"
echo "Installed git-lfs to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

View File

@@ -0,0 +1,15 @@
import os
import sys
BIN_DIR = os.path.join(os.path.dirname(__file__), "bin")
def _run():
binary = os.path.join(BIN_DIR, "git-lfs")
os.execvp(binary, [binary] + sys.argv[1:])
def smoketest():
import subprocess
binary = os.path.join(BIN_DIR, "git-lfs")
subprocess.run([binary, "--version"], check=True)

18
git-lfs/pyproject.toml Normal file
View File

@@ -0,0 +1,18 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "git-lfs"
version = "3.6.1"
description = "Git Large File Storage extension"
requires-python = ">=3.8"
[project.scripts]
git-lfs = "git_lfs:_run"
[tool.setuptools.packages.find]
include = ["git_lfs*"]
[tool.setuptools.package-data]
git_lfs = ["bin/**/*"]

61
git-lfs/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildGitLfs(build_py):
"""Run build.sh to download git-lfs before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "git_lfs", "bin", "git-lfs")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildGitLfs}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

41
json11/build.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -euo pipefail
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="db00e9369a92aa74bf630a2ffb092a4b0b132c01"
INSTALL_DIR="$DIR/json11/install"
VERSION_FILE="$INSTALL_DIR/VERSION"
# Idempotent: skip if already built at this source revision.
if [ -f "$INSTALL_DIR/lib/libjson11.a" ] && [ -f "$INSTALL_DIR/include/json11/json11.hpp" ] && \
[ -f "$VERSION_FILE" ] && [ "$(cat "$VERSION_FILE")" = "$VERSION" ]; then
echo "json11 already present, skipping build."
exit 0
fi
if [ ! -d "$DIR/json11-src/.git" ]; then
git clone https://github.com/dropbox/json11.git json11-src
fi
git -C json11-src fetch --force origin
git -C json11-src checkout --force "$VERSION"
BUILD_DIR="$DIR/build"
rm -rf "$BUILD_DIR" "$INSTALL_DIR"
mkdir -p "$BUILD_DIR" "$INSTALL_DIR/lib" "$INSTALL_DIR/include/json11"
CXX="${CXX:-c++}"
AR="${AR:-ar}"
"$CXX" -std=c++11 -fPIC -O2 -c "$DIR/json11-src/json11.cpp" -o "$BUILD_DIR/json11.o"
"$AR" rcs "$INSTALL_DIR/lib/libjson11.a" "$BUILD_DIR/json11.o"
cp "$DIR/json11-src/json11.hpp" "$INSTALL_DIR/include/json11/json11.hpp"
echo "$VERSION" > "$VERSION_FILE"
# Keep workspace small and deterministic across builds.
rm -rf "$DIR/json11-src" "$BUILD_DIR"
echo "Installed json11 to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

10
json11/json11/__init__.py Normal file
View File

@@ -0,0 +1,10 @@
import os
DIR = os.path.join(os.path.dirname(__file__), "install")
LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include")
def smoketest():
assert os.path.isfile(os.path.join(LIB_DIR, "libjson11.a")), "libjson11.a not found"
assert os.path.isfile(os.path.join(INCLUDE_DIR, "json11", "json11.hpp")), "json11/json11.hpp not found"

15
json11/pyproject.toml Normal file
View File

@@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "json11"
version = "20170411.0"
description = "json11 JSON parser library (static build)"
requires-python = ">=3.8"
[tool.setuptools.packages.find]
include = ["json11*"]
[tool.setuptools.package-data]
json11 = ["install/**/*"]

61
json11/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildJson11(build_py):
"""Run build.sh to compile json11 before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "json11", "install", "lib", "libjson11.a")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildJson11}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

57
libjpeg/build.sh Executable file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="3.1.0"
INSTALL_DIR="$DIR/libjpeg/install"
# Idempotent: skip if already built
if [ -f "$INSTALL_DIR/lib/libjpeg.a" ]; then
echo "libjpeg already present, skipping build."
exit 0
fi
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
# Clone
if [ ! -d "libjpeg-turbo-src" ]; then
git clone --depth 1 --branch "${VERSION}" https://github.com/libjpeg-turbo/libjpeg-turbo.git libjpeg-turbo-src
fi
# Build
PREFIX="$DIR/build/prefix"
mkdir -p "$DIR/build"
cmake -S libjpeg-turbo-src -B "$DIR/build" \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCMAKE_C_FLAGS="-fPIC" \
-DENABLE_SHARED=OFF \
-DENABLE_STATIC=ON \
-DWITH_TURBOJPEG=OFF
cmake --build "$DIR/build" -j"$NJOBS"
cmake --install "$DIR/build"
# Copy to package install dir
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{lib,include}
# Library
cp "$PREFIX/lib/libjpeg.a" "$INSTALL_DIR/lib/"
# Headers
cp "$PREFIX/include/jpeglib.h" "$INSTALL_DIR/include/"
cp "$PREFIX/include/jconfig.h" "$INSTALL_DIR/include/"
cp "$PREFIX/include/jerror.h" "$INSTALL_DIR/include/"
cp "$PREFIX/include/jmorecfg.h" "$INSTALL_DIR/include/"
# Clean up
rm -rf libjpeg-turbo-src "$DIR/build"
echo "Installed libjpeg to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

View File

@@ -0,0 +1,10 @@
import os
DIR = os.path.join(os.path.dirname(__file__), "install")
LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include")
def smoketest():
assert os.path.isfile(os.path.join(LIB_DIR, "libjpeg.a")), "libjpeg.a not found"
assert os.path.isfile(os.path.join(INCLUDE_DIR, "jpeglib.h")), "jpeglib.h not found"

15
libjpeg/pyproject.toml Normal file
View File

@@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "libjpeg"
version = "3.1.0"
description = "libjpeg-turbo JPEG library (static build)"
requires-python = ">=3.8"
[tool.setuptools.packages.find]
include = ["libjpeg*"]
[tool.setuptools.package-data]
libjpeg = ["install/**/*"]

61
libjpeg/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildLibjpeg(build_py):
"""Run build.sh to compile libjpeg-turbo before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "libjpeg", "install", "lib", "libjpeg.a")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildLibjpeg}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

56
libyuv/build.sh Executable file
View File

@@ -0,0 +1,56 @@
#!/usr/bin/env bash
set -euo pipefail
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="6067afde563c3946eebd94f146b3824ab7a97a9c"
INSTALL_DIR="$DIR/libyuv/install"
VERSION_FILE="$INSTALL_DIR/VERSION"
# Idempotent: skip if already built at this source revision.
if [ -f "$INSTALL_DIR/lib/libyuv.a" ] && [ -f "$VERSION_FILE" ] && [ "$(cat "$VERSION_FILE")" = "$VERSION" ]; then
echo "libyuv already present, skipping build."
exit 0
fi
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
if [ ! -d "libyuv-src/.git" ]; then
git clone https://chromium.googlesource.com/libyuv/libyuv libyuv-src
fi
git -C libyuv-src fetch --force origin
git -C libyuv-src checkout --force "$VERSION"
BUILD_DIR="$DIR/build/build"
rm -rf "$DIR/build"
mkdir -p "$BUILD_DIR"
cmake -S "$DIR/libyuv-src" -B "$BUILD_DIR" \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_C_FLAGS="-fPIC" \
-DCMAKE_CXX_FLAGS="-fPIC"
cmake --build "$BUILD_DIR" -j"$NJOBS"
LIBYUV_STATIC="$(find "$BUILD_DIR" -name "libyuv.a" -type f | head -n 1)"
if [ -z "$LIBYUV_STATIC" ]; then
echo "libyuv.a not found in build output" >&2
exit 1
fi
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{lib,include}
cp "$LIBYUV_STATIC" "$INSTALL_DIR/lib/libyuv.a"
cp -r "$DIR/libyuv-src/include/." "$INSTALL_DIR/include/"
echo "$VERSION" > "$VERSION_FILE"
# Keep workspace small and deterministic across builds.
rm -rf "$DIR/libyuv-src" "$DIR/build"
echo "Installed libyuv to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

11
libyuv/libyuv/__init__.py Normal file
View File

@@ -0,0 +1,11 @@
import os
DIR = os.path.join(os.path.dirname(__file__), "install")
LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include")
def smoketest():
assert os.path.isfile(os.path.join(LIB_DIR, "libyuv.a")), "libyuv.a not found"
assert os.path.isfile(os.path.join(INCLUDE_DIR, "libyuv.h")), "libyuv.h not found"
assert os.path.isfile(os.path.join(INCLUDE_DIR, "libyuv", "version.h")), "libyuv/version.h not found"

15
libyuv/pyproject.toml Normal file
View File

@@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "libyuv"
version = "1922.0"
description = "libyuv image processing library (static build)"
requires-python = ">=3.8"
[tool.setuptools.packages.find]
include = ["libyuv*"]
[tool.setuptools.package-data]
libyuv = ["install/**/*"]

61
libyuv/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildLibyuv(build_py):
"""Run build.sh to compile libyuv before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "libyuv", "install", "lib", "libyuv.a")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildLibyuv}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

73
ncurses/build.sh Executable file
View File

@@ -0,0 +1,73 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="6.5"
INSTALL_DIR="$DIR/ncurses/install"
# Idempotent: skip if already built
if [ -f "$INSTALL_DIR/lib/libncurses.a" ]; then
echo "ncurses already present, skipping build."
exit 0
fi
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
# Download
TARBALL="ncurses-${VERSION}.tar.gz"
if [ ! -f "$TARBALL" ]; then
curl -fsSL "https://ftp.gnu.org/gnu/ncurses/${TARBALL}" -o "$TARBALL"
fi
# Extract
if [ ! -d "ncurses-${VERSION}" ]; then
tar xf "$TARBALL"
fi
# Build
PREFIX="$DIR/build/prefix"
mkdir -p "$DIR/build"
cd "ncurses-${VERSION}"
CFLAGS="-fPIC" ./configure \
--prefix="$PREFIX" \
--without-shared \
--with-normal \
--without-debug \
--without-cxx \
--without-cxx-binding \
--without-ada \
--without-manpages \
--without-progs \
--without-tests \
--without-dlsym \
--enable-overwrite
make -j"$NJOBS"
# Only install libs and headers; skip terminfo database (fails on macOS CI)
make install.libs install.includes
cd "$DIR"
# Copy to package install dir
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{lib,include}
# Libraries (ncurses 6.x builds wide-char by default; provide as libncurses.a)
cp "$PREFIX/lib/libncursesw.a" "$INSTALL_DIR/lib/libncurses.a" 2>/dev/null \
|| cp "$PREFIX/lib/libncurses.a" "$INSTALL_DIR/lib/"
# Headers (--enable-overwrite puts them directly in include/)
cp "$PREFIX/include/ncurses.h" "$INSTALL_DIR/include/"
cp "$PREFIX/include/curses.h" "$INSTALL_DIR/include/"
cp "$PREFIX/include/ncurses_dll.h" "$INSTALL_DIR/include/"
cp "$PREFIX/include/unctrl.h" "$INSTALL_DIR/include/"
cp "$PREFIX/include/term.h" "$INSTALL_DIR/include/"
cp "$PREFIX/include/termcap.h" "$INSTALL_DIR/include/"
# Clean up
rm -rf "ncurses-${VERSION}" "$TARBALL" "$DIR/build"
echo "Installed ncurses to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

View File

@@ -0,0 +1,10 @@
import os
DIR = os.path.join(os.path.dirname(__file__), "install")
LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include")
def smoketest():
assert os.path.isfile(os.path.join(LIB_DIR, "libncurses.a")), "libncurses.a not found"
assert os.path.isfile(os.path.join(INCLUDE_DIR, "ncurses.h")), "ncurses.h not found"

15
ncurses/pyproject.toml Normal file
View File

@@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "ncurses"
version = "6.5"
description = "ncurses terminal library (static build)"
requires-python = ">=3.8"
[tool.setuptools.packages.find]
include = ["ncurses*"]
[tool.setuptools.package-data]
ncurses = ["install/**/*"]

61
ncurses/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildNcurses(build_py):
"""Run build.sh to compile ncurses before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "ncurses", "install", "lib", "libncurses.a")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildNcurses}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

75
openssl3/build.sh Executable file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="3.4.1"
INSTALL_DIR="$DIR/openssl3/install"
# Idempotent: skip if already built
if [ -f "$INSTALL_DIR/lib/libcrypto.a" ]; then
echo "openssl already present, skipping build."
exit 0
fi
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
# Download
TARBALL="openssl-${VERSION}.tar.gz"
if [ ! -d "openssl-src" ]; then
curl -fSL -o "$TARBALL" "https://github.com/openssl/openssl/releases/download/openssl-${VERSION}/${TARBALL}"
mkdir -p openssl-src
tar -xf "$TARBALL" -C openssl-src --strip-components=1
rm -f "$TARBALL"
fi
# Configure
PREFIX="$DIR/build/prefix"
cd openssl-src
if [ "$(uname)" = "Darwin" ]; then
TARGET="darwin64-arm64-cc"
else
MACHINE="$(uname -m)"
if [ "$MACHINE" = "x86_64" ]; then
TARGET="linux-x86_64"
elif [ "$MACHINE" = "aarch64" ]; then
TARGET="linux-aarch64"
else
TARGET="linux-${MACHINE}"
fi
fi
./Configure "$TARGET" \
--prefix="$PREFIX" \
--libdir=lib \
no-shared \
no-tests \
no-docs \
no-apps \
-fPIC \
-Os
# Build
make -j"$NJOBS"
make install_sw
cd "$DIR"
# Copy to package install dir
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{lib,include}
# Libraries
cp "$PREFIX/lib/libcrypto.a" "$INSTALL_DIR/lib/"
cp "$PREFIX/lib/libssl.a" "$INSTALL_DIR/lib/"
# Headers
cp -r "$PREFIX/include/openssl" "$INSTALL_DIR/include/"
# Clean up
rm -rf openssl-src "$DIR/build"
echo "Installed openssl to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

View File

@@ -0,0 +1,11 @@
import os
DIR = os.path.join(os.path.dirname(__file__), "install")
LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include")
def smoketest():
assert os.path.isfile(os.path.join(LIB_DIR, "libcrypto.a")), "libcrypto.a not found"
assert os.path.isfile(os.path.join(LIB_DIR, "libssl.a")), "libssl.a not found"
assert os.path.isdir(os.path.join(INCLUDE_DIR, "openssl")), "openssl headers not found"

15
openssl3/pyproject.toml Normal file
View File

@@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "openssl3"
version = "3.4.1"
description = "OpenSSL cryptography library (static build)"
requires-python = ">=3.8"
[tool.setuptools.packages.find]
include = ["openssl3*"]
[tool.setuptools.package-data]
openssl3 = ["install/**/*"]

61
openssl3/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildOpenssl(build_py):
"""Run build.sh to compile OpenSSL before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "openssl3", "install", "lib", "libcrypto.a")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildOpenssl}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

19
pyproject.toml Normal file
View File

@@ -0,0 +1,19 @@
[tool.uv.workspace]
members = [
"bzip2",
"capnproto",
"cppcheck",
"eigen",
"ffmpeg",
"gcc-arm-none-eabi",
"git-lfs",
"json11",
"libjpeg",
"libyuv",
"ncurses",
"openssl3",
"python3-dev",
"raylib",
"zeromq",
"zstd",
]

44
python3-dev/build.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="3.12.8"
INSTALL_DIR="$DIR/python3_dev/install"
# Idempotent: skip if already present
if [ -f "$INSTALL_DIR/include/Python.h" ]; then
echo "python3-dev headers already present, skipping."
exit 0
fi
TARBALL="Python-${VERSION}.tgz"
URL="https://www.python.org/ftp/python/${VERSION}/${TARBALL}"
echo "Downloading CPython ${VERSION} source ..."
curl -fSL -o "$TARBALL" "$URL"
echo "Extracting ..."
tar xzf "$TARBALL"
cd "Python-${VERSION}"
# Run configure to generate pyconfig.h for this platform
echo "Running configure to generate pyconfig.h ..."
./configure --disable-shared --without-ensurepip > /dev/null 2>&1
cd "$DIR"
# Copy headers
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR/include"
cp -r "Python-${VERSION}/Include/"* "$INSTALL_DIR/include/"
cp "Python-${VERSION}/pyconfig.h" "$INSTALL_DIR/include/"
# Clean up
rm -rf "Python-${VERSION}" "$TARBALL"
echo "Installed python3-dev headers to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

View File

@@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "python3-dev"
version = "3.12.8"
description = "CPython development headers"
requires-python = ">=3.8"
[tool.setuptools.packages.find]
include = ["python3_dev*"]
[tool.setuptools.package-data]
python3_dev = ["install/**/*"]

View File

@@ -0,0 +1,9 @@
import os
DIR = os.path.join(os.path.dirname(__file__), "install")
INCLUDE_DIR = os.path.join(DIR, "include")
def smoketest():
assert os.path.isfile(os.path.join(INCLUDE_DIR, "Python.h")), "Python.h not found"
assert os.path.isfile(os.path.join(INCLUDE_DIR, "pyconfig.h")), "pyconfig.h not found"

61
python3-dev/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildPython3Dev(build_py):
"""Run build.sh to download CPython headers before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "python3_dev", "install", "include", "Python.h")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildPython3Dev}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

4
raylib/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
raylib-src/
raylib/install/
raylib/*.modified
raylib/_raylib_cffi*

135
raylib/build.sh Executable file
View File

@@ -0,0 +1,135 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
INSTALL_DIR="$DIR/raylib/install"
# Idempotent: skip if already fully built
# On x86_64 Linux, also require the offscreen variant
NEED_OFFSCREEN=0
if [[ "$(uname)" == "Linux" && "$(uname -m)" == "x86_64" ]]; then
NEED_OFFSCREEN=1
fi
if [ -f "$INSTALL_DIR/lib/libraylib.a" ]; then
if [ "$NEED_OFFSCREEN" -eq 0 ] || [ -f "$INSTALL_DIR/lib/libraylib_offscreen.a" ]; then
echo "raylib already present, skipping build."
exit 0
fi
fi
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
# Detect platform: PLATFORM_COMMA for comma devices, PLATFORM_DESKTOP otherwise
RAYLIB_PLATFORM="${RAYLIB_PLATFORM:-PLATFORM_DESKTOP}"
if [ -f /TICI ]; then
RAYLIB_PLATFORM="PLATFORM_COMMA"
fi
export RAYLIB_PLATFORM
# Install build dependencies
if [[ "$(uname)" == "Linux" ]]; then
if [ "$RAYLIB_PLATFORM" = "PLATFORM_COMMA" ]; then
# comma device: needs DRM/EGL/GLES headers (usually already present on AGNOS)
# apt may fail on devices due to read-only rootfs or package conflicts — that's OK
if command -v apt-get &>/dev/null; then
if [ "$(id -u)" -eq 0 ]; then
apt-get update && apt-get install -y libdrm-dev libgbm-dev libgles2-mesa-dev libegl1-mesa-dev || true
else
sudo apt-get update && sudo apt-get install -y libdrm-dev libgbm-dev libgles2-mesa-dev libegl1-mesa-dev || true
fi
fi
elif [ "$RAYLIB_PLATFORM" = "PLATFORM_OFFSCREEN" ]; then
# offscreen (CI): needs EGL/GL dev packages (no X11)
if command -v apt-get &>/dev/null; then
if [ "$(id -u)" -eq 0 ]; then
apt-get update && apt-get install -y libegl-dev libgl-dev
else
sudo apt-get update && sudo apt-get install -y libegl-dev libgl-dev
fi
fi
else
# desktop: needs X11/GL dev packages
if command -v dnf &>/dev/null; then
dnf install -y libX11-devel libXcursor-devel libXrandr-devel libXinerama-devel libXi-devel mesa-libGL-devel
elif command -v apt-get &>/dev/null; then
if [ "$(id -u)" -eq 0 ]; then
apt-get update && apt-get install -y libxcursor-dev libxi-dev libxinerama-dev libxrandr-dev libgl-dev
else
sudo apt-get update && sudo apt-get install -y libxcursor-dev libxi-dev libxinerama-dev libxrandr-dev libgl-dev
fi
fi
fi
fi
# Clone and build raylib C library
RAYLIB_COMMIT="d9d7cc1353ec0f73c97e84ddf0973983d1ee25e2"
if [ ! -d "raylib-src" ]; then
git clone -b platform-offscreen --no-tags https://github.com/commaai/raylib.git raylib-src
fi
cd raylib-src
git fetch origin "$RAYLIB_COMMIT"
git reset --hard "$RAYLIB_COMMIT"
git clean -xdff .
cd src
make -j"$NJOBS" PLATFORM="$RAYLIB_PLATFORM"
cd "$DIR"
# Install lib + headers
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{lib,include}
cp raylib-src/src/libraylib.a "$INSTALL_DIR/lib/"
cp raylib-src/src/raylib.h raylib-src/src/raymath.h raylib-src/src/rlgl.h "$INSTALL_DIR/include/"
# On x86_64 Linux, also build the offscreen variant for CI headless rendering
if [[ "$(uname)" == "Linux" && "$(uname -m)" == "x86_64" && "$RAYLIB_PLATFORM" != "PLATFORM_OFFSCREEN" ]]; then
echo "Building offscreen variant..."
# Install EGL/GL dev packages needed for offscreen build + bundling
if command -v dnf &>/dev/null; then
dnf install -y mesa-libEGL-devel mesa-libGL-devel libglvnd-opengl libglvnd-core-devel 2>/dev/null || true
elif command -v apt-get &>/dev/null; then
if [ "$(id -u)" -eq 0 ]; then
apt-get update && apt-get install -y libegl-dev libgl-dev
else
sudo apt-get update && sudo apt-get install -y libegl-dev libgl-dev
fi
fi
cd raylib-src/src
make clean
make -j"$NJOBS" PLATFORM=PLATFORM_OFFSCREEN
cp libraylib.a "$INSTALL_DIR/lib/libraylib_offscreen.a"
cd "$DIR"
# Bundle GLVND dispatchers so offscreen rendering works without extra system packages
MESA_DIR="$INSTALL_DIR/lib/mesa"
mkdir -p "$MESA_DIR"
ldconfig 2>/dev/null || true
for lib in libEGL.so.1 libOpenGL.so.0 libGLdispatch.so.0; do
src="$(ldconfig -p 2>/dev/null | grep "$lib" | grep -E 'x86.64|libc6,' | awk '{print $NF}' | head -1)"
if [ -n "$src" ] && [ -f "$src" ]; then
cp -L "$src" "$MESA_DIR/"
# Create unversioned symlink for the linker
base="${lib%%.so.*}"
ln -sf "$lib" "$MESA_DIR/${base}.so"
fi
done
fi
# Download raygui header
RAYGUI_COMMIT="76b36b597edb70ffaf96f046076adc20d67e7827"
curl -fsSLo "$INSTALL_DIR/include/raygui.h" \
"https://raw.githubusercontent.com/raysan5/raygui/$RAYGUI_COMMIT/src/raygui.h"
# Clean up source
rm -rf raylib-src
echo "Installed raylib to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

16
raylib/pyproject.toml Normal file
View File

@@ -0,0 +1,16 @@
[build-system]
requires = ["setuptools>=64", "wheel", "cffi>=1.17.1"]
build-backend = "setuptools.build_meta"
[project]
name = "raylib"
version = "5.5.0.8"
description = "raylib + pyray Python bindings (commaai fork)"
requires-python = ">=3.8"
dependencies = ["cffi>=1.17.1"]
[tool.setuptools.packages.find]
include = ["raylib*", "pyray*"]
[tool.setuptools.package-data]
raylib = ["install/**/*", "_raylib_cffi*.so"]

159
raylib/pyray/__init__.py Normal file
View File

@@ -0,0 +1,159 @@
# Copyright (c) 2021 Richard Smith and others
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# This Source Code may also be made available under the following Secondary
# licenses when the conditions for such availability set forth in the Eclipse
# Public License, v. 2.0 are satisfied: GNU General Public License, version 2
# with the GNU Classpath Exception which is
# available at https://www.gnu.org/software/classpath/license.html.
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
import re
import weakref
from array import array
from raylib import rl, ffi
from raylib.colors import *
try:
from raylib.defines import *
except AttributeError:
print("sorry deprecated enums dont work on dynamic version")
from inspect import getmembers, isbuiltin
current_module = __import__(__name__)
def _underscore(word: str) -> str:
word = re.sub('2D$', '_2d', word)
word = re.sub('3D$', '_3d', word)
word = re.sub(r"([A-Z]+)([A-Z][a-z])", r'\1_\2', word)
word = re.sub(r"([a-z\d])([A-Z])", r'\1_\2', word)
word = word.replace("-", "_")
return word.lower()
def _wrap_function(original_func):
c_args = [str(x) for x in ffi.typeof(original_func).args]
number_of_args = len(c_args)
c_arg_is_pointer = [x.kind == 'pointer' for x in ffi.typeof(original_func).args]
c_arg_is_string = [str(x) == "<ctype 'char *'>" for x in ffi.typeof(original_func).args]
# c_arg_is_void_pointer = [str(x) == "<ctype 'void *'>" for x in ffi.typeof(original_func).args]
def wrapped_func(*args):
args = list(args) # tuple is immutable, converting it to mutable list is faster than constructing new list!
for i in range(number_of_args):
try:
arg = args[i]
except IndexError:
raise RuntimeError(f"function requires {number_of_args} arguments but you supplied {len(args)}")
if c_arg_is_pointer[i]:
if c_arg_is_string[i]: # we assume c_arg is 'const char *'
try: # if it's a non-const 'char *' then user should be supplying a ctype pointer, not a Python
# string
args[i] = arg.encode('utf-8') # in that case this conversion will fail
except AttributeError: # but those functions are uncommon, so quicker on average to try the
# conversion
pass # and ignore the exception
# if user supplied a Python string but c_arg is a 'char *' not a 'const char *' then we ought to raise
# exception because its an out
# parameter and user should supply a ctype pointer, but we cant because cffi cant detect 'const'
# so we would have to get the info from raylib.json
elif c_args[i] == "<ctype 'char * *'>" and type(arg) is list:
args[i] = [ffi.new("char[]", x.encode('utf-8')) for x in arg]
elif is_cdata(arg) and "*" not in str(arg):
args[i] = ffi.addressof(arg)
elif arg is None:
args[i] = ffi.NULL
elif not is_cdata(arg):
if c_args[i] == "<ctype '_Bool *'>":
raise TypeError(
f"Argument {i} ({arg}) must be a ctype bool, please create one with: pyray.ffi.new('bool "
f"*', True)")
elif c_args[i] == "<ctype 'int *'>":
raise TypeError(
f"Argument {i} ({arg}) must be a ctype int, please create one with: pyray.ffi.new('int "
f"*', 1)")
elif c_args[i] == "<ctype 'float *'>":
raise TypeError(
f"Argument {i} ({arg}) must be a ctype float, please create one with: pyray.ffi.new("
f"'float *', 1.0)")
elif c_args[i] == "<ctype 'void *'>":
# we could assume it's a string and try to convert it but we would have to be sure it's
# const. that seems reasonable assumption for char* but i'm not confident it is for void*
raise TypeError(
f"Argument {i} ({arg}) must be a cdata pointer. Type is void so I don't know what type it "
f"should be."
"If it's a const string you can create it with pyray.ffi.new('char []', b\"whatever\") . "
"If it's a float you can create it with pyray.ffi.new('float *', 1.0)")
result = original_func(*args)
if result is None:
return
elif is_cdata(result) and str(result).startswith("<cdata 'char *'"):
if str(result) == "<cdata 'char *' NULL>":
return ""
else:
return ffi.string(result).decode('utf-8')
else:
return result
# apparently pypy and cpython produce different types so check for both
def is_cdata(arg):
return str(type(arg)) == "<class '_cffi_backend.__CDataOwn'>" or str(
type(arg)) == "<class '_cffi_backend._CDataBase'>"
return wrapped_func
global_weakkeydict = weakref.WeakKeyDictionary()
def _make_struct_constructor_function(struct):
def func(*args):
# print(struct, args)
modified_args = []
for (field, arg) in zip(ffi.typeof(struct).fields, args):
# print("arg:", str(arg), "field:", field[1], "field type:", field[1].type, "type(arg):", str(type(arg)))
if arg is None:
arg = ffi.NULL
elif (field[1].type.kind == 'pointer'
and (str(type(arg)) == "<class 'numpy.ndarray'>"
or isinstance(arg, (array, bytes, bytearray, memoryview)))):
arg = ffi.from_buffer(field[1].type, arg)
modified_args.append(arg)
s = ffi.new(f"struct {struct} *", modified_args)[0]
global_weakkeydict[s] = modified_args
return s
return func
for name, attr in getmembers(rl):
# print(name, attr)
uname = _underscore(name)
if isbuiltin(attr) or str(type(attr)) == "<class '_cffi_backend.__FFIFunctionWrapper'>" or str(
type(attr)) == "<class '_cffi_backend._CDataBase'>":
# print(attr.__call__)
# print(attr.__doc__)
# print(dir(attr))
# print(dir(attr.__repr__))
f = _wrap_function(attr)
setattr(current_module, uname, f)
else:
setattr(current_module, name, attr)
for struct in ffi.list_types()[0]:
f = _make_struct_constructor_function(struct)
setattr(current_module, struct, f)
# overwrite ffi enums with our own
from raylib.enums import *
def text_format(*args):
raise RuntimeError("Use Python f-strings etc rather than calling text_format().")

71
raylib/raylib/__init__.py Normal file
View File

@@ -0,0 +1,71 @@
import os
import platform as _platform
DIR = os.path.join(os.path.dirname(__file__), "install")
LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include")
def _detect_platform():
"""Auto-detect the raylib platform. In CI on Linux x86_64, use offscreen EGL rendering."""
explicit = os.environ.get("RAYLIB_PLATFORM", "")
if explicit:
return explicit
if os.environ.get("CI") and _platform.system() == "Linux" and _platform.machine() == "x86_64":
return "PLATFORM_OFFSCREEN"
return ""
def smoketest():
assert os.path.isfile(os.path.join(LIB_DIR, "libraylib.a")), "libraylib.a not found"
assert os.path.isfile(os.path.join(INCLUDE_DIR, "raylib.h")), "raylib.h not found"
# Build CFFI extension on first import if not already compiled,
# or rebuild if the target platform changed since last build.
def _ensure_cffi_built():
import glob
import subprocess
import sys
pkg_dir = os.path.dirname(__file__)
platform_marker = os.path.join(pkg_dir, ".raylib_platform")
requested = _detect_platform()
# Export so build.py picks it up
if requested:
os.environ["RAYLIB_PLATFORM"] = requested
# Mesa llvmpipe for software rendering in headless CI
if requested == "PLATFORM_OFFSCREEN":
os.environ.setdefault("LIBGL_ALWAYS_SOFTWARE", "1")
cffi_files = glob.glob(os.path.join(pkg_dir, "_raylib_cffi*"))
# Rebuild if platform changed
if cffi_files and requested:
built_for = open(platform_marker).read().strip() if os.path.isfile(platform_marker) else ""
if built_for != requested:
for f in cffi_files:
os.remove(f)
cffi_files = []
if not cffi_files:
build_script = os.path.join(pkg_dir, "build.py")
if os.path.isfile(build_script) and os.path.isfile(os.path.join(LIB_DIR, "libraylib.a")):
try:
subprocess.check_call([sys.executable, build_script], cwd=os.path.dirname(pkg_dir))
with open(platform_marker, "w") as f:
f.write(requested)
except subprocess.CalledProcessError:
pass
_ensure_cffi_built()
# CFFI bindings (available when graphics libraries are present)
try:
from ._raylib_cffi import ffi, lib as rl
from raylib._raylib_cffi.lib import * # noqa: F403
from raylib.colors import * # noqa: F403
from raylib.defines import * # noqa: F403
from .version import __version__
except (ImportError, OSError):
pass

137
raylib/raylib/build.py Normal file
View File

@@ -0,0 +1,137 @@
# Based on commaai/raylib-python-cffi (commit ab0191f)
# Modified to use local install paths and compile standalone (no cffi_modules)
import re
import os
import platform
import subprocess
import time
from cffi import FFI
HERE = os.path.dirname(os.path.abspath(__file__))
RAYLIB_INCLUDE_PATH = os.path.join(HERE, "install", "include")
RAYLIB_LIB_PATH = os.path.join(HERE, "install", "lib")
RAYLIB_PLATFORM = os.getenv("RAYLIB_PLATFORM", "")
ffibuilder = FFI()
def check_raylib_installed():
return os.path.isfile(os.path.join(RAYLIB_LIB_PATH, 'libraylib.a'))
def pre_process_header(filename, remove_function_bodies=False):
print("Pre-processing " + filename)
file = open(filename, "r")
filetext = "".join([line for line in file if '#include' not in line])
command = ['gcc', '-CC', '-P', '-undef', '-nostdinc', '-DRL_MATRIX_TYPE',
'-DRL_QUATERNION_TYPE', '-DRL_VECTOR4_TYPE', '-DRL_VECTOR3_TYPE', '-DRL_VECTOR2_TYPE',
'-DRLAPI=', '-DPHYSACDEF=', '-DRAYGUIDEF=', '-DRMAPI=',
'-dDI', '-E', '-']
filetext = subprocess.run(command, text=True, input=filetext, stdout=subprocess.PIPE).stdout
filetext = filetext.replace("va_list", "void *")
if remove_function_bodies:
filetext = re.sub('\n{\n(.|\n)*?\n}\n', ';', filetext)
filetext = "\n".join([line for line in filetext.splitlines() if not line.startswith("#")])
modified_path = os.path.join(HERE, os.path.basename(filename) + ".modified")
with open(modified_path, "w") as f:
f.write(filetext)
return filetext
def check_header_exists(file):
if not os.path.isfile(file):
print(f"\nWARNING: {file} not found. Build will not contain these extra functions.\n")
time.sleep(1)
return False
return True
def build_ffi():
"""Set up the FFI builder. Must be called after libraylib.a and headers exist."""
if not check_raylib_installed():
raise Exception("ERROR: raylib not found. Please run build.sh first.")
raylib_h = os.path.join(RAYLIB_INCLUDE_PATH, "raylib.h")
rlgl_h = os.path.join(RAYLIB_INCLUDE_PATH, "rlgl.h")
raymath_h = os.path.join(RAYLIB_INCLUDE_PATH, "raymath.h")
for h in (raylib_h, rlgl_h, raymath_h):
if not os.path.isfile(h):
raise Exception(f"ERROR: {h} not found. Please run build.sh first.")
ffi_includes = """
#include "raylib.h"
#include "rlgl.h"
#include "raymath.h"
"""
raygui_h = os.path.join(RAYLIB_INCLUDE_PATH, "raygui.h")
if check_header_exists(raygui_h):
ffi_includes += """
#define RAYGUI_IMPLEMENTATION
#define RAYGUI_SUPPORT_RICONS
#include "raygui.h"
"""
ffibuilder.cdef(pre_process_header(raylib_h))
ffibuilder.cdef(pre_process_header(rlgl_h))
ffibuilder.cdef(pre_process_header(raymath_h, True))
if os.path.isfile(raygui_h):
ffibuilder.cdef(pre_process_header(raygui_h))
if platform.system() == "Darwin":
print("BUILDING FOR MAC")
extra_link_args = [
os.path.join(RAYLIB_LIB_PATH, 'libraylib.a'),
'-framework', 'OpenGL',
'-framework', 'Cocoa',
'-framework', 'IOKit',
'-framework', 'CoreFoundation',
'-framework', 'CoreVideo',
]
libraries = []
extra_compile_args = ["-Wno-error=incompatible-function-pointer-types"]
else:
print("BUILDING FOR LINUX")
extra_link_args = [
f'-L{RAYLIB_LIB_PATH}', '-lraylib',
'-lm', '-lpthread', '-lGL',
'-lrt', '-ldl', '-lpthread', '-latomic',
]
if RAYLIB_PLATFORM == "PLATFORM_COMMA":
extra_link_args.remove('-lGL')
extra_link_args += ['-lGLESv2', '-lEGL', '-lgbm', '-ldrm']
elif RAYLIB_PLATFORM == "PLATFORM_OFFSCREEN":
# Use offscreen variant if available, otherwise fall back to default
offscreen_lib = os.path.join(RAYLIB_LIB_PATH, 'libraylib_offscreen.a')
if os.path.isfile(offscreen_lib):
extra_link_args[extra_link_args.index('-lraylib')] = '-lraylib_offscreen'
extra_link_args.remove('-lGL')
# Use bundled GLVND dispatchers if available, with RPATH for runtime
mesa_dir = os.path.join(RAYLIB_LIB_PATH, 'mesa')
if os.path.isdir(mesa_dir):
extra_link_args += [f'-L{mesa_dir}', f'-Wl,-rpath,$ORIGIN/install/lib/mesa']
extra_link_args += ['-lOpenGL', '-lEGL']
else:
extra_link_args += ['-lX11']
extra_compile_args = ["-Wno-incompatible-pointer-types"]
libraries = []
print("extra_link_args: " + str(extra_link_args))
ffibuilder.set_source("raylib._raylib_cffi",
ffi_includes,
py_limited_api=True,
include_dirs=[RAYLIB_INCLUDE_PATH],
extra_link_args=extra_link_args,
extra_compile_args=extra_compile_args,
libraries=libraries)
if __name__ == "__main__":
build_ffi()
# compile with output going to the package root (parent of raylib/)
pkg_root = os.path.dirname(HERE)
ffibuilder.compile(verbose=True, tmpdir=pkg_root)

41
raylib/raylib/colors.py Normal file
View File

@@ -0,0 +1,41 @@
# Copyright (c) 2021 Richard Smith and others
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# This Source Code may also be made available under the following Secondary
# licenses when the conditions for such availability set forth in the Eclipse
# Public License, v. 2.0 are satisfied: GNU General Public License, version 2
# with the GNU Classpath Exception which is
# available at https://www.gnu.org/software/classpath/license.html.
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
LIGHTGRAY =( 200, 200, 200, 255 )
GRAY =( 130, 130, 130, 255 )
DARKGRAY =( 80, 80, 80, 255 )
YELLOW =( 253, 249, 0, 255 )
GOLD =( 255, 203, 0, 255 )
ORANGE =( 255, 161, 0, 255 )
PINK =( 255, 109, 194, 255 )
RED =( 230, 41, 55, 255 )
MAROON =( 190, 33, 55, 255 )
GREEN =( 0, 228, 48, 255 )
LIME =( 0, 158, 47, 255 )
DARKGREEN =( 0, 117, 44, 255 )
SKYBLUE =( 102, 191, 255, 255 )
BLUE =( 0, 121, 241, 255 )
DARKBLUE =( 0, 82, 172, 255 )
PURPLE =( 200, 122, 255, 255 )
VIOLET =( 135, 60, 190, 255 )
DARKPURPLE =( 112, 31, 126, 255 )
BEIGE =( 211, 176, 131, 255 )
BROWN =( 127, 106, 79, 255 )
DARKBROWN =( 76, 63, 47, 255 )
WHITE =( 255, 255, 255, 255 )
BLACK =( 0, 0, 0, 255 )
BLANK =( 0, 0, 0, 0 )
MAGENTA =( 255, 0, 255, 255 )
RAYWHITE =( 245, 245, 245, 255 )

510
raylib/raylib/defines.py Normal file
View File

@@ -0,0 +1,510 @@
import raylib
RAYLIB_VERSION_MAJOR: int = 5
RAYLIB_VERSION_MINOR: int = 5
RAYLIB_VERSION_PATCH: int = 0
RAYLIB_VERSION: str = "5.5"
PI: float = 3.141592653589793
DEG2RAD = PI / 180.0
RAD2DEG = 180.0 / PI
MOUSE_LEFT_BUTTON = raylib.MOUSE_BUTTON_LEFT
MOUSE_RIGHT_BUTTON = raylib.MOUSE_BUTTON_RIGHT
MOUSE_MIDDLE_BUTTON = raylib.MOUSE_BUTTON_MIDDLE
MATERIAL_MAP_DIFFUSE = raylib.MATERIAL_MAP_ALBEDO
MATERIAL_MAP_SPECULAR = raylib.MATERIAL_MAP_METALNESS
SHADER_LOC_MAP_DIFFUSE = raylib.SHADER_LOC_MAP_ALBEDO
SHADER_LOC_MAP_SPECULAR = raylib.SHADER_LOC_MAP_METALNESS
EPSILON: float = 1e-06
RLGL_VERSION: str = "5.0"
RL_DEFAULT_BATCH_BUFFER_ELEMENTS: int = 8192
RL_DEFAULT_BATCH_BUFFERS: int = 1
RL_DEFAULT_BATCH_DRAWCALLS: int = 256
RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS: int = 4
RL_MAX_MATRIX_STACK_SIZE: int = 32
RL_MAX_SHADER_LOCATIONS: int = 32
RL_TEXTURE_WRAP_S: int = 10242
RL_TEXTURE_WRAP_T: int = 10243
RL_TEXTURE_MAG_FILTER: int = 10240
RL_TEXTURE_MIN_FILTER: int = 10241
RL_TEXTURE_FILTER_NEAREST: int = 9728
RL_TEXTURE_FILTER_LINEAR: int = 9729
RL_TEXTURE_FILTER_MIP_NEAREST: int = 9984
RL_TEXTURE_FILTER_NEAREST_MIP_LINEAR: int = 9986
RL_TEXTURE_FILTER_LINEAR_MIP_NEAREST: int = 9985
RL_TEXTURE_FILTER_MIP_LINEAR: int = 9987
RL_TEXTURE_FILTER_ANISOTROPIC: int = 12288
RL_TEXTURE_MIPMAP_BIAS_RATIO: int = 16384
RL_TEXTURE_WRAP_REPEAT: int = 10497
RL_TEXTURE_WRAP_CLAMP: int = 33071
RL_TEXTURE_WRAP_MIRROR_REPEAT: int = 33648
RL_TEXTURE_WRAP_MIRROR_CLAMP: int = 34626
RL_MODELVIEW: int = 5888
RL_PROJECTION: int = 5889
RL_TEXTURE: int = 5890
RL_LINES: int = 1
RL_TRIANGLES: int = 4
RL_QUADS: int = 7
RL_UNSIGNED_BYTE: int = 5121
RL_FLOAT: int = 5126
RL_STREAM_DRAW: int = 35040
RL_STREAM_READ: int = 35041
RL_STREAM_COPY: int = 35042
RL_STATIC_DRAW: int = 35044
RL_STATIC_READ: int = 35045
RL_STATIC_COPY: int = 35046
RL_DYNAMIC_DRAW: int = 35048
RL_DYNAMIC_READ: int = 35049
RL_DYNAMIC_COPY: int = 35050
RL_FRAGMENT_SHADER: int = 35632
RL_VERTEX_SHADER: int = 35633
RL_COMPUTE_SHADER: int = 37305
RL_ZERO: int = 0
RL_ONE: int = 1
RL_SRC_COLOR: int = 768
RL_ONE_MINUS_SRC_COLOR: int = 769
RL_SRC_ALPHA: int = 770
RL_ONE_MINUS_SRC_ALPHA: int = 771
RL_DST_ALPHA: int = 772
RL_ONE_MINUS_DST_ALPHA: int = 773
RL_DST_COLOR: int = 774
RL_ONE_MINUS_DST_COLOR: int = 775
RL_SRC_ALPHA_SATURATE: int = 776
RL_CONSTANT_COLOR: int = 32769
RL_ONE_MINUS_CONSTANT_COLOR: int = 32770
RL_CONSTANT_ALPHA: int = 32771
RL_ONE_MINUS_CONSTANT_ALPHA: int = 32772
RL_FUNC_ADD: int = 32774
RL_MIN: int = 32775
RL_MAX: int = 32776
RL_FUNC_SUBTRACT: int = 32778
RL_FUNC_REVERSE_SUBTRACT: int = 32779
RL_BLEND_EQUATION: int = 32777
RL_BLEND_EQUATION_RGB: int = 32777
RL_BLEND_EQUATION_ALPHA: int = 34877
RL_BLEND_DST_RGB: int = 32968
RL_BLEND_SRC_RGB: int = 32969
RL_BLEND_DST_ALPHA: int = 32970
RL_BLEND_SRC_ALPHA: int = 32971
RL_BLEND_COLOR: int = 32773
RL_READ_FRAMEBUFFER: int = 36008
RL_DRAW_FRAMEBUFFER: int = 36009
RL_DEFAULT_SHADER_ATTRIB_LOCATION_POSITION: int = 0
RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD: int = 1
RL_DEFAULT_SHADER_ATTRIB_LOCATION_NORMAL: int = 2
RL_DEFAULT_SHADER_ATTRIB_LOCATION_COLOR: int = 3
RL_DEFAULT_SHADER_ATTRIB_LOCATION_TANGENT: int = 4
RL_DEFAULT_SHADER_ATTRIB_LOCATION_TEXCOORD2: int = 5
RL_DEFAULT_SHADER_ATTRIB_LOCATION_INDICES: int = 6
RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEIDS: int = 7
RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS: int = 8
RL_SHADER_LOC_MAP_DIFFUSE = raylib.RL_SHADER_LOC_MAP_ALBEDO
RL_SHADER_LOC_MAP_SPECULAR = raylib.RL_SHADER_LOC_MAP_METALNESS
GL_SHADING_LANGUAGE_VERSION: int = 35724
GL_COMPRESSED_RGB_S3TC_DXT1_EXT: int = 33776
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: int = 33777
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: int = 33778
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: int = 33779
GL_ETC1_RGB8_OES: int = 36196
GL_COMPRESSED_RGB8_ETC2: int = 37492
GL_COMPRESSED_RGBA8_ETC2_EAC: int = 37496
GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: int = 35840
GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: int = 35842
GL_COMPRESSED_RGBA_ASTC_4x4_KHR: int = 37808
GL_COMPRESSED_RGBA_ASTC_8x8_KHR: int = 37815
GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: int = 34047
GL_TEXTURE_MAX_ANISOTROPY_EXT: int = 34046
GL_PROGRAM_POINT_SIZE: int = 34370
GL_LINE_WIDTH: int = 2849
GL_UNSIGNED_SHORT_5_6_5: int = 33635
GL_UNSIGNED_SHORT_5_5_5_1: int = 32820
GL_UNSIGNED_SHORT_4_4_4_4: int = 32819
GL_LUMINANCE: int = 6409
GL_LUMINANCE_ALPHA: int = 6410
RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION: str = "vertexPosition"
RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD: str = "vertexTexCoord"
RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL: str = "vertexNormal"
RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR: str = "vertexColor"
RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT: str = "vertexTangent"
RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2: str = "vertexTexCoord2"
RL_DEFAULT_SHADER_ATTRIB_NAME_BONEIDS: str = "vertexBoneIds"
RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS: str = "vertexBoneWeights"
RL_DEFAULT_SHADER_UNIFORM_NAME_MVP: str = "mvp"
RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW: str = "matView"
RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION: str = "matProjection"
RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL: str = "matModel"
RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL: str = "matNormal"
RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR: str = "colDiffuse"
RL_DEFAULT_SHADER_UNIFORM_NAME_BONE_MATRICES: str = "boneMatrices"
RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0: str = "texture0"
RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1: str = "texture1"
RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2: str = "texture2"
RAYGUI_VERSION_MAJOR: int = 4
RAYGUI_VERSION_MINOR: int = 5
RAYGUI_VERSION_PATCH: int = 0
RAYGUI_VERSION: str = "4.5-dev"
SCROLLBAR_LEFT_SIDE: int = 0
SCROLLBAR_RIGHT_SIDE: int = 1
RAYGUI_ICON_SIZE: int = 16
RAYGUI_ICON_MAX_ICONS: int = 256
RAYGUI_ICON_MAX_NAME_LENGTH: int = 32
RAYGUI_MAX_CONTROLS: int = 16
RAYGUI_MAX_PROPS_BASE: int = 16
RAYGUI_MAX_PROPS_EXTENDED: int = 8
KEY_RIGHT: int = 262
KEY_LEFT: int = 263
KEY_DOWN: int = 264
KEY_UP: int = 265
KEY_BACKSPACE: int = 259
KEY_ENTER: int = 257
MOUSE_LEFT_BUTTON: int = 0
RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT: int = 24
RAYGUI_GROUPBOX_LINE_THICK: int = 1
RAYGUI_LINE_MARGIN_TEXT: int = 12
RAYGUI_LINE_TEXT_PADDING: int = 4
RAYGUI_PANEL_BORDER_WIDTH: int = 1
RAYGUI_TABBAR_ITEM_WIDTH: int = 160
RAYGUI_MIN_SCROLLBAR_WIDTH: int = 40
RAYGUI_MIN_SCROLLBAR_HEIGHT: int = 40
RAYGUI_MIN_MOUSE_WHEEL_SPEED: int = 20
RAYGUI_TOGGLEGROUP_MAX_ITEMS: int = 32
RAYGUI_TEXTBOX_AUTO_CURSOR_COOLDOWN: int = 40
RAYGUI_TEXTBOX_AUTO_CURSOR_DELAY: int = 1
RAYGUI_VALUEBOX_MAX_CHARS: int = 32
RAYGUI_COLORBARALPHA_CHECKED_SIZE: int = 10
RAYGUI_MESSAGEBOX_BUTTON_HEIGHT: int = 24
RAYGUI_MESSAGEBOX_BUTTON_PADDING: int = 12
RAYGUI_TEXTINPUTBOX_BUTTON_HEIGHT: int = 24
RAYGUI_TEXTINPUTBOX_BUTTON_PADDING: int = 12
RAYGUI_TEXTINPUTBOX_HEIGHT: int = 26
RAYGUI_GRID_ALPHA: float = 0.15
MAX_LINE_BUFFER_SIZE: int = 256
ICON_TEXT_PADDING: int = 4
RAYGUI_MAX_TEXT_LINES: int = 128
RAYGUI_TEXTSPLIT_MAX_ITEMS: int = 128
RAYGUI_TEXTSPLIT_MAX_TEXT_SIZE: int = 1024
RAYGUI_TEXTFORMAT_MAX_SIZE: int = 256
PHYSAC_MAX_BODIES: int = 64
PHYSAC_MAX_MANIFOLDS: int = 4096
PHYSAC_MAX_VERTICES: int = 24
PHYSAC_DEFAULT_CIRCLE_VERTICES: int = 24
PHYSAC_COLLISION_ITERATIONS: int = 100
PHYSAC_PENETRATION_ALLOWANCE: float = 0.05
PHYSAC_PENETRATION_CORRECTION: float = 0.4
PHYSAC_PI: float = 3.141592653589793
PHYSAC_DEG2RAD = PHYSAC_PI / 180.0
PHYSAC_FLT_MAX: float = 3.402823466e+38
PHYSAC_EPSILON: float = 1e-06
GLFW_VERSION_MAJOR: int = 3
GLFW_VERSION_MINOR: int = 4
GLFW_VERSION_REVISION: int = 0
GLFW_TRUE: int = 1
GLFW_FALSE: int = 0
GLFW_RELEASE: int = 0
GLFW_PRESS: int = 1
GLFW_REPEAT: int = 2
GLFW_HAT_CENTERED: int = 0
GLFW_HAT_UP: int = 1
GLFW_HAT_RIGHT: int = 2
GLFW_HAT_DOWN: int = 4
GLFW_HAT_LEFT: int = 8
GLFW_HAT_RIGHT_UP = GLFW_HAT_RIGHT | GLFW_HAT_UP
GLFW_HAT_RIGHT_DOWN = GLFW_HAT_RIGHT | GLFW_HAT_DOWN
GLFW_HAT_LEFT_UP = GLFW_HAT_LEFT | GLFW_HAT_UP
GLFW_HAT_LEFT_DOWN = GLFW_HAT_LEFT | GLFW_HAT_DOWN
GLFW_KEY_SPACE: int = 32
GLFW_KEY_APOSTROPHE: int = 39
GLFW_KEY_COMMA: int = 44
GLFW_KEY_MINUS: int = 45
GLFW_KEY_PERIOD: int = 46
GLFW_KEY_SLASH: int = 47
GLFW_KEY_0: int = 48
GLFW_KEY_1: int = 49
GLFW_KEY_2: int = 50
GLFW_KEY_3: int = 51
GLFW_KEY_4: int = 52
GLFW_KEY_5: int = 53
GLFW_KEY_6: int = 54
GLFW_KEY_7: int = 55
GLFW_KEY_8: int = 56
GLFW_KEY_9: int = 57
GLFW_KEY_SEMICOLON: int = 59
GLFW_KEY_EQUAL: int = 61
GLFW_KEY_A: int = 65
GLFW_KEY_B: int = 66
GLFW_KEY_C: int = 67
GLFW_KEY_D: int = 68
GLFW_KEY_E: int = 69
GLFW_KEY_F: int = 70
GLFW_KEY_G: int = 71
GLFW_KEY_H: int = 72
GLFW_KEY_I: int = 73
GLFW_KEY_J: int = 74
GLFW_KEY_K: int = 75
GLFW_KEY_L: int = 76
GLFW_KEY_M: int = 77
GLFW_KEY_N: int = 78
GLFW_KEY_O: int = 79
GLFW_KEY_P: int = 80
GLFW_KEY_Q: int = 81
GLFW_KEY_R: int = 82
GLFW_KEY_S: int = 83
GLFW_KEY_T: int = 84
GLFW_KEY_U: int = 85
GLFW_KEY_V: int = 86
GLFW_KEY_W: int = 87
GLFW_KEY_X: int = 88
GLFW_KEY_Y: int = 89
GLFW_KEY_Z: int = 90
GLFW_KEY_LEFT_BRACKET: int = 91
GLFW_KEY_BACKSLASH: int = 92
GLFW_KEY_RIGHT_BRACKET: int = 93
GLFW_KEY_GRAVE_ACCENT: int = 96
GLFW_KEY_WORLD_1: int = 161
GLFW_KEY_WORLD_2: int = 162
GLFW_KEY_ESCAPE: int = 256
GLFW_KEY_ENTER: int = 257
GLFW_KEY_TAB: int = 258
GLFW_KEY_BACKSPACE: int = 259
GLFW_KEY_INSERT: int = 260
GLFW_KEY_DELETE: int = 261
GLFW_KEY_RIGHT: int = 262
GLFW_KEY_LEFT: int = 263
GLFW_KEY_DOWN: int = 264
GLFW_KEY_UP: int = 265
GLFW_KEY_PAGE_UP: int = 266
GLFW_KEY_PAGE_DOWN: int = 267
GLFW_KEY_HOME: int = 268
GLFW_KEY_END: int = 269
GLFW_KEY_CAPS_LOCK: int = 280
GLFW_KEY_SCROLL_LOCK: int = 281
GLFW_KEY_NUM_LOCK: int = 282
GLFW_KEY_PRINT_SCREEN: int = 283
GLFW_KEY_PAUSE: int = 284
GLFW_KEY_F1: int = 290
GLFW_KEY_F2: int = 291
GLFW_KEY_F3: int = 292
GLFW_KEY_F4: int = 293
GLFW_KEY_F5: int = 294
GLFW_KEY_F6: int = 295
GLFW_KEY_F7: int = 296
GLFW_KEY_F8: int = 297
GLFW_KEY_F9: int = 298
GLFW_KEY_F10: int = 299
GLFW_KEY_F11: int = 300
GLFW_KEY_F12: int = 301
GLFW_KEY_F13: int = 302
GLFW_KEY_F14: int = 303
GLFW_KEY_F15: int = 304
GLFW_KEY_F16: int = 305
GLFW_KEY_F17: int = 306
GLFW_KEY_F18: int = 307
GLFW_KEY_F19: int = 308
GLFW_KEY_F20: int = 309
GLFW_KEY_F21: int = 310
GLFW_KEY_F22: int = 311
GLFW_KEY_F23: int = 312
GLFW_KEY_F24: int = 313
GLFW_KEY_F25: int = 314
GLFW_KEY_KP_0: int = 320
GLFW_KEY_KP_1: int = 321
GLFW_KEY_KP_2: int = 322
GLFW_KEY_KP_3: int = 323
GLFW_KEY_KP_4: int = 324
GLFW_KEY_KP_5: int = 325
GLFW_KEY_KP_6: int = 326
GLFW_KEY_KP_7: int = 327
GLFW_KEY_KP_8: int = 328
GLFW_KEY_KP_9: int = 329
GLFW_KEY_KP_DECIMAL: int = 330
GLFW_KEY_KP_DIVIDE: int = 331
GLFW_KEY_KP_MULTIPLY: int = 332
GLFW_KEY_KP_SUBTRACT: int = 333
GLFW_KEY_KP_ADD: int = 334
GLFW_KEY_KP_ENTER: int = 335
GLFW_KEY_KP_EQUAL: int = 336
GLFW_KEY_LEFT_SHIFT: int = 340
GLFW_KEY_LEFT_CONTROL: int = 341
GLFW_KEY_LEFT_ALT: int = 342
GLFW_KEY_LEFT_SUPER: int = 343
GLFW_KEY_RIGHT_SHIFT: int = 344
GLFW_KEY_RIGHT_CONTROL: int = 345
GLFW_KEY_RIGHT_ALT: int = 346
GLFW_KEY_RIGHT_SUPER: int = 347
GLFW_KEY_MENU: int = 348
GLFW_MOD_SHIFT: int = 1
GLFW_MOD_CONTROL: int = 2
GLFW_MOD_ALT: int = 4
GLFW_MOD_SUPER: int = 8
GLFW_MOD_CAPS_LOCK: int = 16
GLFW_MOD_NUM_LOCK: int = 32
GLFW_MOUSE_BUTTON_1: int = 0
GLFW_MOUSE_BUTTON_2: int = 1
GLFW_MOUSE_BUTTON_3: int = 2
GLFW_MOUSE_BUTTON_4: int = 3
GLFW_MOUSE_BUTTON_5: int = 4
GLFW_MOUSE_BUTTON_6: int = 5
GLFW_MOUSE_BUTTON_7: int = 6
GLFW_MOUSE_BUTTON_8: int = 7
GLFW_JOYSTICK_1: int = 0
GLFW_JOYSTICK_2: int = 1
GLFW_JOYSTICK_3: int = 2
GLFW_JOYSTICK_4: int = 3
GLFW_JOYSTICK_5: int = 4
GLFW_JOYSTICK_6: int = 5
GLFW_JOYSTICK_7: int = 6
GLFW_JOYSTICK_8: int = 7
GLFW_JOYSTICK_9: int = 8
GLFW_JOYSTICK_10: int = 9
GLFW_JOYSTICK_11: int = 10
GLFW_JOYSTICK_12: int = 11
GLFW_JOYSTICK_13: int = 12
GLFW_JOYSTICK_14: int = 13
GLFW_JOYSTICK_15: int = 14
GLFW_JOYSTICK_16: int = 15
GLFW_GAMEPAD_BUTTON_A: int = 0
GLFW_GAMEPAD_BUTTON_B: int = 1
GLFW_GAMEPAD_BUTTON_X: int = 2
GLFW_GAMEPAD_BUTTON_Y: int = 3
GLFW_GAMEPAD_BUTTON_LEFT_BUMPER: int = 4
GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER: int = 5
GLFW_GAMEPAD_BUTTON_BACK: int = 6
GLFW_GAMEPAD_BUTTON_START: int = 7
GLFW_GAMEPAD_BUTTON_GUIDE: int = 8
GLFW_GAMEPAD_BUTTON_LEFT_THUMB: int = 9
GLFW_GAMEPAD_BUTTON_RIGHT_THUMB: int = 10
GLFW_GAMEPAD_BUTTON_DPAD_UP: int = 11
GLFW_GAMEPAD_BUTTON_DPAD_RIGHT: int = 12
GLFW_GAMEPAD_BUTTON_DPAD_DOWN: int = 13
GLFW_GAMEPAD_BUTTON_DPAD_LEFT: int = 14
GLFW_GAMEPAD_AXIS_LEFT_X: int = 0
GLFW_GAMEPAD_AXIS_LEFT_Y: int = 1
GLFW_GAMEPAD_AXIS_RIGHT_X: int = 2
GLFW_GAMEPAD_AXIS_RIGHT_Y: int = 3
GLFW_GAMEPAD_AXIS_LEFT_TRIGGER: int = 4
GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER: int = 5
GLFW_NO_ERROR: int = 0
GLFW_NOT_INITIALIZED: int = 65537
GLFW_NO_CURRENT_CONTEXT: int = 65538
GLFW_INVALID_ENUM: int = 65539
GLFW_INVALID_VALUE: int = 65540
GLFW_OUT_OF_MEMORY: int = 65541
GLFW_API_UNAVAILABLE: int = 65542
GLFW_VERSION_UNAVAILABLE: int = 65543
GLFW_PLATFORM_ERROR: int = 65544
GLFW_FORMAT_UNAVAILABLE: int = 65545
GLFW_NO_WINDOW_CONTEXT: int = 65546
GLFW_CURSOR_UNAVAILABLE: int = 65547
GLFW_FEATURE_UNAVAILABLE: int = 65548
GLFW_FEATURE_UNIMPLEMENTED: int = 65549
GLFW_PLATFORM_UNAVAILABLE: int = 65550
GLFW_FOCUSED: int = 131073
GLFW_ICONIFIED: int = 131074
GLFW_RESIZABLE: int = 131075
GLFW_VISIBLE: int = 131076
GLFW_DECORATED: int = 131077
GLFW_AUTO_ICONIFY: int = 131078
GLFW_FLOATING: int = 131079
GLFW_MAXIMIZED: int = 131080
GLFW_CENTER_CURSOR: int = 131081
GLFW_TRANSPARENT_FRAMEBUFFER: int = 131082
GLFW_HOVERED: int = 131083
GLFW_FOCUS_ON_SHOW: int = 131084
GLFW_MOUSE_PASSTHROUGH: int = 131085
GLFW_POSITION_X: int = 131086
GLFW_POSITION_Y: int = 131087
GLFW_RED_BITS: int = 135169
GLFW_GREEN_BITS: int = 135170
GLFW_BLUE_BITS: int = 135171
GLFW_ALPHA_BITS: int = 135172
GLFW_DEPTH_BITS: int = 135173
GLFW_STENCIL_BITS: int = 135174
GLFW_ACCUM_RED_BITS: int = 135175
GLFW_ACCUM_GREEN_BITS: int = 135176
GLFW_ACCUM_BLUE_BITS: int = 135177
GLFW_ACCUM_ALPHA_BITS: int = 135178
GLFW_AUX_BUFFERS: int = 135179
GLFW_STEREO: int = 135180
GLFW_SAMPLES: int = 135181
GLFW_SRGB_CAPABLE: int = 135182
GLFW_REFRESH_RATE: int = 135183
GLFW_DOUBLEBUFFER: int = 135184
GLFW_CLIENT_API: int = 139265
GLFW_CONTEXT_VERSION_MAJOR: int = 139266
GLFW_CONTEXT_VERSION_MINOR: int = 139267
GLFW_CONTEXT_REVISION: int = 139268
GLFW_CONTEXT_ROBUSTNESS: int = 139269
GLFW_OPENGL_FORWARD_COMPAT: int = 139270
GLFW_CONTEXT_DEBUG: int = 139271
GLFW_OPENGL_PROFILE: int = 139272
GLFW_CONTEXT_RELEASE_BEHAVIOR: int = 139273
GLFW_CONTEXT_NO_ERROR: int = 139274
GLFW_CONTEXT_CREATION_API: int = 139275
GLFW_SCALE_TO_MONITOR: int = 139276
GLFW_SCALE_FRAMEBUFFER: int = 139277
GLFW_COCOA_RETINA_FRAMEBUFFER: int = 143361
GLFW_COCOA_FRAME_NAME: int = 143362
GLFW_COCOA_GRAPHICS_SWITCHING: int = 143363
GLFW_X11_CLASS_NAME: int = 147457
GLFW_X11_INSTANCE_NAME: int = 147458
GLFW_WIN32_KEYBOARD_MENU: int = 151553
GLFW_WIN32_SHOWDEFAULT: int = 151554
GLFW_WAYLAND_APP_ID: int = 155649
GLFW_NO_API: int = 0
GLFW_OPENGL_API: int = 196609
GLFW_OPENGL_ES_API: int = 196610
GLFW_NO_ROBUSTNESS: int = 0
GLFW_NO_RESET_NOTIFICATION: int = 200705
GLFW_LOSE_CONTEXT_ON_RESET: int = 200706
GLFW_OPENGL_ANY_PROFILE: int = 0
GLFW_OPENGL_CORE_PROFILE: int = 204801
GLFW_OPENGL_COMPAT_PROFILE: int = 204802
GLFW_CURSOR: int = 208897
GLFW_STICKY_KEYS: int = 208898
GLFW_STICKY_MOUSE_BUTTONS: int = 208899
GLFW_LOCK_KEY_MODS: int = 208900
GLFW_RAW_MOUSE_MOTION: int = 208901
GLFW_CURSOR_NORMAL: int = 212993
GLFW_CURSOR_HIDDEN: int = 212994
GLFW_CURSOR_DISABLED: int = 212995
GLFW_CURSOR_CAPTURED: int = 212996
GLFW_ANY_RELEASE_BEHAVIOR: int = 0
GLFW_RELEASE_BEHAVIOR_FLUSH: int = 217089
GLFW_RELEASE_BEHAVIOR_NONE: int = 217090
GLFW_NATIVE_CONTEXT_API: int = 221185
GLFW_EGL_CONTEXT_API: int = 221186
GLFW_OSMESA_CONTEXT_API: int = 221187
GLFW_ANGLE_PLATFORM_TYPE_NONE: int = 225281
GLFW_ANGLE_PLATFORM_TYPE_OPENGL: int = 225282
GLFW_ANGLE_PLATFORM_TYPE_OPENGLES: int = 225283
GLFW_ANGLE_PLATFORM_TYPE_D3D9: int = 225284
GLFW_ANGLE_PLATFORM_TYPE_D3D11: int = 225285
GLFW_ANGLE_PLATFORM_TYPE_VULKAN: int = 225287
GLFW_ANGLE_PLATFORM_TYPE_METAL: int = 225288
GLFW_WAYLAND_PREFER_LIBDECOR: int = 229377
GLFW_WAYLAND_DISABLE_LIBDECOR: int = 229378
GLFW_ANY_POSITION: int = 2147483648
GLFW_ARROW_CURSOR: int = 221185
GLFW_IBEAM_CURSOR: int = 221186
GLFW_CROSSHAIR_CURSOR: int = 221187
GLFW_POINTING_HAND_CURSOR: int = 221188
GLFW_RESIZE_EW_CURSOR: int = 221189
GLFW_RESIZE_NS_CURSOR: int = 221190
GLFW_RESIZE_NWSE_CURSOR: int = 221191
GLFW_RESIZE_NESW_CURSOR: int = 221192
GLFW_RESIZE_ALL_CURSOR: int = 221193
GLFW_NOT_ALLOWED_CURSOR: int = 221194
GLFW_CONNECTED: int = 262145
GLFW_DISCONNECTED: int = 262146
GLFW_JOYSTICK_HAT_BUTTONS: int = 327681
GLFW_ANGLE_PLATFORM_TYPE: int = 327682
GLFW_PLATFORM: int = 327683
GLFW_COCOA_CHDIR_RESOURCES: int = 331777
GLFW_COCOA_MENUBAR: int = 331778
GLFW_X11_XCB_VULKAN_SURFACE: int = 335873
GLFW_WAYLAND_LIBDECOR: int = 339969
GLFW_ANY_PLATFORM: int = 393216
GLFW_PLATFORM_WIN32: int = 393217
GLFW_PLATFORM_COCOA: int = 393218
GLFW_PLATFORM_WAYLAND: int = 393219
GLFW_PLATFORM_X11: int = 393220
GLFW_PLATFORM_NULL: int = 393221

719
raylib/raylib/enums.py Normal file
View File

@@ -0,0 +1,719 @@
from enum import IntEnum
class ConfigFlags(IntEnum):
FLAG_VSYNC_HINT = 64
FLAG_FULLSCREEN_MODE = 2
FLAG_WINDOW_RESIZABLE = 4
FLAG_WINDOW_UNDECORATED = 8
FLAG_WINDOW_HIDDEN = 128
FLAG_WINDOW_MINIMIZED = 512
FLAG_WINDOW_MAXIMIZED = 1024
FLAG_WINDOW_UNFOCUSED = 2048
FLAG_WINDOW_TOPMOST = 4096
FLAG_WINDOW_ALWAYS_RUN = 256
FLAG_WINDOW_TRANSPARENT = 16
FLAG_WINDOW_HIGHDPI = 8192
FLAG_WINDOW_MOUSE_PASSTHROUGH = 16384
FLAG_BORDERLESS_WINDOWED_MODE = 32768
FLAG_MSAA_4X_HINT = 32
FLAG_INTERLACED_HINT = 65536
class TraceLogLevel(IntEnum):
LOG_ALL = 0
LOG_TRACE = 1
LOG_DEBUG = 2
LOG_INFO = 3
LOG_WARNING = 4
LOG_ERROR = 5
LOG_FATAL = 6
LOG_NONE = 7
class KeyboardKey(IntEnum):
KEY_NULL = 0
KEY_APOSTROPHE = 39
KEY_COMMA = 44
KEY_MINUS = 45
KEY_PERIOD = 46
KEY_SLASH = 47
KEY_ZERO = 48
KEY_ONE = 49
KEY_TWO = 50
KEY_THREE = 51
KEY_FOUR = 52
KEY_FIVE = 53
KEY_SIX = 54
KEY_SEVEN = 55
KEY_EIGHT = 56
KEY_NINE = 57
KEY_SEMICOLON = 59
KEY_EQUAL = 61
KEY_A = 65
KEY_B = 66
KEY_C = 67
KEY_D = 68
KEY_E = 69
KEY_F = 70
KEY_G = 71
KEY_H = 72
KEY_I = 73
KEY_J = 74
KEY_K = 75
KEY_L = 76
KEY_M = 77
KEY_N = 78
KEY_O = 79
KEY_P = 80
KEY_Q = 81
KEY_R = 82
KEY_S = 83
KEY_T = 84
KEY_U = 85
KEY_V = 86
KEY_W = 87
KEY_X = 88
KEY_Y = 89
KEY_Z = 90
KEY_LEFT_BRACKET = 91
KEY_BACKSLASH = 92
KEY_RIGHT_BRACKET = 93
KEY_GRAVE = 96
KEY_SPACE = 32
KEY_ESCAPE = 256
KEY_ENTER = 257
KEY_TAB = 258
KEY_BACKSPACE = 259
KEY_INSERT = 260
KEY_DELETE = 261
KEY_RIGHT = 262
KEY_LEFT = 263
KEY_DOWN = 264
KEY_UP = 265
KEY_PAGE_UP = 266
KEY_PAGE_DOWN = 267
KEY_HOME = 268
KEY_END = 269
KEY_CAPS_LOCK = 280
KEY_SCROLL_LOCK = 281
KEY_NUM_LOCK = 282
KEY_PRINT_SCREEN = 283
KEY_PAUSE = 284
KEY_F1 = 290
KEY_F2 = 291
KEY_F3 = 292
KEY_F4 = 293
KEY_F5 = 294
KEY_F6 = 295
KEY_F7 = 296
KEY_F8 = 297
KEY_F9 = 298
KEY_F10 = 299
KEY_F11 = 300
KEY_F12 = 301
KEY_LEFT_SHIFT = 340
KEY_LEFT_CONTROL = 341
KEY_LEFT_ALT = 342
KEY_LEFT_SUPER = 343
KEY_RIGHT_SHIFT = 344
KEY_RIGHT_CONTROL = 345
KEY_RIGHT_ALT = 346
KEY_RIGHT_SUPER = 347
KEY_KB_MENU = 348
KEY_KP_0 = 320
KEY_KP_1 = 321
KEY_KP_2 = 322
KEY_KP_3 = 323
KEY_KP_4 = 324
KEY_KP_5 = 325
KEY_KP_6 = 326
KEY_KP_7 = 327
KEY_KP_8 = 328
KEY_KP_9 = 329
KEY_KP_DECIMAL = 330
KEY_KP_DIVIDE = 331
KEY_KP_MULTIPLY = 332
KEY_KP_SUBTRACT = 333
KEY_KP_ADD = 334
KEY_KP_ENTER = 335
KEY_KP_EQUAL = 336
KEY_BACK = 4
KEY_MENU = 5
KEY_VOLUME_UP = 24
KEY_VOLUME_DOWN = 25
class MouseButton(IntEnum):
MOUSE_BUTTON_LEFT = 0
MOUSE_BUTTON_RIGHT = 1
MOUSE_BUTTON_MIDDLE = 2
MOUSE_BUTTON_SIDE = 3
MOUSE_BUTTON_EXTRA = 4
MOUSE_BUTTON_FORWARD = 5
MOUSE_BUTTON_BACK = 6
class MouseCursor(IntEnum):
MOUSE_CURSOR_DEFAULT = 0
MOUSE_CURSOR_ARROW = 1
MOUSE_CURSOR_IBEAM = 2
MOUSE_CURSOR_CROSSHAIR = 3
MOUSE_CURSOR_POINTING_HAND = 4
MOUSE_CURSOR_RESIZE_EW = 5
MOUSE_CURSOR_RESIZE_NS = 6
MOUSE_CURSOR_RESIZE_NWSE = 7
MOUSE_CURSOR_RESIZE_NESW = 8
MOUSE_CURSOR_RESIZE_ALL = 9
MOUSE_CURSOR_NOT_ALLOWED = 10
class GamepadButton(IntEnum):
GAMEPAD_BUTTON_UNKNOWN = 0
GAMEPAD_BUTTON_LEFT_FACE_UP = 1
GAMEPAD_BUTTON_LEFT_FACE_RIGHT = 2
GAMEPAD_BUTTON_LEFT_FACE_DOWN = 3
GAMEPAD_BUTTON_LEFT_FACE_LEFT = 4
GAMEPAD_BUTTON_RIGHT_FACE_UP = 5
GAMEPAD_BUTTON_RIGHT_FACE_RIGHT = 6
GAMEPAD_BUTTON_RIGHT_FACE_DOWN = 7
GAMEPAD_BUTTON_RIGHT_FACE_LEFT = 8
GAMEPAD_BUTTON_LEFT_TRIGGER_1 = 9
GAMEPAD_BUTTON_LEFT_TRIGGER_2 = 10
GAMEPAD_BUTTON_RIGHT_TRIGGER_1 = 11
GAMEPAD_BUTTON_RIGHT_TRIGGER_2 = 12
GAMEPAD_BUTTON_MIDDLE_LEFT = 13
GAMEPAD_BUTTON_MIDDLE = 14
GAMEPAD_BUTTON_MIDDLE_RIGHT = 15
GAMEPAD_BUTTON_LEFT_THUMB = 16
GAMEPAD_BUTTON_RIGHT_THUMB = 17
class GamepadAxis(IntEnum):
GAMEPAD_AXIS_LEFT_X = 0
GAMEPAD_AXIS_LEFT_Y = 1
GAMEPAD_AXIS_RIGHT_X = 2
GAMEPAD_AXIS_RIGHT_Y = 3
GAMEPAD_AXIS_LEFT_TRIGGER = 4
GAMEPAD_AXIS_RIGHT_TRIGGER = 5
class MaterialMapIndex(IntEnum):
MATERIAL_MAP_ALBEDO = 0
MATERIAL_MAP_METALNESS = 1
MATERIAL_MAP_NORMAL = 2
MATERIAL_MAP_ROUGHNESS = 3
MATERIAL_MAP_OCCLUSION = 4
MATERIAL_MAP_EMISSION = 5
MATERIAL_MAP_HEIGHT = 6
MATERIAL_MAP_CUBEMAP = 7
MATERIAL_MAP_IRRADIANCE = 8
MATERIAL_MAP_PREFILTER = 9
MATERIAL_MAP_BRDF = 10
class ShaderLocationIndex(IntEnum):
SHADER_LOC_VERTEX_POSITION = 0
SHADER_LOC_VERTEX_TEXCOORD01 = 1
SHADER_LOC_VERTEX_TEXCOORD02 = 2
SHADER_LOC_VERTEX_NORMAL = 3
SHADER_LOC_VERTEX_TANGENT = 4
SHADER_LOC_VERTEX_COLOR = 5
SHADER_LOC_MATRIX_MVP = 6
SHADER_LOC_MATRIX_VIEW = 7
SHADER_LOC_MATRIX_PROJECTION = 8
SHADER_LOC_MATRIX_MODEL = 9
SHADER_LOC_MATRIX_NORMAL = 10
SHADER_LOC_VECTOR_VIEW = 11
SHADER_LOC_COLOR_DIFFUSE = 12
SHADER_LOC_COLOR_SPECULAR = 13
SHADER_LOC_COLOR_AMBIENT = 14
SHADER_LOC_MAP_ALBEDO = 15
SHADER_LOC_MAP_METALNESS = 16
SHADER_LOC_MAP_NORMAL = 17
SHADER_LOC_MAP_ROUGHNESS = 18
SHADER_LOC_MAP_OCCLUSION = 19
SHADER_LOC_MAP_EMISSION = 20
SHADER_LOC_MAP_HEIGHT = 21
SHADER_LOC_MAP_CUBEMAP = 22
SHADER_LOC_MAP_IRRADIANCE = 23
SHADER_LOC_MAP_PREFILTER = 24
SHADER_LOC_MAP_BRDF = 25
SHADER_LOC_VERTEX_BONEIDS = 26
SHADER_LOC_VERTEX_BONEWEIGHTS = 27
SHADER_LOC_BONE_MATRICES = 28
class ShaderUniformDataType(IntEnum):
SHADER_UNIFORM_FLOAT = 0
SHADER_UNIFORM_VEC2 = 1
SHADER_UNIFORM_VEC3 = 2
SHADER_UNIFORM_VEC4 = 3
SHADER_UNIFORM_INT = 4
SHADER_UNIFORM_IVEC2 = 5
SHADER_UNIFORM_IVEC3 = 6
SHADER_UNIFORM_IVEC4 = 7
SHADER_UNIFORM_SAMPLER2D = 8
class ShaderAttributeDataType(IntEnum):
SHADER_ATTRIB_FLOAT = 0
SHADER_ATTRIB_VEC2 = 1
SHADER_ATTRIB_VEC3 = 2
SHADER_ATTRIB_VEC4 = 3
class PixelFormat(IntEnum):
PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1
PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA = 2
PIXELFORMAT_UNCOMPRESSED_R5G6B5 = 3
PIXELFORMAT_UNCOMPRESSED_R8G8B8 = 4
PIXELFORMAT_UNCOMPRESSED_R5G5B5A1 = 5
PIXELFORMAT_UNCOMPRESSED_R4G4B4A4 = 6
PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 = 7
PIXELFORMAT_UNCOMPRESSED_R32 = 8
PIXELFORMAT_UNCOMPRESSED_R32G32B32 = 9
PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 = 10
PIXELFORMAT_UNCOMPRESSED_R16 = 11
PIXELFORMAT_UNCOMPRESSED_R16G16B16 = 12
PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 = 13
PIXELFORMAT_COMPRESSED_DXT1_RGB = 14
PIXELFORMAT_COMPRESSED_DXT1_RGBA = 15
PIXELFORMAT_COMPRESSED_DXT3_RGBA = 16
PIXELFORMAT_COMPRESSED_DXT5_RGBA = 17
PIXELFORMAT_COMPRESSED_ETC1_RGB = 18
PIXELFORMAT_COMPRESSED_ETC2_RGB = 19
PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA = 20
PIXELFORMAT_COMPRESSED_PVRT_RGB = 21
PIXELFORMAT_COMPRESSED_PVRT_RGBA = 22
PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA = 23
PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA = 24
class TextureFilter(IntEnum):
TEXTURE_FILTER_POINT = 0
TEXTURE_FILTER_BILINEAR = 1
TEXTURE_FILTER_TRILINEAR = 2
TEXTURE_FILTER_ANISOTROPIC_4X = 3
TEXTURE_FILTER_ANISOTROPIC_8X = 4
TEXTURE_FILTER_ANISOTROPIC_16X = 5
class TextureWrap(IntEnum):
TEXTURE_WRAP_REPEAT = 0
TEXTURE_WRAP_CLAMP = 1
TEXTURE_WRAP_MIRROR_REPEAT = 2
TEXTURE_WRAP_MIRROR_CLAMP = 3
class CubemapLayout(IntEnum):
CUBEMAP_LAYOUT_AUTO_DETECT = 0
CUBEMAP_LAYOUT_LINE_VERTICAL = 1
CUBEMAP_LAYOUT_LINE_HORIZONTAL = 2
CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR = 3
CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE = 4
class FontType(IntEnum):
FONT_DEFAULT = 0
FONT_BITMAP = 1
FONT_SDF = 2
class BlendMode(IntEnum):
BLEND_ALPHA = 0
BLEND_ADDITIVE = 1
BLEND_MULTIPLIED = 2
BLEND_ADD_COLORS = 3
BLEND_SUBTRACT_COLORS = 4
BLEND_ALPHA_PREMULTIPLY = 5
BLEND_CUSTOM = 6
BLEND_CUSTOM_SEPARATE = 7
class Gesture(IntEnum):
GESTURE_NONE = 0
GESTURE_TAP = 1
GESTURE_DOUBLETAP = 2
GESTURE_HOLD = 4
GESTURE_DRAG = 8
GESTURE_SWIPE_RIGHT = 16
GESTURE_SWIPE_LEFT = 32
GESTURE_SWIPE_UP = 64
GESTURE_SWIPE_DOWN = 128
GESTURE_PINCH_IN = 256
GESTURE_PINCH_OUT = 512
class CameraMode(IntEnum):
CAMERA_CUSTOM = 0
CAMERA_FREE = 1
CAMERA_ORBITAL = 2
CAMERA_FIRST_PERSON = 3
CAMERA_THIRD_PERSON = 4
class CameraProjection(IntEnum):
CAMERA_PERSPECTIVE = 0
CAMERA_ORTHOGRAPHIC = 1
class NPatchLayout(IntEnum):
NPATCH_NINE_PATCH = 0
NPATCH_THREE_PATCH_VERTICAL = 1
NPATCH_THREE_PATCH_HORIZONTAL = 2
class GuiState(IntEnum):
STATE_NORMAL = 0
STATE_FOCUSED = 1
STATE_PRESSED = 2
STATE_DISABLED = 3
class GuiTextAlignment(IntEnum):
TEXT_ALIGN_LEFT = 0
TEXT_ALIGN_CENTER = 1
TEXT_ALIGN_RIGHT = 2
class GuiTextAlignmentVertical(IntEnum):
TEXT_ALIGN_TOP = 0
TEXT_ALIGN_MIDDLE = 1
TEXT_ALIGN_BOTTOM = 2
class GuiTextWrapMode(IntEnum):
TEXT_WRAP_NONE = 0
TEXT_WRAP_CHAR = 1
TEXT_WRAP_WORD = 2
class GuiControl(IntEnum):
DEFAULT = 0
LABEL = 1
BUTTON = 2
TOGGLE = 3
SLIDER = 4
PROGRESSBAR = 5
CHECKBOX = 6
COMBOBOX = 7
DROPDOWNBOX = 8
TEXTBOX = 9
VALUEBOX = 10
SPINNER = 11
LISTVIEW = 12
COLORPICKER = 13
SCROLLBAR = 14
STATUSBAR = 15
class GuiControlProperty(IntEnum):
BORDER_COLOR_NORMAL = 0
BASE_COLOR_NORMAL = 1
TEXT_COLOR_NORMAL = 2
BORDER_COLOR_FOCUSED = 3
BASE_COLOR_FOCUSED = 4
TEXT_COLOR_FOCUSED = 5
BORDER_COLOR_PRESSED = 6
BASE_COLOR_PRESSED = 7
TEXT_COLOR_PRESSED = 8
BORDER_COLOR_DISABLED = 9
BASE_COLOR_DISABLED = 10
TEXT_COLOR_DISABLED = 11
BORDER_WIDTH = 12
TEXT_PADDING = 13
TEXT_ALIGNMENT = 14
class GuiDefaultProperty(IntEnum):
TEXT_SIZE = 16
TEXT_SPACING = 17
LINE_COLOR = 18
BACKGROUND_COLOR = 19
TEXT_LINE_SPACING = 20
TEXT_ALIGNMENT_VERTICAL = 21
TEXT_WRAP_MODE = 22
class GuiToggleProperty(IntEnum):
GROUP_PADDING = 16
class GuiSliderProperty(IntEnum):
SLIDER_WIDTH = 16
SLIDER_PADDING = 17
class GuiProgressBarProperty(IntEnum):
PROGRESS_PADDING = 16
class GuiScrollBarProperty(IntEnum):
ARROWS_SIZE = 16
ARROWS_VISIBLE = 17
SCROLL_SLIDER_PADDING = 18
SCROLL_SLIDER_SIZE = 19
SCROLL_PADDING = 20
SCROLL_SPEED = 21
class GuiCheckBoxProperty(IntEnum):
CHECK_PADDING = 16
class GuiComboBoxProperty(IntEnum):
COMBO_BUTTON_WIDTH = 16
COMBO_BUTTON_SPACING = 17
class GuiDropdownBoxProperty(IntEnum):
ARROW_PADDING = 16
DROPDOWN_ITEMS_SPACING = 17
DROPDOWN_ARROW_HIDDEN = 18
DROPDOWN_ROLL_UP = 19
class GuiTextBoxProperty(IntEnum):
TEXT_READONLY = 16
class GuiSpinnerProperty(IntEnum):
SPIN_BUTTON_WIDTH = 16
SPIN_BUTTON_SPACING = 17
class GuiListViewProperty(IntEnum):
LIST_ITEMS_HEIGHT = 16
LIST_ITEMS_SPACING = 17
SCROLLBAR_WIDTH = 18
SCROLLBAR_SIDE = 19
LIST_ITEMS_BORDER_WIDTH = 20
class GuiColorPickerProperty(IntEnum):
COLOR_SELECTOR_SIZE = 16
HUEBAR_WIDTH = 17
HUEBAR_PADDING = 18
HUEBAR_SELECTOR_HEIGHT = 19
HUEBAR_SELECTOR_OVERFLOW = 20
class GuiIconName(IntEnum):
ICON_NONE = 0
ICON_FOLDER_FILE_OPEN = 1
ICON_FILE_SAVE_CLASSIC = 2
ICON_FOLDER_OPEN = 3
ICON_FOLDER_SAVE = 4
ICON_FILE_OPEN = 5
ICON_FILE_SAVE = 6
ICON_FILE_EXPORT = 7
ICON_FILE_ADD = 8
ICON_FILE_DELETE = 9
ICON_FILETYPE_TEXT = 10
ICON_FILETYPE_AUDIO = 11
ICON_FILETYPE_IMAGE = 12
ICON_FILETYPE_PLAY = 13
ICON_FILETYPE_VIDEO = 14
ICON_FILETYPE_INFO = 15
ICON_FILE_COPY = 16
ICON_FILE_CUT = 17
ICON_FILE_PASTE = 18
ICON_CURSOR_HAND = 19
ICON_CURSOR_POINTER = 20
ICON_CURSOR_CLASSIC = 21
ICON_PENCIL = 22
ICON_PENCIL_BIG = 23
ICON_BRUSH_CLASSIC = 24
ICON_BRUSH_PAINTER = 25
ICON_WATER_DROP = 26
ICON_COLOR_PICKER = 27
ICON_RUBBER = 28
ICON_COLOR_BUCKET = 29
ICON_TEXT_T = 30
ICON_TEXT_A = 31
ICON_SCALE = 32
ICON_RESIZE = 33
ICON_FILTER_POINT = 34
ICON_FILTER_BILINEAR = 35
ICON_CROP = 36
ICON_CROP_ALPHA = 37
ICON_SQUARE_TOGGLE = 38
ICON_SYMMETRY = 39
ICON_SYMMETRY_HORIZONTAL = 40
ICON_SYMMETRY_VERTICAL = 41
ICON_LENS = 42
ICON_LENS_BIG = 43
ICON_EYE_ON = 44
ICON_EYE_OFF = 45
ICON_FILTER_TOP = 46
ICON_FILTER = 47
ICON_TARGET_POINT = 48
ICON_TARGET_SMALL = 49
ICON_TARGET_BIG = 50
ICON_TARGET_MOVE = 51
ICON_CURSOR_MOVE = 52
ICON_CURSOR_SCALE = 53
ICON_CURSOR_SCALE_RIGHT = 54
ICON_CURSOR_SCALE_LEFT = 55
ICON_UNDO = 56
ICON_REDO = 57
ICON_REREDO = 58
ICON_MUTATE = 59
ICON_ROTATE = 60
ICON_REPEAT = 61
ICON_SHUFFLE = 62
ICON_EMPTYBOX = 63
ICON_TARGET = 64
ICON_TARGET_SMALL_FILL = 65
ICON_TARGET_BIG_FILL = 66
ICON_TARGET_MOVE_FILL = 67
ICON_CURSOR_MOVE_FILL = 68
ICON_CURSOR_SCALE_FILL = 69
ICON_CURSOR_SCALE_RIGHT_FILL = 70
ICON_CURSOR_SCALE_LEFT_FILL = 71
ICON_UNDO_FILL = 72
ICON_REDO_FILL = 73
ICON_REREDO_FILL = 74
ICON_MUTATE_FILL = 75
ICON_ROTATE_FILL = 76
ICON_REPEAT_FILL = 77
ICON_SHUFFLE_FILL = 78
ICON_EMPTYBOX_SMALL = 79
ICON_BOX = 80
ICON_BOX_TOP = 81
ICON_BOX_TOP_RIGHT = 82
ICON_BOX_RIGHT = 83
ICON_BOX_BOTTOM_RIGHT = 84
ICON_BOX_BOTTOM = 85
ICON_BOX_BOTTOM_LEFT = 86
ICON_BOX_LEFT = 87
ICON_BOX_TOP_LEFT = 88
ICON_BOX_CENTER = 89
ICON_BOX_CIRCLE_MASK = 90
ICON_POT = 91
ICON_ALPHA_MULTIPLY = 92
ICON_ALPHA_CLEAR = 93
ICON_DITHERING = 94
ICON_MIPMAPS = 95
ICON_BOX_GRID = 96
ICON_GRID = 97
ICON_BOX_CORNERS_SMALL = 98
ICON_BOX_CORNERS_BIG = 99
ICON_FOUR_BOXES = 100
ICON_GRID_FILL = 101
ICON_BOX_MULTISIZE = 102
ICON_ZOOM_SMALL = 103
ICON_ZOOM_MEDIUM = 104
ICON_ZOOM_BIG = 105
ICON_ZOOM_ALL = 106
ICON_ZOOM_CENTER = 107
ICON_BOX_DOTS_SMALL = 108
ICON_BOX_DOTS_BIG = 109
ICON_BOX_CONCENTRIC = 110
ICON_BOX_GRID_BIG = 111
ICON_OK_TICK = 112
ICON_CROSS = 113
ICON_ARROW_LEFT = 114
ICON_ARROW_RIGHT = 115
ICON_ARROW_DOWN = 116
ICON_ARROW_UP = 117
ICON_ARROW_LEFT_FILL = 118
ICON_ARROW_RIGHT_FILL = 119
ICON_ARROW_DOWN_FILL = 120
ICON_ARROW_UP_FILL = 121
ICON_AUDIO = 122
ICON_FX = 123
ICON_WAVE = 124
ICON_WAVE_SINUS = 125
ICON_WAVE_SQUARE = 126
ICON_WAVE_TRIANGULAR = 127
ICON_CROSS_SMALL = 128
ICON_PLAYER_PREVIOUS = 129
ICON_PLAYER_PLAY_BACK = 130
ICON_PLAYER_PLAY = 131
ICON_PLAYER_PAUSE = 132
ICON_PLAYER_STOP = 133
ICON_PLAYER_NEXT = 134
ICON_PLAYER_RECORD = 135
ICON_MAGNET = 136
ICON_LOCK_CLOSE = 137
ICON_LOCK_OPEN = 138
ICON_CLOCK = 139
ICON_TOOLS = 140
ICON_GEAR = 141
ICON_GEAR_BIG = 142
ICON_BIN = 143
ICON_HAND_POINTER = 144
ICON_LASER = 145
ICON_COIN = 146
ICON_EXPLOSION = 147
ICON_1UP = 148
ICON_PLAYER = 149
ICON_PLAYER_JUMP = 150
ICON_KEY = 151
ICON_DEMON = 152
ICON_TEXT_POPUP = 153
ICON_GEAR_EX = 154
ICON_CRACK = 155
ICON_CRACK_POINTS = 156
ICON_STAR = 157
ICON_DOOR = 158
ICON_EXIT = 159
ICON_MODE_2D = 160
ICON_MODE_3D = 161
ICON_CUBE = 162
ICON_CUBE_FACE_TOP = 163
ICON_CUBE_FACE_LEFT = 164
ICON_CUBE_FACE_FRONT = 165
ICON_CUBE_FACE_BOTTOM = 166
ICON_CUBE_FACE_RIGHT = 167
ICON_CUBE_FACE_BACK = 168
ICON_CAMERA = 169
ICON_SPECIAL = 170
ICON_LINK_NET = 171
ICON_LINK_BOXES = 172
ICON_LINK_MULTI = 173
ICON_LINK = 174
ICON_LINK_BROKE = 175
ICON_TEXT_NOTES = 176
ICON_NOTEBOOK = 177
ICON_SUITCASE = 178
ICON_SUITCASE_ZIP = 179
ICON_MAILBOX = 180
ICON_MONITOR = 181
ICON_PRINTER = 182
ICON_PHOTO_CAMERA = 183
ICON_PHOTO_CAMERA_FLASH = 184
ICON_HOUSE = 185
ICON_HEART = 186
ICON_CORNER = 187
ICON_VERTICAL_BARS = 188
ICON_VERTICAL_BARS_FILL = 189
ICON_LIFE_BARS = 190
ICON_INFO = 191
ICON_CROSSLINE = 192
ICON_HELP = 193
ICON_FILETYPE_ALPHA = 194
ICON_FILETYPE_HOME = 195
ICON_LAYERS_VISIBLE = 196
ICON_LAYERS = 197
ICON_WINDOW = 198
ICON_HIDPI = 199
ICON_FILETYPE_BINARY = 200
ICON_HEX = 201
ICON_SHIELD = 202
ICON_FILE_NEW = 203
ICON_FOLDER_ADD = 204
ICON_ALARM = 205
ICON_CPU = 206
ICON_ROM = 207
ICON_STEP_OVER = 208
ICON_STEP_INTO = 209
ICON_STEP_OUT = 210
ICON_RESTART = 211
ICON_BREAKPOINT_ON = 212
ICON_BREAKPOINT_OFF = 213
ICON_BURGER_MENU = 214
ICON_CASE_SENSITIVE = 215
ICON_REG_EXP = 216
ICON_FOLDER = 217
ICON_FILE = 218
ICON_SAND_TIMER = 219
ICON_WARNING = 220
ICON_HELP_BOX = 221
ICON_INFO_BOX = 222
ICON_PRIORITY = 223
ICON_LAYERS_ISO = 224
ICON_LAYERS2 = 225
ICON_MLAYERS = 226
ICON_MAPS = 227
ICON_HOT = 228
ICON_229 = 229
ICON_230 = 230
ICON_231 = 231
ICON_232 = 232
ICON_233 = 233
ICON_234 = 234
ICON_235 = 235
ICON_236 = 236
ICON_237 = 237
ICON_238 = 238
ICON_239 = 239
ICON_240 = 240
ICON_241 = 241
ICON_242 = 242
ICON_243 = 243
ICON_244 = 244
ICON_245 = 245
ICON_246 = 246
ICON_247 = 247
ICON_248 = 248
ICON_249 = 249
ICON_250 = 250
ICON_251 = 251
ICON_252 = 252
ICON_253 = 253
ICON_254 = 254
ICON_255 = 255

1
raylib/raylib/version.py Normal file
View File

@@ -0,0 +1 @@
__version__ = "5.5.0.8"

67
raylib/setup.py Normal file
View File

@@ -0,0 +1,67 @@
import glob
import os
import platform
import subprocess
import sys
from setuptools import setup
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildRaylib(build_py):
"""Run build.sh to compile the C library and CFFI extension before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
lib_dir = os.path.join(pkg_dir, "raylib", "install", "lib")
marker = os.path.join(lib_dir, "libraylib.a")
offscreen_marker = os.path.join(lib_dir, "libraylib_offscreen.a")
need_offscreen = platform.system() == "Linux" and platform.machine() == "x86_64"
if not os.path.exists(marker) or (need_offscreen and not os.path.exists(offscreen_marker)):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
# Build CFFI extension so it's included in the wheel
cffi_so = glob.glob(os.path.join(pkg_dir, "raylib", "_raylib_cffi*"))
if not cffi_so:
build_cffi = os.path.join(pkg_dir, "raylib", "build.py")
if os.path.isfile(build_cffi):
subprocess.check_call([sys.executable, build_cffi], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildRaylib}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific wheel (contains native .a library)."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
setup(cmdclass=cmdclass)

131
release.sh Executable file
View File

@@ -0,0 +1,131 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$ROOT_DIR"
REPO=commaai/dependencies
echo
echo "Publishing wheels to GitHub Releases ($REPO)"
shopt -s nullglob
for toml in */pyproject.toml; do
pkg="$(dirname "$toml")"
module="${pkg//-/_}"
version="$(python3 -c "import tomllib; print(tomllib.load(open('$toml', 'rb'))['project']['version'])")"
tag="${pkg}/v${version}"
wheels=("dist/${module}-${version}-"*.whl)
if [[ ${#wheels[@]} -eq 0 ]]; then
echo "missing wheel for $pkg ($module-$version) in dist" >&2
exit 1
fi
echo "[$pkg] Uploading ${#wheels[@]} wheel(s) to $tag"
gh release create "$tag" "${wheels[@]}" --repo "$REPO" --title "$pkg v$version" --notes "Platform wheels for $pkg $version" 2>/dev/null ||
gh release upload "$tag" "${wheels[@]}" --repo "$REPO" --clobber
done
shopt -u nullglob
TOKEN="$(gh auth token 2>/dev/null)" || { echo "set GH_TOKEN to publish shim branch" >&2; exit 1; }
TMP_DIR="$(mktemp -d)"
python3 - "$TMP_DIR" "$REPO" <<'PY'
import json
import pathlib
import shutil
import tomllib
import sys
tmp_dir = pathlib.Path(sys.argv[1])
repo = sys.argv[2]
repo_url = f"https://github.com/{repo}"
shim_setup = pathlib.Path("_shim_setup.py")
for toml in sorted(pathlib.Path(".").glob("*/pyproject.toml")):
pkg = toml.parent.name
module = pkg.replace("-", "_")
data = tomllib.load(toml.open("rb"))
version = str(data["project"]["version"])
tag = f"{pkg}/v{version}"
description = data["project"]["description"]
patterns = data.get("tool", {}).get("setuptools", {}).get("package-data", {}).get(module, [""])
datadir = patterns[0].split("/", 1)[0] if patterns and patterns[0] else ""
scripts = data.get("project", {}).get("scripts", {}) or {}
pkg_dir = tmp_dir / pkg
mod_dir = pkg_dir / module
mod_dir.mkdir(parents=True, exist_ok=True)
# copy all .py files from the main module
src_mod = pathlib.Path(pkg) / module
for py_file in src_mod.glob("*.py"):
shutil.copy2(py_file, mod_dir / py_file.name)
# copy extra packages (e.g. pyray for raylib)
include_patterns = data.get("tool", {}).get("setuptools", {}).get("packages", {}).get("find", {}).get("include", [])
extra_packages = []
for pattern in include_patterns:
p = pattern.rstrip("*")
if p and p != module and p != f"{module}/":
src_extra = pathlib.Path(pkg) / p
if src_extra.is_dir():
dst_extra = pkg_dir / p
shutil.copytree(src_extra, dst_extra, dirs_exist_ok=True)
extra_packages.append(pattern)
shutil.copy2(shim_setup, pkg_dir / "setup.py")
deps = data.get("project", {}).get("dependencies", [])
lines = [
"[build-system]",
'requires = ["setuptools>=64", "wheel", \'tomli; python_version < \"3.11\"\']',
'build-backend = "setuptools.build_meta"',
"",
"[project]",
f'name = "{pkg}"',
f'version = "{version}"',
f"description = {json.dumps(description + ' (pre-built)')}",
'requires-python = ">=3.8"',
]
if deps:
lines.append(f"dependencies = {json.dumps(deps)}")
if scripts:
lines += ["", "[project.scripts]"]
for name, target in scripts.items():
lines.append(f'"{name}" = {json.dumps(target)}')
find_include = [f"{module}*"] + extra_packages
lines += [
"",
"[tool.setuptools.packages.find]",
f"include = {json.dumps(find_include)}",
"",
"[tool.setuptools.package-data]",
f'{module} = ["{datadir}/**/*", "*.so"]',
"",
"[tool.shim]",
f'repo_url = "{repo_url}"',
f'tag = "{tag}"',
f'datadir = "{datadir}"',
]
(pkg_dir / "pyproject.toml").write_text("\n".join(lines) + "\n")
PY
(
cd "$TMP_DIR"
git init
git checkout -b releases
git add .
git -c user.name="github-actions[bot]" -c user.email="github-actions[bot]@users.noreply.github.com" commit -m "update shim packages"
git remote add origin "https://x-access-token:${TOKEN}@github.com/${REPO}.git"
git push -f origin releases
)
rm -rf "$TMP_DIR"

39
setup.sh Executable file
View File

@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -euo pipefail
# sets up build-time dependencies (NOT runtime dependencies)
run_as_root() {
if [ "$(id -u)" -eq 0 ]; then
"$@"
elif command -v sudo &>/dev/null; then
sudo "$@"
else
echo "error: root privileges required for: $*" >&2
exit 1
fi
}
if [ "$(uname)" = "Darwin" ]; then
brew install nasm pkg-config
elif command -v dnf &>/dev/null; then
dnf install -y nasm cmake gcc-c++ pkgconfig git perl-IPC-Cmd
elif command -v apt-get &>/dev/null; then
run_as_root apt-get update
run_as_root apt-get install -y nasm cmake g++ pkg-config curl
fi
if ! command -v uv &>/dev/null; then
command -v curl &>/dev/null || {
echo "error: curl is required to install uv" >&2
exit 1
}
UV_BIN_DIR="$HOME/.local/bin"
mkdir -p "$UV_BIN_DIR"
curl -LsSf https://astral.sh/uv/install.sh | env UV_UNMANAGED_INSTALL="$UV_BIN_DIR" sh
export PATH="$UV_BIN_DIR:$PATH"
command -v uv &>/dev/null || {
echo "error: failed to install uv" >&2
exit 1
}
fi

60
test.sh
View File

@@ -1,60 +0,0 @@
#!/usr/bin/env bash
set -e
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
# Create a temporary virtualenv
VENV_DIR="$(mktemp -d)"
trap 'rm -rf "$VENV_DIR"' EXIT
python3 -m venv "$VENV_DIR"
source "$VENV_DIR/bin/activate"
pip install --upgrade pip >/dev/null
# Auto-discover packages: any subdirectory containing a pyproject.toml
PACKAGES=()
for toml in "$REPO_DIR"/*/pyproject.toml; do
[ -f "$toml" ] || continue
PACKAGES+=("$(dirname "$toml")")
done
if [ ${#PACKAGES[@]} -eq 0 ]; then
echo "No packages found."
exit 1
fi
FAILED=()
for pkg in "${PACKAGES[@]}"; do
name="$(basename "$pkg")"
echo "========================================="
echo "Testing: $name"
echo "========================================="
# Install from git URL with subdirectory (simulates real-world usage)
echo "[$name] pip install ..."
pip install "$pkg" --verbose
# Verify import works
module="${name//-/_}"
echo "[$name] Verifying import of $module ..."
python -c "import $module; print(f'{$module.__name__} OK')"
echo "[$name] PASSED"
echo
done
if [ ${#FAILED[@]} -ne 0 ]; then
echo "FAILED packages: ${FAILED[*]}"
exit 1
fi
echo "All ${#PACKAGES[@]} package(s) passed."
echo
echo "Installed sizes:"
for pkg in "${PACKAGES[@]}"; do
name="$(basename "$pkg")"
module="${name//-/_}"
mod_dir="$(python -c "import $module, os; print(os.path.dirname($module.__file__))")"
size="$(du -sh "$mod_dir" | cut -f1)"
echo " $name: $size"
done

42
test_wheels_in_image.sh Executable file
View File

@@ -0,0 +1,42 @@
#!/usr/bin/env bash
set -euo pipefail
# a small script for testing our built wheels in a variety of linux distros
IMAGE="${1:?usage: ./test_wheels_in_image.sh <image>}"
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$ROOT_DIR"
# setup our deps - should only need a python3 build
docker build -t wheeltest -f - . <<DOCKERFILE
FROM $IMAGE
RUN if command -v apk >/dev/null; then \
apk add --no-cache python3 py3-pip bash; \
elif command -v apt-get >/dev/null; then \
apt-get update && apt-get install -y --no-install-recommends python3 python3-pip python3-venv; \
elif command -v dnf >/dev/null; then \
dnf install -y python3 python3-pip; \
elif command -v pacman >/dev/null; then \
pacman -Sy --noconfirm python python-pip; \
elif command -v zypper >/dev/null; then \
zypper install -y python3 python3-pip; \
elif command -v xbps-install >/dev/null; then \
xbps-install -Sy python3 python3-pip bash; \
fi
DOCKERFILE
# install + smoketest
docker run --rm -v "$PWD:/work" -w /work wheeltest bash -lc '
set -euo pipefail
python3 -m venv /tmp/venv
source /tmp/venv/bin/activate
pip install dist/*.whl
for toml in */pyproject.toml; do
module="$(basename "$(dirname "$toml")" | tr "-" "_")"
python -c "import $module; $module.smoketest()" && echo "$module: OK"
done
'
echo
echo "All good!"

61
zeromq/build.sh Executable file
View File

@@ -0,0 +1,61 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="4.3.5"
INSTALL_DIR="$DIR/zeromq/install"
# Idempotent: skip if already built
if [ -f "$INSTALL_DIR/lib/libzmq.a" ]; then
echo "zeromq already present, skipping build."
exit 0
fi
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
# Clone
if [ ! -d "libzmq-src" ]; then
git clone --depth 1 --branch "v${VERSION}" https://github.com/zeromq/libzmq.git libzmq-src
fi
# Build
PREFIX="$DIR/build/prefix"
mkdir -p "$DIR/build"
cmake -S libzmq-src -B "$DIR/build" \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_C_FLAGS="-fPIC" \
-DCMAKE_CXX_FLAGS="-fPIC" \
-DWITH_LIBSODIUM=OFF \
-DWITH_TLS=OFF \
-DWITH_DOCS=OFF \
-DBUILD_TESTS=OFF \
-DBUILD_SHARED=OFF \
-DBUILD_STATIC=ON \
-DENABLE_DRAFTS=OFF
cmake --build "$DIR/build" -j"$NJOBS"
cmake --install "$DIR/build"
# Copy to package install dir
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{lib,include}
# Library
cp "$PREFIX/lib/libzmq.a" "$INSTALL_DIR/lib/"
# Headers
cp "$PREFIX/include/zmq.h" "$INSTALL_DIR/include/"
cp "$PREFIX/include/zmq_utils.h" "$INSTALL_DIR/include/"
# Clean up
rm -rf libzmq-src "$DIR/build"
echo "Installed zeromq to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

15
zeromq/pyproject.toml Normal file
View File

@@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "zeromq"
version = "4.3.5"
description = "ZeroMQ messaging library (static build)"
requires-python = ">=3.8"
[tool.setuptools.packages.find]
include = ["zeromq*"]
[tool.setuptools.package-data]
zeromq = ["install/**/*"]

61
zeromq/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildZeromq(build_py):
"""Run build.sh to compile zeromq before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "zeromq", "install", "lib", "libzmq.a")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildZeromq}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

10
zeromq/zeromq/__init__.py Normal file
View File

@@ -0,0 +1,10 @@
import os
DIR = os.path.join(os.path.dirname(__file__), "install")
LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include")
def smoketest():
assert os.path.isfile(os.path.join(LIB_DIR, "libzmq.a")), "libzmq.a not found"
assert os.path.isfile(os.path.join(INCLUDE_DIR, "zmq.h")), "zmq.h not found"

59
zstd/build.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd "$DIR"
VERSION="1.5.6"
INSTALL_DIR="$DIR/zstd/install"
# Idempotent: skip if already built
if [ -f "$INSTALL_DIR/lib/libzstd.a" ]; then
echo "zstd already present, skipping build."
exit 0
fi
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
# Clone
if [ ! -d "zstd-src" ]; then
git clone --depth 1 --branch "v${VERSION}" https://github.com/facebook/zstd.git zstd-src
fi
# Build
PREFIX="$DIR/build/prefix"
mkdir -p "$DIR/build"
cmake -S zstd-src/build/cmake -B "$DIR/build" \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_C_FLAGS="-fPIC" \
-DZSTD_BUILD_PROGRAMS=OFF \
-DZSTD_BUILD_TESTS=OFF \
-DZSTD_BUILD_CONTRIB=OFF \
-DZSTD_BUILD_SHARED=OFF \
-DZSTD_BUILD_STATIC=ON
cmake --build "$DIR/build" -j"$NJOBS"
cmake --install "$DIR/build"
# Copy to package install dir
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"/{lib,include}
# Library
cp "$PREFIX/lib/libzstd.a" "$INSTALL_DIR/lib/"
# Headers
cp "$PREFIX/include/zstd.h" "$INSTALL_DIR/include/"
cp "$PREFIX/include/zstd_errors.h" "$INSTALL_DIR/include/"
cp "$PREFIX/include/zdict.h" "$INSTALL_DIR/include/"
# Clean up
rm -rf zstd-src "$DIR/build"
echo "Installed zstd to $INSTALL_DIR"
du -sh "$INSTALL_DIR"

15
zstd/pyproject.toml Normal file
View File

@@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=64", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "zstd"
version = "1.5.6"
description = "Zstandard compression library (static build)"
requires-python = ">=3.8"
[tool.setuptools.packages.find]
include = ["zstd*"]
[tool.setuptools.package-data]
zstd = ["install/**/*"]

61
zstd/setup.py Normal file
View File

@@ -0,0 +1,61 @@
import os
import platform
import subprocess
from setuptools.command.build_py import build_py
try:
from wheel.bdist_wheel import bdist_wheel
except ImportError:
bdist_wheel = None
class BuildZstd(build_py):
"""Run build.sh to compile zstd before collecting package data."""
def run(self):
pkg_dir = os.path.dirname(os.path.abspath(__file__))
marker = os.path.join(pkg_dir, "zstd", "install", "lib", "libzstd.a")
if not os.path.exists(marker):
build_script = os.path.join(pkg_dir, "build.sh")
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
super().run()
cmdclass = {"build_py": BuildZstd}
if bdist_wheel is not None:
class PlatformWheel(bdist_wheel):
"""Produce a platform-specific, Python-version-agnostic wheel."""
def finalize_options(self):
super().finalize_options()
self.root_is_pure = False
def get_tag(self):
system = platform.system()
machine = platform.machine()
if system == "Linux":
plat = f"linux_{machine}"
elif system == "Darwin":
plat = "macosx_11_0_arm64"
else:
plat = f"{system.lower()}_{machine}"
return "py3", "none", plat
cmdclass["bdist_wheel"] = PlatformWheel
def setup():
from setuptools import setup as _setup
_setup(cmdclass=cmdclass)
if __name__ == "__main__":
setup()

10
zstd/zstd/__init__.py Normal file
View File

@@ -0,0 +1,10 @@
import os
DIR = os.path.join(os.path.dirname(__file__), "install")
LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include")
def smoketest():
assert os.path.isfile(os.path.join(LIB_DIR, "libzstd.a")), "libzstd.a not found"
assert os.path.isfile(os.path.join(INCLUDE_DIR, "zstd.h")), "zstd.h not found"