Compare commits
38 Commits
raylib/v5.
...
xvfb/v1.20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
975313a86f | ||
|
|
19a9ed13c0 | ||
|
|
f9dd627e57 | ||
|
|
058ed3c076 | ||
|
|
9f9bc38a3e | ||
|
|
79fefe6558 | ||
|
|
2f5b981c19 | ||
|
|
54dafe6c1b | ||
|
|
0fc2d13e50 | ||
|
|
567fde8231 | ||
|
|
d1af35e660 | ||
|
|
5457e99bb7 | ||
|
|
0f28906d50 | ||
|
|
8b6c712f60 | ||
|
|
6ad06e2173 | ||
|
|
577b731299 | ||
|
|
6692e3d936 | ||
|
|
6bc1fe9a9a | ||
|
|
14d916d054 | ||
|
|
62afc9ea71 | ||
|
|
c55046f7f0 | ||
|
|
a78417ecd1 | ||
|
|
d14d45aef4 | ||
|
|
224cbbb783 | ||
|
|
53271a60fa | ||
|
|
8d9b59b9d0 | ||
|
|
950d288e77 | ||
|
|
331d94a683 | ||
|
|
2e9aed768a | ||
|
|
65674ad817 | ||
|
|
61379f09ec | ||
|
|
21bb9ab18e | ||
|
|
2341b89849 | ||
|
|
7d158432af | ||
|
|
c81badf4a5 | ||
|
|
122939fdf2 | ||
|
|
9690fd5160 | ||
|
|
c835b206c6 |
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
@@ -23,13 +23,15 @@ jobs:
|
||||
- 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 }}-
|
||||
key: build-cache-v2-${{ matrix.platform }}-${{ hashFiles('build.sh', 'setup.sh', '*/pyproject.toml', '*/setup.py', '*/build.sh') }}
|
||||
restore-keys: build-cache-v2-${{ matrix.platform }}-
|
||||
path: |
|
||||
.uv-cache
|
||||
*/*/install
|
||||
*/*/toolchain
|
||||
*/*/bin
|
||||
*/*-src
|
||||
*/build
|
||||
- name: Build wheels
|
||||
env:
|
||||
MANYLINUX: ${{ runner.os == 'Linux' && '1' || '0' }}
|
||||
@@ -90,8 +92,8 @@ jobs:
|
||||
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 }}-
|
||||
key: build-cache-v2-${{ matrix.platform }}-${{ hashFiles('build.sh', 'setup.sh', '*/pyproject.toml', '*/setup.py', '*/build.sh') }}
|
||||
restore-keys: build-cache-v2-${{ matrix.platform }}-
|
||||
path: |
|
||||
.uv-cache
|
||||
*/*/install
|
||||
|
||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -2,6 +2,7 @@
|
||||
repo/
|
||||
.venv/
|
||||
__pycache__/
|
||||
uv.lock
|
||||
|
||||
# agents
|
||||
.claude/
|
||||
@@ -26,3 +27,12 @@ gcc-arm-none-eabi/gcc_arm_none_eabi/toolchain/
|
||||
|
||||
# downloaded git-lfs
|
||||
git-lfs/git_lfs/bin/
|
||||
|
||||
# downloaded mdbook
|
||||
mdbook/mdbook/bin/
|
||||
|
||||
# vendored at build time
|
||||
acados/acados/acados_template/
|
||||
acados/casadi/
|
||||
acados/casadi-venv/
|
||||
acados/casadi-wheel/
|
||||
|
||||
@@ -42,9 +42,9 @@ contributions welcome for other platforms!
|
||||
|
||||
```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 per-package release branches for pre-built wheels
|
||||
"capnproto @ git+https://github.com/commaai/dependencies.git@release-capnproto#subdirectory=capnproto",
|
||||
"ffmpeg @ git+https://github.com/commaai/dependencies.git@release-ffmpeg#subdirectory=ffmpeg",
|
||||
|
||||
# use the master branch to build the package on pip install
|
||||
"capnproto @ git+https://github.com/commaai/dependencies.git@master#subdirectory=capnproto",
|
||||
@@ -58,4 +58,4 @@ 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
|
||||
* each `release-<package>` branch contains a single shim package, so old lockfiles keep resolving even as new packages are added
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
"""Shim setup.py: downloads pre-built wheels from GitHub Releases at install time."""
|
||||
import os
|
||||
import platform
|
||||
import time
|
||||
import zipfile
|
||||
from io import BytesIO
|
||||
from urllib.error import URLError
|
||||
from urllib.request import urlopen
|
||||
|
||||
try:
|
||||
@@ -23,6 +25,17 @@ DATADIR = _cfg["tool"]["shim"]["datadir"]
|
||||
VERSION = _cfg["project"]["version"]
|
||||
MODULE = _cfg["project"]["name"].replace("-", "_")
|
||||
|
||||
# all top-level packages bundled in this wheel (e.g. acados + casadi).
|
||||
# `packages` may be a flat list or a dict with find.include patterns.
|
||||
_pkgs = _cfg.get("tool", {}).get("setuptools", {}).get("packages", [f"{MODULE}*"])
|
||||
if isinstance(_pkgs, list):
|
||||
_INCLUDE = _pkgs
|
||||
elif isinstance(_pkgs, dict):
|
||||
_INCLUDE = _pkgs.get("find", {}).get("include", [f"{MODULE}*"])
|
||||
else:
|
||||
_INCLUDE = [f"{MODULE}*"]
|
||||
TOP_PACKAGES = sorted({p.rstrip("*").rstrip("/") for p in _INCLUDE if p.rstrip("*").rstrip("/")})
|
||||
|
||||
PLATFORM_MAP = {
|
||||
("Linux", "x86_64"): "linux_x86_64",
|
||||
("Linux", "aarch64"): "linux_aarch64",
|
||||
@@ -41,50 +54,52 @@ class InstallPrebuilt(build_py):
|
||||
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}"
|
||||
whl_names = [
|
||||
f"{MODULE}-{VERSION}-py3-none-{plat}.whl",
|
||||
f"{MODULE}-{VERSION}-py3-none-any.whl",
|
||||
]
|
||||
|
||||
print(f"Downloading {url} ...")
|
||||
raw = urlopen(url).read()
|
||||
raw = None
|
||||
for whl_name in whl_names:
|
||||
url = f"{REPO_URL}/releases/download/{TAG}/{whl_name}"
|
||||
print(f"Downloading {url} ...")
|
||||
for attempt in range(3):
|
||||
try:
|
||||
raw = urlopen(url, timeout=60).read()
|
||||
break
|
||||
except (URLError, OSError) as e:
|
||||
if attempt == 2:
|
||||
if whl_name == whl_names[-1]:
|
||||
raise
|
||||
break
|
||||
wait = 2 ** attempt
|
||||
print(f"Download failed ({e}), retrying in {wait}s ...")
|
||||
time.sleep(wait)
|
||||
if raw is not None:
|
||||
break
|
||||
|
||||
print(f"Extracting {DATADIR} ...")
|
||||
print("Extracting wheel ...")
|
||||
with zipfile.ZipFile(BytesIO(raw)) as zf:
|
||||
prefix = f"{MODULE}/{DATADIR}/"
|
||||
alt_prefix = f"{MODULE}-{VERSION}.data/purelib/{MODULE}/{DATADIR}/"
|
||||
purelib_data = f"{MODULE}-{VERSION}.data/purelib/"
|
||||
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'):
|
||||
if info.is_dir():
|
||||
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
|
||||
name = info.filename
|
||||
if name.startswith(purelib_data):
|
||||
rel = name[len(purelib_data):]
|
||||
else:
|
||||
rel = name
|
||||
if "/" not in rel:
|
||||
continue
|
||||
top = rel.split("/", 1)[0]
|
||||
if top not in TOP_PACKAGES:
|
||||
continue
|
||||
dest = os.path.join(_HERE, 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)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
48
acados/acados/__init__.py
Normal file
48
acados/acados/__init__.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import os
|
||||
|
||||
DIR = os.path.join(os.path.dirname(__file__), "install")
|
||||
INCLUDE_DIR = os.path.join(DIR, "include")
|
||||
LIB_DIR = os.path.join(DIR, "lib")
|
||||
BIN_DIR = os.path.join(DIR, "bin")
|
||||
TERA_PATH = os.path.join(BIN_DIR, "t_renderer")
|
||||
|
||||
TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), "acados_template")
|
||||
|
||||
|
||||
def smoketest():
|
||||
import sys
|
||||
|
||||
lib_ext = ".dylib" if sys.platform == "darwin" else ".so"
|
||||
for lib in ("libacados", "libblasfeo", "libhpipm", "libqpOASES_e"):
|
||||
path = os.path.join(LIB_DIR, lib + lib_ext)
|
||||
assert os.path.isfile(path), f"missing lib: {path}"
|
||||
|
||||
assert os.path.isfile(os.path.join(INCLUDE_DIR, "acados_c", "ocp_nlp_interface.h"))
|
||||
assert os.path.isfile(os.path.join(INCLUDE_DIR, "blasfeo", "include", "blasfeo.h"))
|
||||
assert os.path.isfile(os.path.join(INCLUDE_DIR, "hpipm", "include", "hpipm_common.h"))
|
||||
|
||||
assert os.path.isfile(TERA_PATH) and os.access(TERA_PATH, os.X_OK), f"t_renderer missing/not executable: {TERA_PATH}"
|
||||
|
||||
assert os.path.isfile(os.path.join(TEMPLATE_DIR, "__init__.py"))
|
||||
assert os.path.isfile(os.path.join(TEMPLATE_DIR, "acados_layout.json"))
|
||||
assert os.path.isdir(os.path.join(TEMPLATE_DIR, "c_templates_tera"))
|
||||
|
||||
# the vendored slim casadi shipped in this wheel is built against cpython 3.12
|
||||
# and pulls in numpy; only exercise it when both are available (real consumers
|
||||
# like openpilot install via the shim, which declares numpy as a dep).
|
||||
try:
|
||||
import numpy # noqa: F401
|
||||
except ImportError:
|
||||
return
|
||||
if sys.version_info[:2] != (3, 12):
|
||||
return
|
||||
|
||||
from casadi import SX, MX, DM, Function, CasadiMeta, vertcat, jacobian, sin, cos, n_nodes # noqa: F401
|
||||
|
||||
x = SX.sym("x")
|
||||
y = SX.sym("y")
|
||||
expr = vertcat(sin(x), cos(y))
|
||||
J = jacobian(expr, vertcat(x, y))
|
||||
assert J.shape == (2, 2)
|
||||
assert n_nodes(J) > 0
|
||||
assert isinstance(CasadiMeta.version(), str)
|
||||
139
acados/build.sh
Executable file
139
acados/build.sh
Executable file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$DIR"
|
||||
|
||||
# v0.2.2
|
||||
VERSION="8af9b0ad180940ef611884574a0b27a43504311d"
|
||||
INSTALL_DIR="$DIR/acados/install"
|
||||
TEMPLATE_DIR="$DIR/acados/acados_template"
|
||||
CASADI_DIR="$DIR/casadi"
|
||||
CASADI_VERSION="3.6.7"
|
||||
|
||||
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
|
||||
|
||||
# pick BLAS target per host arch
|
||||
ARCH="$(uname -m)"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# this BLASFEO version doesn't have an Apple Silicon target; Cortex-A57
|
||||
# baseline ARMv8 SIMD compiles and runs fine on M1+.
|
||||
BLAS_TARGET="ARMV8A_ARM_CORTEX_A57"
|
||||
elif [[ "$ARCH" == "aarch64" ]]; then
|
||||
# Cortex-A57 = TICI baseline; safe for any modern aarch64
|
||||
BLAS_TARGET="ARMV8A_ARM_CORTEX_A57"
|
||||
else
|
||||
BLAS_TARGET="X64_AUTOMATIC"
|
||||
fi
|
||||
|
||||
ACADOS_FLAGS=(
|
||||
-DACADOS_WITH_QPOASES=ON
|
||||
-UBLASFEO_TARGET
|
||||
-DBLASFEO_TARGET="$BLAS_TARGET"
|
||||
-DACADOS_INSTALL_DIR="$INSTALL_DIR"
|
||||
# acados (and several of its submodules) still pin cmake_minimum_required <3.5;
|
||||
# CMake 4 removed that compatibility, so re-enable it here.
|
||||
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
# qpOASES + blasfeo both call malloc()/posix_memalign() without including
|
||||
# <stdlib.h>. C99/C2x and modern gcc/clang reject implicit declarations as
|
||||
# errors. qpOASES also has a real Constraints*/Constraints** pointer bug
|
||||
# that gcc 14+ now flags as an error too. Downgrade both so the upstream
|
||||
# (pinned) sources keep compiling.
|
||||
"-DCMAKE_C_FLAGS=-Wno-implicit-function-declaration -Wno-incompatible-pointer-types"
|
||||
)
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
ACADOS_FLAGS+=(
|
||||
-DCMAKE_OSX_ARCHITECTURES=arm64
|
||||
-DCMAKE_MACOSX_RPATH=1
|
||||
)
|
||||
fi
|
||||
|
||||
# clone/update source
|
||||
if [ ! -d "acados-src/.git" ]; then
|
||||
rm -rf acados-src
|
||||
git clone https://github.com/acados/acados.git acados-src
|
||||
fi
|
||||
git -C acados-src fetch --all --tags
|
||||
git -C acados-src checkout --force "$VERSION"
|
||||
git -C acados-src submodule update --init --recursive --depth=1
|
||||
|
||||
# build acados
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake "${ACADOS_FLAGS[@]}" "$DIR/acados-src"
|
||||
make -j"$NJOBS" install
|
||||
cd "$DIR"
|
||||
|
||||
# we don't ship sample json templates
|
||||
rm -f "$INSTALL_DIR"/lib/*.json
|
||||
|
||||
# python interface package (acados_template)
|
||||
rm -rf "$TEMPLATE_DIR"
|
||||
cp -r acados-src/interfaces/acados_template/acados_template "$TEMPLATE_DIR"
|
||||
|
||||
# strip future_fstrings (avoids needing the compatibility package on py>=3.6).
|
||||
# Cython chokes on the unknown encoding in .pyx/.pxd too, not just .py.
|
||||
find "$TEMPLATE_DIR" -type f \( -name '*.py' -o -name '*.pyx' -o -name '*.pxd' \) \
|
||||
-exec sed -i.bak '/future.fstrings/d' {} +
|
||||
find "$TEMPLATE_DIR" -name '*.bak' -delete
|
||||
|
||||
# acados_template's gnsf/check_reformulation.py uses an absolute `from
|
||||
# acados_template.utils import ...` that only worked when acados_template was
|
||||
# itself a top-level package on the path. We ship it as `acados.acados_template`,
|
||||
# so rewrite to the relative form the rest of gnsf already uses.
|
||||
if [ -f "$TEMPLATE_DIR/gnsf/check_reformulation.py" ]; then
|
||||
sed -i.bak 's/^from acados_template\.utils /from ..utils /' "$TEMPLATE_DIR/gnsf/check_reformulation.py"
|
||||
rm -f "$TEMPLATE_DIR/gnsf/check_reformulation.py.bak"
|
||||
fi
|
||||
|
||||
# build tera renderer (needs cargo)
|
||||
if ! command -v cargo >/dev/null 2>&1; then
|
||||
echo "installing rust toolchain (needed for tera_renderer)..."
|
||||
curl -LsSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
|
||||
# shellcheck disable=SC1091
|
||||
source "$HOME/.cargo/env"
|
||||
fi
|
||||
|
||||
mkdir -p "$INSTALL_DIR/bin"
|
||||
cd "$DIR/acados-src/interfaces/acados_template/tera_renderer/"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
cargo build --release --target aarch64-apple-darwin
|
||||
cp target/aarch64-apple-darwin/release/t_renderer "$INSTALL_DIR/bin/t_renderer"
|
||||
else
|
||||
cargo build --release
|
||||
cp target/release/t_renderer "$INSTALL_DIR/bin/t_renderer"
|
||||
fi
|
||||
|
||||
cd "$DIR"
|
||||
|
||||
# vendor a slim casadi: install the upstream wheel into a throwaway cp312 venv
|
||||
# (uv resolves the right platform wheel automatically), then move the casadi/
|
||||
# tree out and slim it.
|
||||
echo "vendoring casadi $CASADI_VERSION ..."
|
||||
rm -rf "$CASADI_DIR" casadi-venv
|
||||
uv venv --python 3.12 --quiet casadi-venv
|
||||
uv pip install --python casadi-venv/bin/python --no-deps --quiet "casadi==$CASADI_VERSION"
|
||||
mv casadi-venv/lib/python3.12/site-packages/casadi "$CASADI_DIR"
|
||||
rm -rf casadi-venv
|
||||
|
||||
# drop everything except the bits openpilot actually needs:
|
||||
# - __init__.py, casadi.py, tools/ (Python wrapper)
|
||||
# - _casadi.so (CPython extension; same name on linux+darwin)
|
||||
# - libcasadi.{so,dylib}* (the C++ runtime that _casadi.so links to)
|
||||
# openpilot only uses symbolic SX/MX/Function/jacobian etc., which live in
|
||||
# libcasadi + _casadi. Solver plugins (conic_*, nlpsol_*, integrator_*, ...)
|
||||
# and their third-party backends (ipopt, bonmin, hpipm, fatrop, ...) are
|
||||
# loaded lazily via dlopen and never reached.
|
||||
cd "$CASADI_DIR"
|
||||
shopt -s extglob
|
||||
# libc++.*.dylib only exists on darwin and is needed by _casadi.so via @rpath
|
||||
rm -rf !(__init__.py|casadi.py|_casadi.so|tools|libcasadi.*|libc++.*)
|
||||
shopt -u extglob
|
||||
|
||||
cd "$DIR"
|
||||
rm -rf casadi-wheel
|
||||
|
||||
echo "Installed acados to $INSTALL_DIR"
|
||||
du -sh "$INSTALL_DIR"
|
||||
echo "Vendored casadi (slim) at $CASADI_DIR"
|
||||
du -sh "$CASADI_DIR"
|
||||
23
acados/pyproject.toml
Normal file
23
acados/pyproject.toml
Normal file
@@ -0,0 +1,23 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=64", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "acados"
|
||||
version = "0.2.2"
|
||||
description = "acados solvers + Python interface, with a slimmed casadi vendored alongside"
|
||||
requires-python = ">=3.8"
|
||||
dependencies = [
|
||||
# the vendored casadi.py shim imports numpy at module load time
|
||||
"numpy",
|
||||
]
|
||||
|
||||
# `find` runs at setup() init time, before build.sh creates these dirs, so
|
||||
# enumerate packages explicitly. acados.acados_template + casadi.tools are
|
||||
# subpackages and ship via package-data.
|
||||
[tool.setuptools]
|
||||
packages = ["acados", "casadi"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
acados = ["install/**/*", "acados_template/**/*"]
|
||||
casadi = ["**/*"]
|
||||
68
acados/setup.py
Normal file
68
acados/setup.py
Normal file
@@ -0,0 +1,68 @@
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
|
||||
from setuptools.command.build_py import build_py
|
||||
|
||||
# `casadi/` is generated by build.sh (vendored from the upstream wheel), but
|
||||
# setuptools requires every declared package to have a directory + __init__.py
|
||||
# *before* any command runs. Drop a stub if it isn't there yet — build.sh
|
||||
# replaces it with the real slim casadi during build_py.
|
||||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
_casadi_init = os.path.join(_HERE, "casadi", "__init__.py")
|
||||
if not os.path.exists(_casadi_init):
|
||||
os.makedirs(os.path.dirname(_casadi_init), exist_ok=True)
|
||||
open(_casadi_init, "w").close()
|
||||
|
||||
try:
|
||||
from wheel.bdist_wheel import bdist_wheel
|
||||
except ImportError:
|
||||
bdist_wheel = None
|
||||
|
||||
|
||||
class BuildAcados(build_py):
|
||||
"""Run build.sh to compile acados before collecting package data."""
|
||||
|
||||
def run(self):
|
||||
pkg_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
cmdclass = {"build_py": BuildAcados}
|
||||
|
||||
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
build.sh
10
build.sh
@@ -34,6 +34,9 @@ fi
|
||||
if [[ -n "${BUILD_SH_IN_MANYLINUX:-}" ]]; then
|
||||
export PATH="/opt/python/cp312-cp312/bin:$PATH"
|
||||
|
||||
# cached *-src repos may be owned by the host runner user; tell git to trust them
|
||||
git config --global --add safe.directory '*'
|
||||
|
||||
./setup.sh
|
||||
|
||||
if [[ -z "${BUILD_SH_REUSE_MANYLINUX_ARTIFACTS:-}" ]]; then
|
||||
@@ -45,10 +48,15 @@ if [[ -n "${BUILD_SH_IN_MANYLINUX:-}" ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
export CMAKE_C_COMPILER_LAUNCHER=ccache
|
||||
export CMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
|
||||
echo "Building workspace packages into dist"
|
||||
START_SECS=$SECONDS
|
||||
|
||||
uv build --all-packages --wheel --out-dir dist --no-create-gitignore --no-build-logs
|
||||
mkdir -p dist/
|
||||
rm -rf dist/*
|
||||
uv build --all-packages --wheel --out-dir dist --no-create-gitignore
|
||||
|
||||
if [[ -n "${BUILD_SH_IN_MANYLINUX:-}" ]]; then
|
||||
VENV_DIR="$ROOT_DIR/.venv-manylinux"
|
||||
|
||||
@@ -4,24 +4,19 @@ set -e
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$DIR"
|
||||
|
||||
VERSION="1.0.8"
|
||||
VERSION="bzip2-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)"
|
||||
CC="ccache ${CC:-cc}"
|
||||
|
||||
# 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
|
||||
# Clone/update source
|
||||
if [ ! -d "bzip2-src/.git" ]; then
|
||||
rm -rf bzip2-src
|
||||
git clone --depth 1 https://gitlab.com/bzip2/bzip2.git bzip2-src
|
||||
fi
|
||||
git -C bzip2-src fetch --depth 1 origin "$VERSION"
|
||||
git -C bzip2-src checkout --force FETCH_HEAD
|
||||
|
||||
# Build static library with -fPIC
|
||||
cd bzip2-src
|
||||
@@ -38,8 +33,5 @@ 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"
|
||||
|
||||
@@ -15,11 +15,8 @@ class BuildBzip2(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
@@ -7,18 +7,15 @@ 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
|
||||
# Clone/update source
|
||||
if [ ! -d "capnproto-src/.git" ]; then
|
||||
rm -rf capnproto-src
|
||||
git clone --depth 1 https://github.com/capnproto/capnproto.git capnproto-src
|
||||
fi
|
||||
git -C capnproto-src fetch --depth 1 origin "v${VERSION}"
|
||||
git -C capnproto-src checkout --force FETCH_HEAD
|
||||
|
||||
# Build
|
||||
PREFIX="$DIR/build/prefix"
|
||||
@@ -64,8 +61,5 @@ 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"
|
||||
|
||||
@@ -15,11 +15,8 @@ class BuildCapnproto(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
22
catch2/build.sh
Executable file
22
catch2/build.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$DIR"
|
||||
|
||||
VERSION="v2.13.10"
|
||||
INSTALL_DIR="$DIR/catch2/install"
|
||||
|
||||
if [ ! -d "catch2-src/.git" ]; then
|
||||
rm -rf catch2-src
|
||||
git clone --depth 1 https://github.com/catchorg/Catch2.git catch2-src
|
||||
fi
|
||||
git -C catch2-src fetch --depth 1 origin "$VERSION"
|
||||
git -C catch2-src checkout --force FETCH_HEAD
|
||||
|
||||
rm -rf "$INSTALL_DIR"
|
||||
mkdir -p "$INSTALL_DIR/include"
|
||||
cp -r catch2-src/single_include/catch2 "$INSTALL_DIR/include/"
|
||||
|
||||
echo "Installed catch2 to $INSTALL_DIR"
|
||||
du -sh "$INSTALL_DIR"
|
||||
9
catch2/catch2/__init__.py
Normal file
9
catch2/catch2/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import os
|
||||
|
||||
DIR = os.path.join(os.path.dirname(__file__), "install")
|
||||
INCLUDE_DIR = os.path.join(DIR, "include")
|
||||
LIB_DIR = DIR # header-only; no libraries
|
||||
|
||||
|
||||
def smoketest():
|
||||
assert os.path.isfile(os.path.join(INCLUDE_DIR, "catch2", "catch.hpp")), "catch2/catch.hpp not found"
|
||||
16
catch2/pyproject.toml
Normal file
16
catch2/pyproject.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=64", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "catch2"
|
||||
version = "2.13.10"
|
||||
description = "Catch2 C++ test framework headers"
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
include = ["catch2*"]
|
||||
exclude = ["catch2-src*"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
catch2 = ["install/**/*"]
|
||||
28
catch2/setup.py
Normal file
28
catch2/setup.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from setuptools.command.build_py import build_py
|
||||
|
||||
|
||||
class BuildCatch2(build_py):
|
||||
"""Run build.sh to download Catch2 headers before collecting package data."""
|
||||
|
||||
def run(self):
|
||||
pkg_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
cmdclass = {"build_py": BuildCatch2}
|
||||
|
||||
|
||||
def setup():
|
||||
from setuptools import setup as _setup
|
||||
|
||||
_setup(cmdclass=cmdclass)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup()
|
||||
@@ -7,18 +7,16 @@ 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)"
|
||||
CXX="ccache ${CXX:-c++}"
|
||||
|
||||
# Clone
|
||||
if [ ! -d "cppcheck-src" ]; then
|
||||
git clone --depth 1 --branch "$VERSION" https://github.com/danmar/cppcheck.git cppcheck-src
|
||||
# Clone/update source
|
||||
if [ ! -d "cppcheck-src/.git" ]; then
|
||||
rm -rf cppcheck-src
|
||||
git clone --depth 1 https://github.com/danmar/cppcheck.git cppcheck-src
|
||||
fi
|
||||
git -C cppcheck-src fetch --depth 1 origin "$VERSION"
|
||||
git -C cppcheck-src checkout --force FETCH_HEAD
|
||||
|
||||
# Build
|
||||
cd cppcheck-src
|
||||
@@ -35,8 +33,5 @@ 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"
|
||||
|
||||
@@ -15,11 +15,8 @@ class BuildCppcheck(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
@@ -7,28 +7,19 @@ 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
|
||||
# Clone/update source
|
||||
if [ ! -d "eigen-src/.git" ]; then
|
||||
rm -rf eigen-src
|
||||
git clone --depth 1 https://gitlab.com/libeigen/eigen.git eigen-src
|
||||
fi
|
||||
git -C eigen-src fetch --depth 1 origin "$VERSION"
|
||||
git -C eigen-src checkout --force FETCH_HEAD
|
||||
|
||||
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 ..."
|
||||
# Copy 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"
|
||||
cp -r eigen-src/Eigen "$INSTALL_DIR/eigen3/"
|
||||
cp -r eigen-src/unsupported "$INSTALL_DIR/eigen3/"
|
||||
|
||||
echo "Installed eigen to $INSTALL_DIR"
|
||||
du -sh "$INSTALL_DIR"
|
||||
|
||||
@@ -15,11 +15,8 @@ class BuildEigen(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
136
ffmpeg/build.sh
136
ffmpeg/build.sh
@@ -4,24 +4,26 @@ set -e
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$DIR"
|
||||
|
||||
PLATFORM="$(uname -s)"
|
||||
FFMPEG_VERSION="7.1"
|
||||
ZLIB_VERSION="da607da739fa6047df13e66a2af6b8bec7c2a498" # v1.3.2
|
||||
X264_BRANCH="stable"
|
||||
LIBDRM_VERSION="libdrm-2.4.124"
|
||||
LIBVA_VERSION="2.22.0"
|
||||
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)"
|
||||
CC="ccache ${CC:-cc}"
|
||||
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
|
||||
if [ ! -d "zlib-src/.git" ]; then
|
||||
rm -rf zlib-src
|
||||
git clone --depth 1 https://github.com/madler/zlib.git zlib-src
|
||||
fi
|
||||
git -C zlib-src fetch --depth 1 origin "$ZLIB_VERSION"
|
||||
git -C zlib-src checkout --force "$ZLIB_VERSION"
|
||||
|
||||
cd zlib-src
|
||||
./configure --prefix="$PREFIX" --static
|
||||
@@ -30,9 +32,12 @@ 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
|
||||
if [ ! -d "x264-src/.git" ]; then
|
||||
rm -rf x264-src
|
||||
git clone --depth 1 https://code.videolan.org/videolan/x264.git x264-src
|
||||
fi
|
||||
git -C x264-src fetch --depth 1 origin "$X264_BRANCH"
|
||||
git -C x264-src checkout --force FETCH_HEAD
|
||||
|
||||
cd x264-src
|
||||
CFLAGS="-fno-finite-math-only" ./configure \
|
||||
@@ -46,14 +51,104 @@ 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
|
||||
# --- Build nv-codec-headers (Linux only, for CUDA/NVDEC) ---
|
||||
if [ "$PLATFORM" = "Linux" ]; then
|
||||
if [ ! -d "nv-codec-headers-src/.git" ]; then
|
||||
rm -rf nv-codec-headers-src
|
||||
git clone --depth 1 https://git.videolan.org/git/ffmpeg/nv-codec-headers.git nv-codec-headers-src
|
||||
fi
|
||||
make -C nv-codec-headers-src PREFIX="$PREFIX" install
|
||||
fi
|
||||
|
||||
# --- Build Vulkan-Headers from source (Linux only, need >= 1.3.277 for FFmpeg 7.1) ---
|
||||
if [ "$PLATFORM" = "Linux" ]; then
|
||||
if [ ! -d "vulkan-headers-src/.git" ]; then
|
||||
rm -rf vulkan-headers-src
|
||||
git clone --depth 1 https://github.com/KhronosGroup/Vulkan-Headers.git vulkan-headers-src
|
||||
fi
|
||||
cmake -S vulkan-headers-src -B vulkan-headers-src/build -DCMAKE_INSTALL_PREFIX="$PREFIX" >/dev/null
|
||||
cmake --install vulkan-headers-src/build >/dev/null
|
||||
fi
|
||||
|
||||
# --- Build libdrm + libva statically (Linux only, for VAAPI without runtime deps) ---
|
||||
if [ "$PLATFORM" = "Linux" ]; then
|
||||
if ! command -v meson &>/dev/null; then
|
||||
pip3 install --quiet meson ninja 2>/dev/null || python3 -m pip install --quiet meson ninja 2>/dev/null || true
|
||||
command -v meson &>/dev/null || { echo "error: meson is required (apt install meson or pip install meson)" >&2; exit 1; }
|
||||
fi
|
||||
|
||||
if [ ! -d "libdrm-src/.git" ]; then
|
||||
rm -rf libdrm-src
|
||||
git clone --depth 1 --branch "$LIBDRM_VERSION" https://gitlab.freedesktop.org/mesa/drm.git libdrm-src
|
||||
fi
|
||||
rm -rf libdrm-src/builddir
|
||||
meson setup libdrm-src/builddir libdrm-src \
|
||||
--prefix="$PREFIX" --libdir=lib --default-library=static \
|
||||
-Dintel=disabled -Dradeon=disabled -Damdgpu=disabled -Dnouveau=disabled \
|
||||
-Dvmwgfx=disabled -Dtests=false -Dman-pages=disabled -Dcairo-tests=disabled \
|
||||
-Dvalgrind=disabled
|
||||
ninja -C libdrm-src/builddir install
|
||||
|
||||
if [ ! -d "libva-src/.git" ]; then
|
||||
rm -rf libva-src
|
||||
git clone --depth 1 --branch "$LIBVA_VERSION" https://github.com/intel/libva.git libva-src
|
||||
fi
|
||||
rm -rf libva-src/builddir
|
||||
# libva hardcodes shared_library(); patch to library() so --default-library=static works
|
||||
sed -i 's/shared_library(/library(/g' libva-src/va/meson.build
|
||||
PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" \
|
||||
meson setup libva-src/builddir libva-src \
|
||||
--prefix="$PREFIX" --libdir=lib --default-library=static \
|
||||
-Ddisable_drm=false -Dwith_x11=no -Dwith_glx=no -Dwith_wayland=no \
|
||||
-Dwith_win32=no -Denable_docs=false
|
||||
ninja -C libva-src/builddir install
|
||||
fi
|
||||
|
||||
# --- Build FFmpeg ---
|
||||
if [ ! -d "ffmpeg-src/.git" ]; then
|
||||
rm -rf ffmpeg-src
|
||||
git clone --depth 1 https://github.com/FFmpeg/FFmpeg.git ffmpeg-src
|
||||
fi
|
||||
git -C ffmpeg-src fetch --depth 1 origin "n${FFMPEG_VERSION}"
|
||||
git -C ffmpeg-src checkout --force FETCH_HEAD
|
||||
|
||||
cd ffmpeg-src
|
||||
|
||||
# Platform-specific hardware acceleration flags
|
||||
HW_FLAGS=()
|
||||
if [ "$PLATFORM" = "Linux" ]; then
|
||||
HW_FLAGS+=(
|
||||
# NVIDIA CUDA/NVDEC (uses dlopen at runtime)
|
||||
--enable-ffnvcodec --enable-cuda --enable-cuvid --enable-nvdec
|
||||
--enable-hwaccel=h264_nvdec,hevc_nvdec
|
||||
--enable-decoder=h264_cuvid,hevc_cuvid
|
||||
|
||||
# VAAPI (Intel/AMD — libva linked statically, driver loaded via dlopen at runtime)
|
||||
--enable-vaapi
|
||||
--enable-hwaccel=h264_vaapi,hevc_vaapi
|
||||
|
||||
# V4L2 Memory-to-Memory (embedded: RPi, Qualcomm, Rockchip)
|
||||
--enable-v4l2-m2m
|
||||
--enable-decoder=h264_v4l2m2m,hevc_v4l2m2m
|
||||
--enable-encoder=h264_v4l2m2m,hevc_v4l2m2m
|
||||
|
||||
# Vulkan video decode/encode (uses dlopen at runtime)
|
||||
--enable-vulkan
|
||||
--enable-hwaccel=h264_vulkan,hevc_vulkan
|
||||
--enable-encoder=h264_vulkan,hevc_vulkan
|
||||
)
|
||||
elif [ "$PLATFORM" = "Darwin" ]; then
|
||||
HW_FLAGS+=(
|
||||
# VideoToolbox (Apple Silicon / macOS)
|
||||
--enable-videotoolbox
|
||||
--enable-hwaccel=h264_videotoolbox,hevc_videotoolbox
|
||||
--enable-encoder=h264_videotoolbox,hevc_videotoolbox
|
||||
)
|
||||
fi
|
||||
|
||||
PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" \
|
||||
./configure \
|
||||
--cc="${CC:-cc}" \
|
||||
--prefix="$PREFIX" \
|
||||
--enable-gpl \
|
||||
--enable-static \
|
||||
@@ -64,6 +159,7 @@ PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" \
|
||||
--disable-doc \
|
||||
--disable-ffplay \
|
||||
--disable-autodetect \
|
||||
--disable-x86asm \
|
||||
--disable-everything \
|
||||
--enable-encoder=libx264,aac,ffvhuff,rawvideo,png,mjpeg \
|
||||
--enable-decoder=h264,hevc,ffvhuff,aac,rawvideo,png,mjpeg,mp3,pcm_s16le \
|
||||
@@ -74,7 +170,8 @@ PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" \
|
||||
--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"
|
||||
--extra-ldflags="-L$PREFIX/lib" \
|
||||
"${HW_FLAGS[@]}"
|
||||
make -j"$NJOBS"
|
||||
make install
|
||||
cd "$DIR"
|
||||
@@ -88,7 +185,11 @@ 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
|
||||
LIBS="libavformat.a libavcodec.a libavutil.a libswresample.a libx264.a libz.a"
|
||||
if [ "$PLATFORM" = "Linux" ]; then
|
||||
LIBS="$LIBS libva.a libva-drm.a libdrm.a"
|
||||
fi
|
||||
for lib in $LIBS; do
|
||||
cp "$PREFIX/lib/$lib" "$INSTALL_DIR/lib/"
|
||||
done
|
||||
|
||||
@@ -100,8 +201,5 @@ 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"
|
||||
|
||||
@@ -15,11 +15,8 @@ class BuildFFmpeg(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
@@ -9,10 +9,11 @@ TOOLCHAIN_BASE="arm-gnu-toolchain-${TOOLCHAIN_VERSION}"
|
||||
GCC_VERSION="13.2.1"
|
||||
|
||||
INSTALL_DIR="$DIR/gcc_arm_none_eabi/toolchain"
|
||||
VERSION_FILE="$INSTALL_DIR/.version"
|
||||
|
||||
# Idempotent: skip if already built
|
||||
if [ -x "$INSTALL_DIR/bin/arm-none-eabi-gcc" ]; then
|
||||
echo "Toolchain already present, skipping download."
|
||||
# Skip if already at correct version
|
||||
if [ -f "$VERSION_FILE" ] && [ "$(cat "$VERSION_FILE")" = "$TOOLCHAIN_VERSION" ]; then
|
||||
echo "Toolchain $TOOLCHAIN_VERSION already present, skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -112,6 +113,7 @@ find "$INSTALL_DIR" -type f \( -executable -o -name '*.so' \) -exec strip {} + 2
|
||||
# --- clean up download artifacts ---
|
||||
rm -rf "$EXTRACT_DIR"
|
||||
rm -f "$TARBALL"
|
||||
echo "$TOOLCHAIN_VERSION" > "$VERSION_FILE"
|
||||
|
||||
echo "Installed to $INSTALL_DIR"
|
||||
du -sh "$INSTALL_DIR"
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from setuptools.command.build_py import build_py
|
||||
from setuptools.dist import Distribution
|
||||
|
||||
try:
|
||||
from wheel.bdist_wheel import bdist_wheel
|
||||
@@ -17,13 +15,8 @@ class BuildToolchain(build_py):
|
||||
|
||||
def run(self):
|
||||
pkg_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
toolchain_marker = os.path.join(
|
||||
pkg_dir, "gcc_arm_none_eabi", "toolchain", "bin", "arm-none-eabi-gcc"
|
||||
)
|
||||
|
||||
if not os.path.exists(toolchain_marker):
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
@@ -6,10 +6,11 @@ cd "$DIR"
|
||||
|
||||
VERSION="3.6.1"
|
||||
INSTALL_DIR="$DIR/git_lfs/bin"
|
||||
VERSION_FILE="$INSTALL_DIR/.version"
|
||||
|
||||
# Idempotent: skip if already present
|
||||
if [ -x "$INSTALL_DIR/git-lfs" ]; then
|
||||
echo "git-lfs already present, skipping download."
|
||||
# Skip if already at correct version
|
||||
if [ -f "$VERSION_FILE" ] && [ "$(cat "$VERSION_FILE")" = "$VERSION" ]; then
|
||||
echo "git-lfs $VERSION already present, skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -51,6 +52,7 @@ fi
|
||||
chmod +x "$INSTALL_DIR/git-lfs"
|
||||
|
||||
rm -f "$FILENAME"
|
||||
echo "$VERSION" > "$VERSION_FILE"
|
||||
|
||||
echo "Installed git-lfs to $INSTALL_DIR"
|
||||
du -sh "$INSTALL_DIR"
|
||||
|
||||
@@ -15,11 +15,8 @@ class BuildGitLfs(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
189
git/build.sh
Executable file
189
git/build.sh
Executable file
@@ -0,0 +1,189 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$DIR"
|
||||
|
||||
VERSION="2.47.1"
|
||||
OPENSSL_VERSION="openssl-3.4.1"
|
||||
CURL_VERSION="curl-8_12_1"
|
||||
ZLIB_VERSION="v1.3.1"
|
||||
INSTALL_DIR="$DIR/git/install"
|
||||
VERSION_FILE="$INSTALL_DIR/.version"
|
||||
|
||||
# Skip if already at correct version
|
||||
if [ -f "$VERSION_FILE" ] && [ "$(cat "$VERSION_FILE")" = "$VERSION" ]; then
|
||||
echo "git $VERSION already present, skipping."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
PLATFORM="$(uname -s)"
|
||||
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/.git" ]; then
|
||||
rm -rf zlib-src
|
||||
git clone --depth 1 https://github.com/madler/zlib.git zlib-src
|
||||
fi
|
||||
git -C zlib-src fetch --depth 1 origin "$ZLIB_VERSION"
|
||||
git -C zlib-src checkout --force FETCH_HEAD
|
||||
|
||||
cd zlib-src
|
||||
./configure --prefix="$PREFIX" --static
|
||||
make -j"$NJOBS"
|
||||
make install
|
||||
cd "$DIR"
|
||||
|
||||
# --- Build OpenSSL (static) ---
|
||||
if [ ! -d "openssl-src/.git" ]; then
|
||||
rm -rf openssl-src
|
||||
git clone --depth 1 https://github.com/openssl/openssl.git openssl-src
|
||||
fi
|
||||
git -C openssl-src fetch --depth 1 origin "$OPENSSL_VERSION"
|
||||
git -C openssl-src checkout --force FETCH_HEAD
|
||||
|
||||
cd openssl-src
|
||||
./Configure \
|
||||
--prefix="$PREFIX" \
|
||||
--libdir=lib \
|
||||
no-shared \
|
||||
no-tests \
|
||||
no-docs
|
||||
make -j"$NJOBS"
|
||||
make install_sw
|
||||
cd "$DIR"
|
||||
|
||||
# --- Build curl (static, with openssl+zlib) ---
|
||||
if [ ! -d "curl-src/.git" ]; then
|
||||
rm -rf curl-src
|
||||
git clone --depth 1 https://github.com/curl/curl.git curl-src
|
||||
fi
|
||||
git -C curl-src fetch --depth 1 origin "$CURL_VERSION"
|
||||
git -C curl-src checkout --force FETCH_HEAD
|
||||
|
||||
cd curl-src
|
||||
autoreconf -fi
|
||||
PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig" \
|
||||
./configure \
|
||||
--prefix="$PREFIX" \
|
||||
--with-openssl="$PREFIX" \
|
||||
--with-zlib="$PREFIX" \
|
||||
--disable-shared \
|
||||
--enable-static \
|
||||
--disable-ldap \
|
||||
--disable-rtsp \
|
||||
--disable-dict \
|
||||
--disable-telnet \
|
||||
--disable-tftp \
|
||||
--disable-pop3 \
|
||||
--disable-imap \
|
||||
--disable-smb \
|
||||
--disable-smtp \
|
||||
--disable-gopher \
|
||||
--disable-mqtt \
|
||||
--disable-manual \
|
||||
--disable-docs \
|
||||
--without-libpsl \
|
||||
--without-brotli \
|
||||
--without-zstd \
|
||||
--without-libidn2 \
|
||||
--without-nghttp2 \
|
||||
--without-librtmp
|
||||
make -j"$NJOBS"
|
||||
make install
|
||||
cd "$DIR"
|
||||
|
||||
# --- Build git (with static curl+openssl+zlib) ---
|
||||
if [ ! -d "git-src/.git" ]; then
|
||||
rm -rf git-src
|
||||
git clone --depth 1 https://github.com/git/git.git git-src
|
||||
fi
|
||||
git -C git-src fetch --depth 1 origin "v${VERSION}"
|
||||
git -C git-src checkout --force FETCH_HEAD
|
||||
|
||||
# Gather static link flags for curl and openssl dependencies
|
||||
# CURL_LIBCURL: used by git-remote-http, git-http-fetch, git-http-push
|
||||
# LIB_4_CRYPTO: used by git-imap-send and other direct openssl consumers
|
||||
# Both need transitive deps (-ldl, -lpthread) since we link statically
|
||||
CRYPTO_DEPS="-lpthread"
|
||||
CURL_EXTRA=""
|
||||
if [ "$PLATFORM" = "Linux" ]; then
|
||||
CRYPTO_DEPS="$CRYPTO_DEPS -ldl"
|
||||
elif [ "$PLATFORM" = "Darwin" ]; then
|
||||
CURL_EXTRA="-framework SystemConfiguration -framework Security -framework CoreFoundation"
|
||||
fi
|
||||
|
||||
cd git-src
|
||||
make prefix="$PREFIX" \
|
||||
RUNTIME_PREFIX=YesPlease \
|
||||
NO_GETTEXT=YesPlease \
|
||||
NO_TCLTK=YesPlease \
|
||||
NO_PERL=YesPlease \
|
||||
NO_PYTHON=YesPlease \
|
||||
NO_EXPAT=YesPlease \
|
||||
INSTALL_SYMLINKS=1 \
|
||||
CURLDIR="$PREFIX" \
|
||||
CURL_LIBCURL="-L$PREFIX/lib -lcurl -lssl -lcrypto -lz $CRYPTO_DEPS $CURL_EXTRA" \
|
||||
OPENSSL_LIBSSL="-L$PREFIX/lib -lssl" \
|
||||
LIB_4_CRYPTO="-lcrypto $CRYPTO_DEPS" \
|
||||
ZLIB_PATH="$PREFIX" \
|
||||
-j"$NJOBS" \
|
||||
all
|
||||
make prefix="$PREFIX" \
|
||||
RUNTIME_PREFIX=YesPlease \
|
||||
NO_GETTEXT=YesPlease \
|
||||
NO_TCLTK=YesPlease \
|
||||
NO_PERL=YesPlease \
|
||||
NO_PYTHON=YesPlease \
|
||||
NO_EXPAT=YesPlease \
|
||||
INSTALL_SYMLINKS=1 \
|
||||
CURLDIR="$PREFIX" \
|
||||
CURL_LIBCURL="-L$PREFIX/lib -lcurl -lssl -lcrypto -lz $CRYPTO_DEPS $CURL_EXTRA" \
|
||||
OPENSSL_LIBSSL="-L$PREFIX/lib -lssl" \
|
||||
LIB_4_CRYPTO="-lcrypto $CRYPTO_DEPS" \
|
||||
ZLIB_PATH="$PREFIX" \
|
||||
install
|
||||
cd "$DIR"
|
||||
|
||||
# Assemble the package install directory
|
||||
# Only copy real files from libexec to avoid bloating the wheel with
|
||||
# copies of the main git binary (builtin commands are symlinks to git)
|
||||
rm -rf "$INSTALL_DIR"
|
||||
mkdir -p "$INSTALL_DIR/bin" "$INSTALL_DIR/libexec/git-core"
|
||||
|
||||
# Main binary
|
||||
cp "$PREFIX/bin/git" "$INSTALL_DIR/bin/"
|
||||
|
||||
# libexec/git-core: copy real files, resolve non-git symlinks, skip git symlinks
|
||||
cd "$PREFIX/libexec/git-core"
|
||||
for f in *; do
|
||||
if [ -L "$f" ]; then
|
||||
target="$(readlink "$f")"
|
||||
# Skip symlinks to the main git binary (these are builtins)
|
||||
case "$target" in
|
||||
git|../../bin/git) continue ;;
|
||||
esac
|
||||
# Resolve other symlinks (e.g., git-remote-https -> git-remote-http)
|
||||
cp -L "$f" "$INSTALL_DIR/libexec/git-core/$f"
|
||||
elif [ -f "$f" ]; then
|
||||
cp "$f" "$INSTALL_DIR/libexec/git-core/$f"
|
||||
fi
|
||||
done
|
||||
cd "$DIR"
|
||||
|
||||
# Copy git binary into libexec for builtin resolution
|
||||
cp "$PREFIX/bin/git" "$INSTALL_DIR/libexec/git-core/git"
|
||||
|
||||
# Templates
|
||||
cp -r "$PREFIX/share" "$INSTALL_DIR/"
|
||||
|
||||
# Strip binaries
|
||||
strip "$INSTALL_DIR/bin/git" "$INSTALL_DIR/libexec/git-core/git" 2>/dev/null || true
|
||||
find "$INSTALL_DIR/libexec/git-core" -maxdepth 1 -type f -perm /111 ! -name "*.sh" -exec strip {} \; 2>/dev/null || true
|
||||
|
||||
echo "$VERSION" > "$VERSION_FILE"
|
||||
|
||||
echo "Installed git to $INSTALL_DIR"
|
||||
du -sh "$INSTALL_DIR"
|
||||
17
git/git/__init__.py
Normal file
17
git/git/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
DIR = os.path.join(os.path.dirname(__file__), "install")
|
||||
BIN_DIR = os.path.join(DIR, "bin")
|
||||
|
||||
|
||||
def _run():
|
||||
binary = os.path.join(BIN_DIR, "git")
|
||||
os.execvp(binary, [binary] + sys.argv[1:])
|
||||
|
||||
|
||||
def smoketest():
|
||||
import subprocess
|
||||
binary = os.path.join(BIN_DIR, "git")
|
||||
subprocess.run([binary, "--version"], check=True)
|
||||
subprocess.run([binary, "ls-remote", "https://github.com/commaai/openpilot.git", "HEAD"], check=True)
|
||||
18
git/pyproject.toml
Normal file
18
git/pyproject.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=64", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "git"
|
||||
version = "2.47.1"
|
||||
description = "Git distributed version control system"
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[project.scripts]
|
||||
git = "git:_run"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
include = ["git*"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
git = ["install/**/*"]
|
||||
@@ -10,21 +10,18 @@ except ImportError:
|
||||
bdist_wheel = None
|
||||
|
||||
|
||||
class BuildOpenssl(build_py):
|
||||
"""Run build.sh to compile OpenSSL before collecting package data."""
|
||||
class BuildGit(build_py):
|
||||
"""Run build.sh to build git 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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
cmdclass = {"build_py": BuildOpenssl}
|
||||
cmdclass = {"build_py": BuildGit}
|
||||
|
||||
if bdist_wheel is not None:
|
||||
|
||||
124
imgui/build.sh
Executable file
124
imgui/build.sh
Executable file
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$DIR"
|
||||
|
||||
INSTALL_DIR="$DIR/imgui/install"
|
||||
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
|
||||
|
||||
# Dear ImGui (docking branch, version 1.92.7)
|
||||
IMGUI_COMMIT="934c6a5f5ef2355d6df25395d555cb71f790c4e9"
|
||||
# ImPlot
|
||||
IMPLOT_COMMIT="93c801b4bb801c5c11031d880b6af1d1f70bd79d"
|
||||
|
||||
# GLFW 3.4
|
||||
GLFW_COMMIT="7b6aead9fb88b3623e3b3725ebb42670cbe4c579"
|
||||
|
||||
# Clone/update imgui
|
||||
if [ ! -d "imgui-src/.git" ]; then
|
||||
rm -rf imgui-src
|
||||
git clone --depth 1 https://github.com/ocornut/imgui.git imgui-src
|
||||
fi
|
||||
git -C imgui-src fetch --depth 1 origin "$IMGUI_COMMIT"
|
||||
git -C imgui-src checkout --force "$IMGUI_COMMIT"
|
||||
|
||||
# Clone/update implot
|
||||
if [ ! -d "implot-src/.git" ]; then
|
||||
rm -rf implot-src
|
||||
git clone --depth 1 https://github.com/epezent/implot.git implot-src
|
||||
fi
|
||||
git -C implot-src fetch --depth 1 origin "$IMPLOT_COMMIT"
|
||||
git -C implot-src checkout --force "$IMPLOT_COMMIT"
|
||||
|
||||
# Clone/update GLFW
|
||||
if [ ! -d "glfw-src/.git" ]; then
|
||||
rm -rf glfw-src
|
||||
git clone --depth 1 https://github.com/glfw/glfw.git glfw-src
|
||||
fi
|
||||
git -C glfw-src fetch --depth 1 origin "$GLFW_COMMIT"
|
||||
git -C glfw-src checkout --force "$GLFW_COMMIT"
|
||||
|
||||
# Install GLFW build dependencies
|
||||
if [[ "$(uname)" == "Linux" ]]; then
|
||||
if command -v dnf &>/dev/null; then
|
||||
dnf install -y libX11-devel libXcursor-devel libXrandr-devel libXinerama-devel libXi-devel mesa-libGL-devel \
|
||||
wayland-devel wayland-protocols-devel libxkbcommon-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 \
|
||||
libwayland-dev wayland-protocols libxkbcommon-dev
|
||||
else
|
||||
sudo apt-get update && sudo apt-get install -y libxcursor-dev libxi-dev libxinerama-dev libxrandr-dev libgl-dev \
|
||||
libwayland-dev wayland-protocols libxkbcommon-dev
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build GLFW static library
|
||||
cmake -B glfw-src/build -S glfw-src \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DGLFW_BUILD_EXAMPLES=OFF \
|
||||
-DGLFW_BUILD_TESTS=OFF \
|
||||
-DGLFW_BUILD_DOCS=OFF
|
||||
cmake --build glfw-src/build --parallel "$NJOBS"
|
||||
|
||||
# Install headers
|
||||
rm -rf "$INSTALL_DIR"
|
||||
mkdir -p "$INSTALL_DIR/include" "$INSTALL_DIR/lib"
|
||||
|
||||
# imgui headers
|
||||
cp imgui-src/imgui.h imgui-src/imgui_internal.h imgui-src/imconfig.h \
|
||||
imgui-src/imstb_rectpack.h imgui-src/imstb_textedit.h imgui-src/imstb_truetype.h \
|
||||
"$INSTALL_DIR/include/"
|
||||
cp imgui-src/backends/imgui_impl_opengl3.h imgui-src/backends/imgui_impl_opengl3_loader.h \
|
||||
imgui-src/backends/imgui_impl_glfw.h \
|
||||
"$INSTALL_DIR/include/"
|
||||
|
||||
# implot headers
|
||||
cp implot-src/implot.h implot-src/implot_internal.h "$INSTALL_DIR/include/"
|
||||
|
||||
# glfw
|
||||
cp glfw-src/build/src/libglfw3.a "$INSTALL_DIR/lib/"
|
||||
cp -r glfw-src/include/GLFW "$INSTALL_DIR/include/"
|
||||
|
||||
# Build libimgui.a (imgui core + backends + implot)
|
||||
IMGUI_SRCS=(
|
||||
imgui-src/imgui.cpp
|
||||
imgui-src/imgui_draw.cpp
|
||||
imgui-src/imgui_tables.cpp
|
||||
imgui-src/imgui_widgets.cpp
|
||||
imgui-src/imgui_demo.cpp
|
||||
imgui-src/backends/imgui_impl_opengl3.cpp
|
||||
imgui-src/backends/imgui_impl_glfw.cpp
|
||||
implot-src/implot.cpp
|
||||
implot-src/implot_items.cpp
|
||||
)
|
||||
OBJ_DIR="$(mktemp -d)"
|
||||
for src in "${IMGUI_SRCS[@]}"; do
|
||||
obj="$OBJ_DIR/$(basename "${src%.cpp}.o")"
|
||||
c++ -c -O2 -fPIC -I"$INSTALL_DIR/include" "$src" -o "$obj" &
|
||||
done
|
||||
wait
|
||||
ar rcs "$INSTALL_DIR/lib/libimgui.a" "$OBJ_DIR"/*.o
|
||||
rm -rf "$OBJ_DIR"
|
||||
|
||||
# Bundle GLVND dispatchers so Linux users don't need system libGL
|
||||
if [[ "$(uname)" == "Linux" ]]; then
|
||||
MESA_DIR="$INSTALL_DIR/lib/mesa"
|
||||
mkdir -p "$MESA_DIR"
|
||||
ldconfig 2>/dev/null || true
|
||||
for lib in libGL.so.1 libGLX.so.0 libEGL.so.1 libOpenGL.so.0 libGLdispatch.so.0; do
|
||||
src="$(ldconfig -p 2>/dev/null | grep -F "$lib" | 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
|
||||
|
||||
echo "Installed imgui to $INSTALL_DIR"
|
||||
du -sh "$INSTALL_DIR"
|
||||
16
imgui/imgui/__init__.py
Normal file
16
imgui/imgui/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import os
|
||||
import platform as _platform
|
||||
|
||||
DIR = os.path.join(os.path.dirname(__file__), "install")
|
||||
INCLUDE_DIR = os.path.join(DIR, "include")
|
||||
LIB_DIR = os.path.join(DIR, "lib")
|
||||
MESA_DIR = os.path.join(DIR, "lib", "mesa")
|
||||
|
||||
|
||||
def smoketest():
|
||||
assert os.path.isfile(os.path.join(INCLUDE_DIR, "imgui.h")), "imgui.h not found"
|
||||
assert os.path.isfile(os.path.join(LIB_DIR, "libimgui.a")), "libimgui.a not found"
|
||||
assert os.path.isfile(os.path.join(LIB_DIR, "libglfw3.a")), "libglfw3.a not found"
|
||||
assert os.path.isfile(os.path.join(INCLUDE_DIR, "GLFW", "glfw3.h")), "GLFW/glfw3.h not found"
|
||||
if _platform.system() == "Linux":
|
||||
assert os.path.isfile(os.path.join(MESA_DIR, "libGL.so.1")), "libGL.so.1 not found"
|
||||
15
imgui/pyproject.toml
Normal file
15
imgui/pyproject.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=64", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "imgui"
|
||||
version = "1.92.7"
|
||||
description = "Dear ImGui + ImPlot + GLFW 3.4 (static)"
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[tool.setuptools]
|
||||
packages = ["imgui"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
imgui = ["install/**/*"]
|
||||
58
imgui/setup.py
Normal file
58
imgui/setup.py
Normal file
@@ -0,0 +1,58 @@
|
||||
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 BuildImgui(build_py):
|
||||
"""Run build.sh to download imgui sources before collecting package data."""
|
||||
|
||||
def run(self):
|
||||
pkg_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
cmdclass = {"build_py": BuildImgui}
|
||||
|
||||
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()
|
||||
@@ -6,36 +6,26 @@ 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
|
||||
CXX="ccache ${CXX:-c++}"
|
||||
|
||||
if [ ! -d "$DIR/json11-src/.git" ]; then
|
||||
git clone https://github.com/dropbox/json11.git json11-src
|
||||
git clone --depth 1 https://github.com/dropbox/json11.git json11-src
|
||||
fi
|
||||
|
||||
git -C json11-src fetch --force origin
|
||||
git -C json11-src fetch --depth 1 origin "$VERSION"
|
||||
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"
|
||||
mkdir -p "$BUILD_DIR"
|
||||
rm -rf "$INSTALL_DIR"
|
||||
mkdir -p "$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"
|
||||
$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"
|
||||
|
||||
@@ -15,11 +15,8 @@ class BuildJson11(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
@@ -7,18 +7,15 @@ 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
|
||||
# Clone/update source
|
||||
if [ ! -d "libjpeg-turbo-src/.git" ]; then
|
||||
rm -rf libjpeg-turbo-src
|
||||
git clone --depth 1 https://github.com/libjpeg-turbo/libjpeg-turbo.git libjpeg-turbo-src
|
||||
fi
|
||||
git -C libjpeg-turbo-src fetch --depth 1 origin "${VERSION}"
|
||||
git -C libjpeg-turbo-src checkout --force FETCH_HEAD
|
||||
|
||||
# Build
|
||||
PREFIX="$DIR/build/prefix"
|
||||
@@ -50,8 +47,5 @@ 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"
|
||||
|
||||
@@ -15,11 +15,8 @@ class BuildLibjpeg(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
52
libusb/build.sh
Executable file
52
libusb/build.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$DIR"
|
||||
|
||||
VERSION="1.0.29"
|
||||
ARCHIVE="libusb-${VERSION}.tar.bz2"
|
||||
URL="https://github.com/libusb/libusb/releases/download/v${VERSION}/${ARCHIVE}"
|
||||
INSTALL_DIR="$DIR/libusb/install"
|
||||
SRC_DIR="$DIR/libusb-src"
|
||||
VERSION_FILE="$SRC_DIR/.version"
|
||||
|
||||
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
|
||||
export CC="ccache ${CC:-cc}"
|
||||
|
||||
if [ ! -f "$VERSION_FILE" ] || [ "$(cat "$VERSION_FILE")" != "$VERSION" ]; then
|
||||
rm -rf "$SRC_DIR"
|
||||
mkdir -p "$SRC_DIR"
|
||||
curl -fSL "$URL" | tar xj --strip-components=1 -C "$SRC_DIR"
|
||||
echo "$VERSION" > "$VERSION_FILE"
|
||||
fi
|
||||
|
||||
PREFIX="$DIR/build/prefix"
|
||||
rm -rf "$DIR/build"
|
||||
mkdir -p "$DIR/build"
|
||||
|
||||
CONFIGURE_ARGS=(
|
||||
--prefix="$PREFIX"
|
||||
--disable-shared
|
||||
--enable-static
|
||||
)
|
||||
|
||||
if [ "$(uname)" = "Linux" ]; then
|
||||
CONFIGURE_ARGS+=(--disable-udev)
|
||||
fi
|
||||
|
||||
cd "$SRC_DIR"
|
||||
CFLAGS="-O2 -fPIC" ./configure "${CONFIGURE_ARGS[@]}"
|
||||
make -j"$NJOBS"
|
||||
make install
|
||||
cd "$DIR"
|
||||
|
||||
rm -rf "$INSTALL_DIR"
|
||||
mkdir -p "$INSTALL_DIR/lib/pkgconfig" "$INSTALL_DIR/include/libusb-1.0"
|
||||
|
||||
cp "$PREFIX/lib/libusb-1.0.a" "$INSTALL_DIR/lib/"
|
||||
cp "$PREFIX/lib/pkgconfig/libusb-1.0.pc" "$INSTALL_DIR/lib/pkgconfig/"
|
||||
cp "$PREFIX/include/libusb-1.0/libusb.h" "$INSTALL_DIR/include/libusb-1.0/"
|
||||
|
||||
echo "Installed libusb to $INSTALL_DIR"
|
||||
du -sh "$INSTALL_DIR"
|
||||
12
libusb/libusb/__init__.py
Normal file
12
libusb/libusb/__init__.py
Normal file
@@ -0,0 +1,12 @@
|
||||
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")
|
||||
PKGCONFIG_DIR = os.path.join(LIB_DIR, "pkgconfig")
|
||||
|
||||
|
||||
def smoketest():
|
||||
assert os.path.isfile(os.path.join(LIB_DIR, "libusb-1.0.a")), "libusb-1.0.a not found"
|
||||
assert os.path.isfile(os.path.join(INCLUDE_DIR, "libusb-1.0", "libusb.h")), "libusb.h not found"
|
||||
assert os.path.isfile(os.path.join(PKGCONFIG_DIR, "libusb-1.0.pc")), "libusb-1.0.pc not found"
|
||||
@@ -3,13 +3,13 @@ requires = ["setuptools>=64", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "openssl3"
|
||||
version = "3.4.1"
|
||||
description = "OpenSSL cryptography library (static build)"
|
||||
name = "libusb"
|
||||
version = "1.0.29"
|
||||
description = "libusb USB device access library (static build)"
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
include = ["openssl3*"]
|
||||
include = ["libusb*"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
openssl3 = ["install/**/*"]
|
||||
libusb = ["install/**/*"]
|
||||
58
libusb/setup.py
Normal file
58
libusb/setup.py
Normal file
@@ -0,0 +1,58 @@
|
||||
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 BuildLibusb(build_py):
|
||||
"""Run build.sh to compile libusb before collecting package data."""
|
||||
|
||||
def run(self):
|
||||
pkg_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
cmdclass = {"build_py": BuildLibusb}
|
||||
|
||||
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()
|
||||
@@ -6,25 +6,17 @@ 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
|
||||
git clone --depth 1 https://chromium.googlesource.com/libyuv/libyuv libyuv-src
|
||||
fi
|
||||
|
||||
git -C libyuv-src fetch --force origin
|
||||
git -C libyuv-src fetch --depth 1 origin "$VERSION"
|
||||
git -C libyuv-src checkout --force "$VERSION"
|
||||
|
||||
BUILD_DIR="$DIR/build/build"
|
||||
rm -rf "$DIR/build"
|
||||
BUILD_DIR="$DIR/build"
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
cmake -S "$DIR/libyuv-src" -B "$BUILD_DIR" \
|
||||
@@ -47,10 +39,6 @@ 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"
|
||||
|
||||
@@ -15,11 +15,8 @@ class BuildLibyuv(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
25
nanosvg/build.sh
Executable file
25
nanosvg/build.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$DIR"
|
||||
|
||||
COMMIT="5cefd9847949af6df13f65027fd43af5a7513633"
|
||||
INSTALL_DIR="$DIR/nanosvg/install"
|
||||
|
||||
# Clone/update source
|
||||
if [ ! -d "nanosvg-src/.git" ]; then
|
||||
rm -rf nanosvg-src
|
||||
git clone --depth 1 https://github.com/memononen/nanosvg.git nanosvg-src
|
||||
fi
|
||||
git -C nanosvg-src fetch --depth 1 origin "$COMMIT"
|
||||
git -C nanosvg-src checkout --force FETCH_HEAD
|
||||
|
||||
# Copy headers
|
||||
rm -rf "$INSTALL_DIR"
|
||||
mkdir -p "$INSTALL_DIR/include"
|
||||
cp nanosvg-src/src/nanosvg.h "$INSTALL_DIR/include/"
|
||||
cp nanosvg-src/src/nanosvgrast.h "$INSTALL_DIR/include/"
|
||||
|
||||
echo "Installed nanosvg to $INSTALL_DIR"
|
||||
du -sh "$INSTALL_DIR"
|
||||
10
nanosvg/nanosvg/__init__.py
Normal file
10
nanosvg/nanosvg/__init__.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import os
|
||||
|
||||
DIR = os.path.join(os.path.dirname(__file__), "install")
|
||||
INCLUDE_DIR = os.path.join(DIR, "include")
|
||||
LIB_DIR = DIR # header-only; no libraries
|
||||
|
||||
|
||||
def smoketest():
|
||||
assert os.path.isfile(os.path.join(INCLUDE_DIR, "nanosvg.h")), "nanosvg.h not found"
|
||||
assert os.path.isfile(os.path.join(INCLUDE_DIR, "nanosvgrast.h")), "nanosvgrast.h not found"
|
||||
@@ -3,13 +3,13 @@ requires = ["setuptools>=64", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "python3-dev"
|
||||
version = "3.12.8"
|
||||
description = "CPython development headers"
|
||||
name = "nanosvg"
|
||||
version = "0.0.1"
|
||||
description = "NanoSVG: simple SVG parser and rasterizer"
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
include = ["python3_dev*"]
|
||||
include = ["nanosvg*"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
python3_dev = ["install/**/*"]
|
||||
nanosvg = ["install/**/*"]
|
||||
@@ -10,21 +10,18 @@ except ImportError:
|
||||
bdist_wheel = None
|
||||
|
||||
|
||||
class BuildPython3Dev(build_py):
|
||||
"""Run build.sh to download CPython headers before collecting package data."""
|
||||
class BuildNanosvg(build_py):
|
||||
"""Run build.sh to download nanosvg 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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
cmdclass = {"build_py": BuildPython3Dev}
|
||||
cmdclass = {"build_py": BuildNanosvg}
|
||||
|
||||
if bdist_wheel is not None:
|
||||
|
||||
@@ -6,31 +6,25 @@ 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
|
||||
VERSION_FILE="$DIR/ncurses-src/.version"
|
||||
|
||||
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
|
||||
export CC="ccache ${CC:-cc}"
|
||||
|
||||
# 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"
|
||||
# Download tarball (v6.5 tag doesn't exist on the GitHub mirror)
|
||||
if [ ! -f "$VERSION_FILE" ] || [ "$(cat "$VERSION_FILE")" != "$VERSION" ]; then
|
||||
rm -rf ncurses-src
|
||||
mkdir -p ncurses-src
|
||||
curl -fSL "https://ftp.gnu.org/gnu/ncurses/ncurses-${VERSION}.tar.gz" \
|
||||
| tar xz --strip-components=1 -C ncurses-src
|
||||
echo "$VERSION" > "$VERSION_FILE"
|
||||
fi
|
||||
|
||||
# Build
|
||||
PREFIX="$DIR/build/prefix"
|
||||
mkdir -p "$DIR/build"
|
||||
|
||||
cd "ncurses-${VERSION}"
|
||||
cd ncurses-src
|
||||
CFLAGS="-fPIC" ./configure \
|
||||
--prefix="$PREFIX" \
|
||||
--without-shared \
|
||||
@@ -66,8 +60,5 @@ 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"
|
||||
|
||||
@@ -15,11 +15,8 @@ class BuildNcurses(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#!/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"
|
||||
@@ -1,11 +0,0 @@
|
||||
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"
|
||||
@@ -1,19 +1,25 @@
|
||||
[tool.uv.workspace]
|
||||
members = [
|
||||
"acados",
|
||||
"bzip2",
|
||||
"capnproto",
|
||||
"catch2",
|
||||
"cppcheck",
|
||||
"eigen",
|
||||
"ffmpeg",
|
||||
"gcc-arm-none-eabi",
|
||||
"git",
|
||||
"git-lfs",
|
||||
"imgui",
|
||||
"json11",
|
||||
"libusb",
|
||||
"libjpeg",
|
||||
"libyuv",
|
||||
"nanosvg",
|
||||
"ncurses",
|
||||
"openssl3",
|
||||
"python3-dev",
|
||||
"qt5",
|
||||
"raylib",
|
||||
"xvfb",
|
||||
"zeromq",
|
||||
"zstd",
|
||||
]
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#!/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"
|
||||
@@ -1,9 +0,0 @@
|
||||
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"
|
||||
@@ -6,13 +6,8 @@ cd "$DIR"
|
||||
|
||||
INSTALL_DIR="$DIR/raylib/install"
|
||||
|
||||
# Idempotent: skip if already built
|
||||
if [ -f "$INSTALL_DIR/lib/libraylib.a" ]; then
|
||||
echo "raylib already present, skipping build."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
NJOBS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)"
|
||||
CC="ccache ${CC:-cc}"
|
||||
|
||||
# Detect platform: PLATFORM_COMMA for comma devices, PLATFORM_DESKTOP otherwise
|
||||
RAYLIB_PLATFORM="${RAYLIB_PLATFORM:-PLATFORM_DESKTOP}"
|
||||
@@ -33,6 +28,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
|
||||
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
|
||||
@@ -48,19 +52,20 @@ if [[ "$(uname)" == "Linux" ]]; then
|
||||
fi
|
||||
|
||||
# Clone and build raylib C library
|
||||
RAYLIB_COMMIT="aa6ade09ac4bfb2847a356535f2d9f87e49ab089"
|
||||
RAYLIB_COMMIT="d9d7cc1353ec0f73c97e84ddf0973983d1ee25e2"
|
||||
|
||||
if [ ! -d "raylib-src" ]; then
|
||||
git clone -b master --no-tags https://github.com/commaai/raylib.git raylib-src
|
||||
if [ ! -d "raylib-src/.git" ]; then
|
||||
rm -rf raylib-src
|
||||
git clone --depth 1 -b platform-offscreen --no-tags https://github.com/commaai/raylib.git raylib-src
|
||||
fi
|
||||
|
||||
cd raylib-src
|
||||
git fetch origin "$RAYLIB_COMMIT"
|
||||
git fetch --depth 1 origin "$RAYLIB_COMMIT"
|
||||
git reset --hard "$RAYLIB_COMMIT"
|
||||
git clean -xdff .
|
||||
|
||||
cd src
|
||||
make -j"$NJOBS" PLATFORM="$RAYLIB_PLATFORM"
|
||||
make clean
|
||||
make -j"$NJOBS" PLATFORM="$RAYLIB_PLATFORM" CC="${CC:-gcc}"
|
||||
|
||||
cd "$DIR"
|
||||
|
||||
@@ -71,13 +76,46 @@ 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 CC="${CC:-gcc}"
|
||||
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"
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "raylib"
|
||||
version = "5.5.0.3"
|
||||
version = "5.5.0.8"
|
||||
description = "raylib + pyray Python bindings (commaai fork)"
|
||||
requires-python = ">=3.8"
|
||||
dependencies = ["cffi>=1.17.1"]
|
||||
|
||||
@@ -1,26 +1,60 @@
|
||||
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
|
||||
# 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__)
|
||||
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")
|
||||
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
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ def build_ffi():
|
||||
'-framework', 'CoreVideo',
|
||||
]
|
||||
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:
|
||||
print("BUILDING FOR LINUX")
|
||||
extra_link_args = [
|
||||
@@ -104,15 +104,26 @@ def build_ffi():
|
||||
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", "-D_CFFI_NO_LIMITED_API"]
|
||||
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=False,
|
||||
py_limited_api=True,
|
||||
include_dirs=[RAYLIB_INCLUDE_PATH],
|
||||
extra_link_args=extra_link_args,
|
||||
extra_compile_args=extra_compile_args,
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "5.5.0.2"
|
||||
__version__ = "5.5.0.8"
|
||||
@@ -18,11 +18,8 @@ class BuildRaylib(build_py):
|
||||
|
||||
def run(self):
|
||||
pkg_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
marker = os.path.join(pkg_dir, "raylib", "install", "lib", "libraylib.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)
|
||||
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*"))
|
||||
|
||||
86
release.sh
86
release.sh
@@ -29,7 +29,7 @@ for toml in */pyproject.toml; do
|
||||
done
|
||||
shopt -u nullglob
|
||||
|
||||
TOKEN="$(gh auth token 2>/dev/null)" || { echo "set GH_TOKEN to publish shim branch" >&2; exit 1; }
|
||||
TOKEN="$(gh auth token 2>/dev/null)" || { echo "set GH_TOKEN to publish shim branches" >&2; exit 1; }
|
||||
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
python3 - "$TMP_DIR" "$REPO" <<'PY'
|
||||
@@ -55,7 +55,8 @@ for toml in sorted(pathlib.Path(".").glob("*/pyproject.toml")):
|
||||
datadir = patterns[0].split("/", 1)[0] if patterns and patterns[0] else ""
|
||||
scripts = data.get("project", {}).get("scripts", {}) or {}
|
||||
|
||||
pkg_dir = tmp_dir / pkg
|
||||
repo_dir = tmp_dir / pkg
|
||||
pkg_dir = repo_dir / pkg
|
||||
mod_dir = pkg_dir / module
|
||||
mod_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@@ -64,17 +65,37 @@ for toml in sorted(pathlib.Path(".").glob("*/pyproject.toml")):
|
||||
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", [])
|
||||
# copy extra packages (e.g. pyray for raylib, slim casadi for acados)
|
||||
# binaries (.so/.dylib) are fetched from the wheel at install time, so the
|
||||
# shim repo only carries Python sources to keep it small
|
||||
def _ignore_binaries(_dir, names):
|
||||
return [n for n in names if n.endswith((".so", ".dylib", ".a")) or ".so." in n or n == "__pycache__"]
|
||||
|
||||
# `packages` is either a flat list (["acados", "casadi"]) or a dict with
|
||||
# `find.include` patterns (["acados*", "casadi*"]) — handle both
|
||||
pkgs_val = data.get("tool", {}).get("setuptools", {}).get("packages", [])
|
||||
if isinstance(pkgs_val, list):
|
||||
include_patterns = list(pkgs_val)
|
||||
elif isinstance(pkgs_val, dict):
|
||||
include_patterns = pkgs_val.get("find", {}).get("include", [])
|
||||
else:
|
||||
include_patterns = []
|
||||
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
|
||||
dst_extra = pkg_dir / 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.copytree(src_extra, dst_extra, dirs_exist_ok=True, ignore=_ignore_binaries)
|
||||
else:
|
||||
# source not in the workspace (typically built lazily by build.sh and
|
||||
# not cached into the publish job). Drop a placeholder __init__.py so
|
||||
# setuptools.packages.find picks it up; the shim's setup.py overwrites
|
||||
# it from the wheel at install time.
|
||||
dst_extra.mkdir(parents=True, exist_ok=True)
|
||||
(dst_extra / "__init__.py").write_text("")
|
||||
extra_packages.append(pattern)
|
||||
|
||||
shutil.copy2(shim_setup, pkg_dir / "setup.py")
|
||||
|
||||
@@ -100,14 +121,28 @@ for toml in sorted(pathlib.Path(".").glob("*/pyproject.toml")):
|
||||
for name, target in scripts.items():
|
||||
lines.append(f'"{name}" = {json.dumps(target)}')
|
||||
|
||||
find_include = [f"{module}*"] + extra_packages
|
||||
# propagate the workspace's package-data so the shim wheel knows to ship
|
||||
# everything the upstream wheel ships (e.g. acados_template/, casadi/*.so).
|
||||
workspace_pkgdata = data.get("tool", {}).get("setuptools", {}).get("package-data", {})
|
||||
|
||||
# extra_packages may be plain names (["casadi"]) or globs (["casadi*"]).
|
||||
# Normalise to plain package names for both `packages` and `package-data`.
|
||||
extra_pkg_names = [p.rstrip("*").rstrip("/") for p in extra_packages]
|
||||
|
||||
lines += [
|
||||
"",
|
||||
"[tool.setuptools.packages.find]",
|
||||
f"include = {json.dumps(find_include)}",
|
||||
"[tool.setuptools]",
|
||||
f"packages = {json.dumps([module] + extra_pkg_names)}",
|
||||
"",
|
||||
"[tool.setuptools.package-data]",
|
||||
f'{module} = ["{datadir}/**/*"]',
|
||||
]
|
||||
module_data = sorted(set(workspace_pkgdata.get(module, [f"{datadir}/**/*"]) + ["*.so"]))
|
||||
lines.append(f"{module} = {json.dumps(module_data)}")
|
||||
for name in extra_pkg_names:
|
||||
extra_data = workspace_pkgdata.get(name, ["**/*"])
|
||||
lines.append(f"{name} = {json.dumps(list(extra_data))}")
|
||||
|
||||
lines += [
|
||||
"",
|
||||
"[tool.shim]",
|
||||
f'repo_url = "{repo_url}"',
|
||||
@@ -118,14 +153,25 @@ for toml in sorted(pathlib.Path(".").glob("*/pyproject.toml")):
|
||||
(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
|
||||
)
|
||||
shopt -s nullglob
|
||||
for repo_dir in "$TMP_DIR"/*; do
|
||||
[[ -d "$repo_dir" ]] || continue
|
||||
|
||||
pkg="$(basename "$repo_dir")"
|
||||
branch="release-$pkg"
|
||||
|
||||
echo "[$pkg] Publishing shim branch $branch"
|
||||
|
||||
(
|
||||
cd "$repo_dir"
|
||||
git init
|
||||
git checkout -b "$branch"
|
||||
git add "$pkg"
|
||||
git -c user.name="github-actions[bot]" -c user.email="github-actions[bot]@users.noreply.github.com" commit -m "update $pkg shim"
|
||||
git remote add origin "https://x-access-token:${TOKEN}@github.com/${REPO}.git"
|
||||
git push -f origin "$branch"
|
||||
)
|
||||
done
|
||||
shopt -u nullglob
|
||||
|
||||
rm -rf "$TMP_DIR"
|
||||
|
||||
6
setup.sh
6
setup.sh
@@ -15,12 +15,12 @@ run_as_root() {
|
||||
}
|
||||
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
brew install nasm pkg-config
|
||||
brew install nasm pkg-config ccache autoconf automake libtool
|
||||
elif command -v dnf &>/dev/null; then
|
||||
dnf install -y nasm cmake gcc-c++ pkgconfig git perl-IPC-Cmd
|
||||
dnf install -y nasm cmake gcc-c++ pkgconfig git perl-IPC-Cmd ccache autoconf automake libtool
|
||||
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
|
||||
run_as_root apt-get install -y nasm cmake g++ pkg-config curl ccache autoconf automake libtool
|
||||
fi
|
||||
|
||||
if ! command -v uv &>/dev/null; then
|
||||
|
||||
133
xvfb/build.sh
Executable file
133
xvfb/build.sh
Executable file
@@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||
cd "$DIR"
|
||||
|
||||
INSTALL_DIR="$DIR/xvfb/install"
|
||||
|
||||
# macOS: Xvfb is Linux-only. Ship an empty install dir so the wheel still
|
||||
# builds; smoketest() is a no-op on Darwin.
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
rm -rf "$INSTALL_DIR"
|
||||
mkdir -p "$INSTALL_DIR"/{bin,lib,share/X11/xkb}
|
||||
echo "xvfb: macOS not supported, shipping empty install dir"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Linux: bundle the Xvfb binary, xkbcomp, xkb keymap data, and the closure
|
||||
# of shared libraries it needs (minus libc/libpthread/etc which the host
|
||||
# always provides). For CI/manylinux we pull from AlmaLinux 8 so the wheel
|
||||
# works on any glibc >= 2.28 distro; on a Debian/Ubuntu dev host we accept
|
||||
# whatever the system has (the local wheel just won't be as portable).
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
dnf install -y -q xorg-x11-server-Xvfb xorg-x11-xkb-utils xkeyboard-config >/dev/null
|
||||
elif command -v apt-get >/dev/null 2>&1; then
|
||||
if [[ "$(id -u)" -eq 0 ]]; then SUDO=""
|
||||
elif command -v sudo >/dev/null 2>&1; then SUDO=sudo
|
||||
else echo "xvfb: need sudo or root to apt-get install" >&2; exit 1; fi
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
$SUDO apt-get update -qq
|
||||
$SUDO apt-get install -y -qq --no-install-recommends \
|
||||
xvfb x11-xkb-utils xkb-data patchelf
|
||||
else
|
||||
echo "xvfb: need dnf or apt-get to fetch upstream Xvfb" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v patchelf >/dev/null 2>&1; then
|
||||
echo "xvfb: patchelf is required but not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf "$INSTALL_DIR"
|
||||
mkdir -p "$INSTALL_DIR"/{bin,lib,share/X11/xkb}
|
||||
|
||||
# Xvfb may live in /usr/bin (RPM/Debian) — just locate it.
|
||||
XVFB_SRC="$(command -v Xvfb || true)"
|
||||
XKBCOMP_SRC="$(command -v xkbcomp || true)"
|
||||
if [[ -z "$XVFB_SRC" || -z "$XKBCOMP_SRC" ]]; then
|
||||
echo "xvfb: Xvfb or xkbcomp not found after install" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp "$XVFB_SRC" "$INSTALL_DIR/bin/Xvfb"
|
||||
cp "$XKBCOMP_SRC" "$INSTALL_DIR/bin/xkbcomp"
|
||||
chmod u+w "$INSTALL_DIR/bin/Xvfb" "$INSTALL_DIR/bin/xkbcomp"
|
||||
cp -a /usr/share/X11/xkb/. "$INSTALL_DIR/share/X11/xkb/"
|
||||
|
||||
# Two binary patches to make Xvfb relocatable:
|
||||
#
|
||||
# 1. "/usr/bin" -> "" (null bytes)
|
||||
# Xvfb's compile-time XkbBinDirectory points at /usr/bin and is used to
|
||||
# build an absolute path to xkbcomp. Blanking it makes the spawned
|
||||
# command just "xkbcomp", which popen() then resolves via PATH. Our
|
||||
# Python wrapper prepends the bundled bin/ to PATH.
|
||||
#
|
||||
# 2. "-R%s" -> "-I%s" (in the xkbcomp argv format string)
|
||||
# Xvfb passes its XkbBaseDirectory to xkbcomp via -R, expecting xkbcomp
|
||||
# to chdir there *and* add "." to the include path. xkbcomp 1.4.x only
|
||||
# chdirs — the include-path side was added later. Switching to -I makes
|
||||
# 1.4.2 actually search the path we hand it via -xkbdir.
|
||||
python3 - "$INSTALL_DIR/bin/Xvfb" <<'PY'
|
||||
import sys
|
||||
path = sys.argv[1]
|
||||
with open(path, "r+b") as f:
|
||||
data = bytearray(f.read())
|
||||
|
||||
def replace_unique(needle: bytes, replacement: bytes):
|
||||
assert len(needle) == len(replacement)
|
||||
idx = data.find(needle)
|
||||
if idx < 0:
|
||||
sys.exit(f"could not find {needle!r} in Xvfb binary")
|
||||
if data.find(needle, idx + 1) >= 0:
|
||||
sys.exit(f"multiple {needle!r} matches; refusing to patch")
|
||||
data[idx:idx + len(needle)] = replacement
|
||||
|
||||
replace_unique(b"/usr/bin\x00", b"\x00" * 9)
|
||||
replace_unique(b'"-R%s"\x00', b'"-I%s"\x00')
|
||||
|
||||
with open(path, "wb") as f:
|
||||
f.write(data)
|
||||
PY
|
||||
|
||||
# bundle the shared library closure. Recursively walk ldd output to catch
|
||||
# libs-of-libs (e.g. libXfont2 -> libfontenc -> libbz2). Skip core glibc
|
||||
# pieces; everything else gets copied alongside the binary.
|
||||
declare -A SEEN
|
||||
collect_libs() {
|
||||
local target="$1"
|
||||
while IFS= read -r line; do
|
||||
local lib
|
||||
lib=$(echo "$line" | awk '{print $3}')
|
||||
[[ -z "$lib" || "$lib" == "not" ]] && continue
|
||||
[[ ! -e "$lib" ]] && continue
|
||||
local base
|
||||
base=$(basename "$lib")
|
||||
case "$base" in
|
||||
libc.so.*|libpthread.so.*|libm.so.*|librt.so.*|libdl.so.*|libgcc_s.so.*|libresolv.so.*|libutil.so.*|ld-linux-*.so.*|linux-vdso.so.*|linux-gate.so.*)
|
||||
continue ;;
|
||||
esac
|
||||
[[ -n "${SEEN[$base]:-}" ]] && continue
|
||||
SEEN[$base]=1
|
||||
cp -L "$lib" "$INSTALL_DIR/lib/$base"
|
||||
chmod u+w "$INSTALL_DIR/lib/$base"
|
||||
collect_libs "$INSTALL_DIR/lib/$base"
|
||||
done < <(ldd "$target" 2>/dev/null || true)
|
||||
}
|
||||
collect_libs "$INSTALL_DIR/bin/Xvfb"
|
||||
collect_libs "$INSTALL_DIR/bin/xkbcomp"
|
||||
|
||||
# point the binaries (and the bundled libs) at our private lib dir so they
|
||||
# don't accidentally resolve against an incompatible host copy.
|
||||
patchelf --set-rpath '$ORIGIN/../lib' "$INSTALL_DIR/bin/Xvfb"
|
||||
patchelf --set-rpath '$ORIGIN/../lib' "$INSTALL_DIR/bin/xkbcomp"
|
||||
for so in "$INSTALL_DIR"/lib/*.so*; do
|
||||
patchelf --set-rpath '$ORIGIN' "$so" 2>/dev/null || true
|
||||
done
|
||||
|
||||
strip --strip-unneeded "$INSTALL_DIR/bin/Xvfb" "$INSTALL_DIR/bin/xkbcomp" 2>/dev/null || true
|
||||
find "$INSTALL_DIR/lib" -name '*.so*' -exec strip --strip-unneeded {} + 2>/dev/null || true
|
||||
|
||||
echo "Installed xvfb to $INSTALL_DIR"
|
||||
du -sh "$INSTALL_DIR"
|
||||
18
xvfb/pyproject.toml
Normal file
18
xvfb/pyproject.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=64", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "xvfb"
|
||||
version = "1.20.11"
|
||||
description = "Xvfb (X virtual framebuffer) headless X server"
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[project.scripts]
|
||||
Xvfb = "xvfb:_run_xvfb"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
include = ["xvfb*"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
xvfb = ["install/**/*"]
|
||||
58
xvfb/setup.py
Normal file
58
xvfb/setup.py
Normal file
@@ -0,0 +1,58 @@
|
||||
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 BuildXvfb(build_py):
|
||||
"""Run build.sh to fetch and bundle Xvfb before collecting package data."""
|
||||
|
||||
def run(self):
|
||||
pkg_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
cmdclass = {"build_py": BuildXvfb}
|
||||
|
||||
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()
|
||||
39
xvfb/xvfb/__init__.py
Normal file
39
xvfb/xvfb/__init__.py
Normal file
@@ -0,0 +1,39 @@
|
||||
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")
|
||||
XKB_DIR = os.path.join(DIR, "share", "X11", "xkb")
|
||||
|
||||
XVFB_BIN = os.path.join(BIN_DIR, "Xvfb")
|
||||
XKBCOMP_BIN = os.path.join(BIN_DIR, "xkbcomp")
|
||||
|
||||
|
||||
def _run_xvfb():
|
||||
# The bundled Xvfb has its compile-time XkbBinDirectory blanked out so it
|
||||
# invokes xkbcomp via PATH lookup; prepend our bin dir so the bundled
|
||||
# xkbcomp wins. -xkbdir points the server at the bundled keymap data.
|
||||
env = os.environ.copy()
|
||||
env["PATH"] = BIN_DIR + os.pathsep + env.get("PATH", "")
|
||||
args = sys.argv[1:]
|
||||
if not any(a == "-xkbdir" for a in args):
|
||||
args = ["-xkbdir", XKB_DIR] + args
|
||||
os.execvpe(XVFB_BIN, [XVFB_BIN] + args, env)
|
||||
|
||||
|
||||
def smoketest():
|
||||
if sys.platform == "darwin":
|
||||
return
|
||||
assert os.path.isfile(XVFB_BIN), f"Xvfb not found at {XVFB_BIN}"
|
||||
assert os.path.isfile(XKBCOMP_BIN), f"xkbcomp not found at {XKBCOMP_BIN}"
|
||||
assert os.path.isdir(XKB_DIR), f"xkb data not found at {XKB_DIR}"
|
||||
|
||||
import subprocess
|
||||
# Xvfb prints usage to stderr and exits non-zero on `-help`; the banner
|
||||
# mentions Xvfb-specific flags like -screen and -fbdir. If those appear,
|
||||
# the binary loaded its bundled libs and ran far enough to print help.
|
||||
result = subprocess.run([XVFB_BIN, "-help"], capture_output=True, text=True)
|
||||
output = result.stderr + result.stdout
|
||||
assert "-screen scrn WxHxD" in output, \
|
||||
f"Xvfb -help did not produce expected output: {output}"
|
||||
@@ -7,18 +7,15 @@ 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
|
||||
# Clone/update source
|
||||
if [ ! -d "libzmq-src/.git" ]; then
|
||||
rm -rf libzmq-src
|
||||
git clone --depth 1 https://github.com/zeromq/libzmq.git libzmq-src
|
||||
fi
|
||||
git -C libzmq-src fetch --depth 1 origin "v${VERSION}"
|
||||
git -C libzmq-src checkout --force FETCH_HEAD
|
||||
|
||||
# Build
|
||||
PREFIX="$DIR/build/prefix"
|
||||
@@ -54,8 +51,5 @@ cp "$PREFIX/lib/libzmq.a" "$INSTALL_DIR/lib/"
|
||||
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,11 +15,8 @@ class BuildZeromq(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
@@ -7,18 +7,15 @@ 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
|
||||
# Clone/update source
|
||||
if [ ! -d "zstd-src/.git" ]; then
|
||||
rm -rf zstd-src
|
||||
git clone --depth 1 https://github.com/facebook/zstd.git zstd-src
|
||||
fi
|
||||
git -C zstd-src fetch --depth 1 origin "v${VERSION}"
|
||||
git -C zstd-src checkout --force FETCH_HEAD
|
||||
|
||||
# Build
|
||||
PREFIX="$DIR/build/prefix"
|
||||
@@ -52,8 +49,5 @@ 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,11 +15,8 @@ class BuildZstd(build_py):
|
||||
|
||||
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)
|
||||
build_script = os.path.join(pkg_dir, "build.sh")
|
||||
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||
|
||||
super().run()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user