Compare commits

...

5 Commits

Author SHA1 Message Date
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
6 changed files with 100 additions and 10 deletions

View File

@@ -33,6 +33,15 @@ if [[ "$(uname)" == "Linux" ]]; then
sudo apt-get update && sudo apt-get install -y libdrm-dev libgbm-dev libgles2-mesa-dev libegl1-mesa-dev || true sudo apt-get update && sudo apt-get install -y libdrm-dev libgbm-dev libgles2-mesa-dev libegl1-mesa-dev || true
fi fi
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 else
# desktop: needs X11/GL dev packages # desktop: needs X11/GL dev packages
if command -v dnf &>/dev/null; then if command -v dnf &>/dev/null; then
@@ -48,10 +57,10 @@ if [[ "$(uname)" == "Linux" ]]; then
fi fi
# Clone and build raylib C library # Clone and build raylib C library
RAYLIB_COMMIT="aa6ade09ac4bfb2847a356535f2d9f87e49ab089" RAYLIB_COMMIT="d9d7cc1353ec0f73c97e84ddf0973983d1ee25e2"
if [ ! -d "raylib-src" ]; then if [ ! -d "raylib-src" ]; then
git clone -b master --no-tags https://github.com/commaai/raylib.git raylib-src git clone -b platform-offscreen --no-tags https://github.com/commaai/raylib.git raylib-src
fi fi
cd raylib-src cd raylib-src
@@ -71,6 +80,42 @@ mkdir -p "$INSTALL_DIR"/{lib,include}
cp raylib-src/src/libraylib.a "$INSTALL_DIR/lib/" 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/" 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 # Download raygui header
RAYGUI_COMMIT="76b36b597edb70ffaf96f046076adc20d67e7827" RAYGUI_COMMIT="76b36b597edb70ffaf96f046076adc20d67e7827"
curl -fsSLo "$INSTALL_DIR/include/raygui.h" \ curl -fsSLo "$INSTALL_DIR/include/raygui.h" \

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "raylib" name = "raylib"
version = "5.5.0.3" version = "5.5.0.6"
description = "raylib + pyray Python bindings (commaai fork)" description = "raylib + pyray Python bindings (commaai fork)"
requires-python = ">=3.8" requires-python = ">=3.8"
dependencies = ["cffi>=1.17.1"] dependencies = ["cffi>=1.17.1"]

View File

@@ -1,26 +1,60 @@
import os import os
import platform as _platform
DIR = os.path.join(os.path.dirname(__file__), "install") DIR = os.path.join(os.path.dirname(__file__), "install")
LIB_DIR = os.path.join(DIR, "lib") LIB_DIR = os.path.join(DIR, "lib")
INCLUDE_DIR = os.path.join(DIR, "include") 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(): def smoketest():
assert os.path.isfile(os.path.join(LIB_DIR, "libraylib.a")), "libraylib.a not found" 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" 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 # Build CFFI extension on first import if not already compiled,
# or rebuild if the target platform changed since last build.
def _ensure_cffi_built(): def _ensure_cffi_built():
import glob import glob
import subprocess import subprocess
import sys import sys
pkg_dir = os.path.dirname(__file__) pkg_dir = os.path.dirname(__file__)
if not glob.glob(os.path.join(pkg_dir, "_raylib_cffi*")): 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") 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")): if os.path.isfile(build_script) and os.path.isfile(os.path.join(LIB_DIR, "libraylib.a")):
try: try:
subprocess.check_call([sys.executable, build_script], cwd=os.path.dirname(pkg_dir)) 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: except subprocess.CalledProcessError:
pass pass

View File

@@ -93,7 +93,7 @@ def build_ffi():
'-framework', 'CoreVideo', '-framework', 'CoreVideo',
] ]
libraries = [] libraries = []
extra_compile_args = ["-Wno-error=incompatible-function-pointer-types", "-D_CFFI_NO_LIMITED_API"] extra_compile_args = ["-Wno-error=incompatible-function-pointer-types"]
else: else:
print("BUILDING FOR LINUX") print("BUILDING FOR LINUX")
extra_link_args = [ extra_link_args = [
@@ -104,15 +104,26 @@ def build_ffi():
if RAYLIB_PLATFORM == "PLATFORM_COMMA": if RAYLIB_PLATFORM == "PLATFORM_COMMA":
extra_link_args.remove('-lGL') extra_link_args.remove('-lGL')
extra_link_args += ['-lGLESv2', '-lEGL', '-lgbm', '-ldrm'] 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: else:
extra_link_args += ['-lX11'] extra_link_args += ['-lX11']
extra_compile_args = ["-Wno-incompatible-pointer-types", "-D_CFFI_NO_LIMITED_API"] extra_compile_args = ["-Wno-incompatible-pointer-types"]
libraries = [] libraries = []
print("extra_link_args: " + str(extra_link_args)) print("extra_link_args: " + str(extra_link_args))
ffibuilder.set_source("raylib._raylib_cffi", ffibuilder.set_source("raylib._raylib_cffi",
ffi_includes, ffi_includes,
py_limited_api=False, py_limited_api=True,
include_dirs=[RAYLIB_INCLUDE_PATH], include_dirs=[RAYLIB_INCLUDE_PATH],
extra_link_args=extra_link_args, extra_link_args=extra_link_args,
extra_compile_args=extra_compile_args, extra_compile_args=extra_compile_args,

View File

@@ -1 +1 @@
__version__ = "5.5.0.2" __version__ = "5.5.0.6"

View File

@@ -107,7 +107,7 @@ for toml in sorted(pathlib.Path(".").glob("*/pyproject.toml")):
f"include = {json.dumps(find_include)}", f"include = {json.dumps(find_include)}",
"", "",
"[tool.setuptools.package-data]", "[tool.setuptools.package-data]",
f'{module} = ["{datadir}/**/*"]', f'{module} = ["{datadir}/**/*", "*.so"]',
"", "",
"[tool.shim]", "[tool.shim]",
f'repo_url = "{repo_url}"', f'repo_url = "{repo_url}"',