feat: reduce build size — replace Pillow with cv2, refactor build scripts
All checks were successful
Build Release / create-release (push) Successful in 1s
Build Release / build-docker (push) Successful in 42s
Lint & Test / test (push) Successful in 2m50s
Build Release / build-windows (push) Successful in 3m27s
Build Release / build-linux (push) Successful in 1m59s
All checks were successful
Build Release / create-release (push) Successful in 1s
Build Release / build-docker (push) Successful in 42s
Lint & Test / test (push) Successful in 2m50s
Build Release / build-windows (push) Successful in 3m27s
Build Release / build-linux (push) Successful in 1m59s
- Create utils/image_codec.py with cv2-based image helpers - Replace PIL usage across all routes, filters, and engines with cv2 - Move Pillow from core deps to [tray] optional in pyproject.toml - Extract shared build logic into build-common.sh (detect_version, cleanup, etc.) - Strip unused NumPy/PIL/zeroconf/debug files in build scripts
This commit is contained in:
@@ -22,27 +22,13 @@ PYTHON_DIR="$DIST_DIR/python"
|
||||
APP_DIR="$DIST_DIR/app"
|
||||
PYTHON_VERSION="${PYTHON_VERSION:-3.11.9}"
|
||||
|
||||
source "$SCRIPT_DIR/build-common.sh"
|
||||
|
||||
# ── Version detection ────────────────────────────────────────
|
||||
|
||||
VERSION="${1:-}"
|
||||
|
||||
if [ -z "$VERSION" ]; then
|
||||
VERSION=$(git describe --tags --exact-match 2>/dev/null || true)
|
||||
fi
|
||||
if [ -z "$VERSION" ]; then
|
||||
VERSION="${GITEA_REF_NAME:-${GITHUB_REF_NAME:-}}"
|
||||
fi
|
||||
if [ -z "$VERSION" ]; then
|
||||
VERSION=$(grep -oP '^version\s*=\s*"\K[^"]+' "$SERVER_DIR/pyproject.toml" 2>/dev/null || echo "0.0.0")
|
||||
fi
|
||||
|
||||
VERSION_CLEAN="${VERSION#v}"
|
||||
detect_version "${1:-}"
|
||||
ZIP_NAME="LedGrab-v${VERSION_CLEAN}-win-x64.zip"
|
||||
|
||||
# Stamp the resolved version into pyproject.toml so that
|
||||
# importlib.metadata reads the correct value at runtime.
|
||||
sed -i "s/^version = .*/version = \"${VERSION_CLEAN}\"/" "$SERVER_DIR/pyproject.toml"
|
||||
|
||||
echo "=== Cross-building LedGrab v${VERSION_CLEAN} (Windows from Linux) ==="
|
||||
echo " Embedded Python: $PYTHON_VERSION"
|
||||
echo " Output: build/$ZIP_NAME"
|
||||
@@ -50,11 +36,8 @@ echo ""
|
||||
|
||||
# ── Clean ────────────────────────────────────────────────────
|
||||
|
||||
if [ -d "$DIST_DIR" ]; then
|
||||
echo "[1/9] Cleaning previous build..."
|
||||
rm -rf "$DIST_DIR"
|
||||
fi
|
||||
mkdir -p "$DIST_DIR"
|
||||
echo "[1/9] Cleaning..."
|
||||
clean_dist
|
||||
|
||||
# ── Download Windows embedded Python ─────────────────────────
|
||||
|
||||
@@ -195,15 +178,11 @@ WHEEL_DIR="$BUILD_DIR/win-wheels"
|
||||
mkdir -p "$WHEEL_DIR"
|
||||
|
||||
# Core dependencies (cross-platform, should have win_amd64 wheels)
|
||||
# We parse pyproject.toml deps and download win_amd64 wheels.
|
||||
# For packages that are pure Python, --only-binary will fail,
|
||||
# so we fall back to allowing source for those.
|
||||
DEPS=(
|
||||
"fastapi>=0.115.0"
|
||||
"uvicorn[standard]>=0.32.0"
|
||||
"httpx>=0.27.2"
|
||||
"mss>=9.0.2"
|
||||
"Pillow>=10.4.0"
|
||||
"numpy>=2.1.3"
|
||||
"pydantic>=2.9.2"
|
||||
"pydantic-settings>=2.6.0"
|
||||
@@ -220,7 +199,6 @@ DEPS=(
|
||||
"sounddevice>=0.5"
|
||||
"aiomqtt>=2.0.0"
|
||||
"openrgb-python>=0.2.15"
|
||||
# camera extra
|
||||
"opencv-python-headless>=4.8.0"
|
||||
)
|
||||
|
||||
@@ -232,8 +210,9 @@ WIN_DEPS=(
|
||||
"winrt-Windows.Foundation>=3.0.0"
|
||||
"winrt-Windows.Foundation.Collections>=3.0.0"
|
||||
"winrt-Windows.ApplicationModel>=3.0.0"
|
||||
# System tray
|
||||
# System tray (Pillow needed by pystray for tray icon)
|
||||
"pystray>=0.19.0"
|
||||
"Pillow>=10.4.0"
|
||||
)
|
||||
|
||||
# Download cross-platform deps (prefer binary, allow source for pure Python)
|
||||
@@ -286,73 +265,26 @@ for sdist in "$WHEEL_DIR"/*.tar.gz; do
|
||||
done
|
||||
|
||||
# ── Reduce package size ────────────────────────────────────────
|
||||
echo " Cleaning up to reduce size..."
|
||||
|
||||
# Remove caches, tests, docs, type stubs
|
||||
find "$SITE_PACKAGES" -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
||||
find "$SITE_PACKAGES" -type d -name tests -exec rm -rf {} + 2>/dev/null || true
|
||||
find "$SITE_PACKAGES" -type d -name test -exec rm -rf {} + 2>/dev/null || true
|
||||
find "$SITE_PACKAGES" -type d -name "*.dist-info" -exec rm -rf {} + 2>/dev/null || true
|
||||
find "$SITE_PACKAGES" -name "*.pyi" -delete 2>/dev/null || true
|
||||
cleanup_site_packages "$SITE_PACKAGES" "pyd" "dll"
|
||||
|
||||
# Remove pip and setuptools (not needed at runtime)
|
||||
rm -rf "$SITE_PACKAGES"/pip "$SITE_PACKAGES"/pip-* 2>/dev/null || true
|
||||
rm -rf "$SITE_PACKAGES"/setuptools "$SITE_PACKAGES"/setuptools-* "$SITE_PACKAGES"/pkg_resources 2>/dev/null || true
|
||||
rm -rf "$SITE_PACKAGES"/_distutils_hack 2>/dev/null || true
|
||||
|
||||
# Remove pythonwin GUI IDE and help file (ships with pywin32 but not needed)
|
||||
# Windows-specific cleanup
|
||||
rm -rf "$SITE_PACKAGES"/pythonwin 2>/dev/null || true
|
||||
rm -f "$SITE_PACKAGES"/PyWin32.chm 2>/dev/null || true
|
||||
|
||||
# OpenCV: remove ffmpeg DLL (28MB, only for video file I/O, not camera),
|
||||
# Haar cascades (2.6MB), and misc dev files
|
||||
CV2_DIR="$SITE_PACKAGES/cv2"
|
||||
if [ -d "$CV2_DIR" ]; then
|
||||
rm -f "$CV2_DIR"/opencv_videoio_ffmpeg*.dll 2>/dev/null || true
|
||||
rm -rf "$CV2_DIR/data" "$CV2_DIR/gapi" "$CV2_DIR/misc" "$CV2_DIR/utils" 2>/dev/null || true
|
||||
rm -rf "$CV2_DIR/typing_stubs" "$CV2_DIR/typing" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# numpy: remove tests, f2py, typing stubs
|
||||
rm -rf "$SITE_PACKAGES/numpy/tests" "$SITE_PACKAGES/numpy/*/tests" 2>/dev/null || true
|
||||
rm -rf "$SITE_PACKAGES/numpy/f2py" 2>/dev/null || true
|
||||
rm -rf "$SITE_PACKAGES/numpy/typing" 2>/dev/null || true
|
||||
rm -rf "$SITE_PACKAGES/numpy/_pyinstaller" 2>/dev/null || true
|
||||
|
||||
# Pillow: remove unused image plugins' test data
|
||||
rm -rf "$SITE_PACKAGES/PIL/tests" 2>/dev/null || true
|
||||
|
||||
# winrt: remove type stubs
|
||||
find "$SITE_PACKAGES/winrt" -name "*.pyi" -delete 2>/dev/null || true
|
||||
|
||||
# Remove wled_controller if it got installed
|
||||
rm -rf "$SITE_PACKAGES"/wled_controller* "$SITE_PACKAGES"/wled*.dist-info 2>/dev/null || true
|
||||
|
||||
CLEANED_SIZE=$(du -sh "$SITE_PACKAGES" | cut -f1)
|
||||
echo " Site-packages after cleanup: $CLEANED_SIZE"
|
||||
|
||||
WHEEL_COUNT=$(ls "$WHEEL_DIR"/*.whl 2>/dev/null | wc -l)
|
||||
echo " Installed $WHEEL_COUNT packages"
|
||||
|
||||
# ── Build frontend ───────────────────────────────────────────
|
||||
|
||||
echo "[7/9] Building frontend bundle..."
|
||||
(cd "$SERVER_DIR" && npm ci --loglevel error && npm run build) 2>&1 | {
|
||||
grep -v 'RemoteException' || true
|
||||
}
|
||||
echo "[7/9] Building frontend..."
|
||||
build_frontend
|
||||
|
||||
# ── Copy application files ───────────────────────────────────
|
||||
|
||||
echo "[8/9] Copying application files..."
|
||||
mkdir -p "$APP_DIR"
|
||||
|
||||
cp -r "$SERVER_DIR/src" "$APP_DIR/src"
|
||||
cp -r "$SERVER_DIR/config" "$APP_DIR/config"
|
||||
mkdir -p "$DIST_DIR/data" "$DIST_DIR/logs"
|
||||
|
||||
# Clean up source maps and __pycache__
|
||||
find "$APP_DIR" -name "*.map" -delete 2>/dev/null || true
|
||||
find "$APP_DIR" -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
|
||||
copy_app_files
|
||||
|
||||
# Pre-compile Python bytecode for faster startup
|
||||
echo " Pre-compiling Python bytecode..."
|
||||
|
||||
Reference in New Issue
Block a user