#!/usr/bin/env bash # integrate-redbear.sh — Prepare Red Bear OS custom work for standard builds. # # Usage: # ./local/scripts/integrate-redbear.sh # REDBEAR_TAG=build/x86_64-unknown-redox/redbear.tag ./local/scripts/integrate-redbear.sh # # This script is idempotent and safe to run repeatedly. It ensures the Red Bear OS overlay # is wired into the main build tree, stages branding assets and firmware into local # recipe sources, and updates a tag file consumed by the build system. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" REDBEAR_TAG="${REDBEAR_TAG:-build/redbear.tag}" if [ -t 1 ]; then GREEN='\033[1;32m' YELLOW='\033[1;33m' CYAN='\033[1;36m' RESET='\033[0m' else GREEN='' YELLOW='' CYAN='' RESET='' fi cd "$PROJECT_ROOT" status() { echo -e "${GREEN}✅${RESET} $1" } warn() { echo -e "${YELLOW}⚠️${RESET} $1" } section() { echo -e "${CYAN}==>${RESET} $1" } require_repo_relative_path() { local path="$1" case "$path" in /*|../*|*/../*|..) warn "Refusing unsafe path outside repo: $path" return 1 ;; esac } require_real_parent_dirs() { local path="$1" local parent="$(dirname "$path")" require_repo_relative_path "$path" while [ "$parent" != "." ] && [ "$parent" != "/" ]; do if [ -L "$parent" ]; then warn "Refusing path with symlink parent: $path" return 1 fi parent="$(dirname "$parent")" done } symlink() { local target="$1" local link="$2" local current="" require_real_parent_dirs "$link" mkdir -p "$(dirname "$link")" if [ -L "$link" ]; then current="$(readlink "$link")" if [ "$current" = "$target" ]; then return 0 fi fi if [ -d "$link" ] && [ ! -L "$link" ]; then warn "Refusing to replace directory $link" return 1 fi if [ -e "$link" ] || [ -L "$link" ]; then rm -f "$link" ln -s "$target" "$link" status "Refreshed $link -> $target" else ln -s "$target" "$link" status "Linked $link -> $target" fi } stage_file() { local source_path="$1" local dest_path="$2" local label="$3" if [ ! -f "$source_path" ]; then warn "$label missing at ${source_path#$PROJECT_ROOT/}; skipping" return 0 fi require_real_parent_dirs "$dest_path" if [ -L "$dest_path" ]; then warn "$label destination is a symlink at ${dest_path#$PROJECT_ROOT/}; refusing to overwrite" return 1 fi mkdir -p "$(dirname "$dest_path")" if [ -f "$dest_path" ] && cmp -s "$source_path" "$dest_path"; then status "$label already staged" return 0 fi cp "$source_path" "$dest_path" status "Staged $label" } echo "========================================" echo " Red Bear OS Pre-Build Integration" echo "========================================" echo "Root: ${PROJECT_ROOT##*/}" echo "Tag: $REDBEAR_TAG" echo "" section "Ensuring custom recipe symlinks..." symlink "../../local/recipes/branding/redbear-release" "recipes/branding/redbear-release" symlink "../../local/recipes/drivers/linux-kpi" "recipes/drivers/linux-kpi" symlink "../../local/recipes/drivers/redbear-btusb" "recipes/drivers/redbear-btusb" symlink "../../local/recipes/drivers/redbear-iwlwifi" "recipes/drivers/redbear-iwlwifi" symlink "../../local/recipes/drivers/redox-driver-sys" "recipes/drivers/redox-driver-sys" symlink "../../local/recipes/gpu/amdgpu" "recipes/gpu/amdgpu" symlink "../../local/recipes/gpu/redox-drm" "recipes/gpu/redox-drm" symlink "../../local/recipes/libs/libqrencode" "recipes/libs/libqrencode" symlink "../../local/recipes/system/evdevd" "recipes/system/evdevd" symlink "../../local/recipes/system/redbear-firmware" "recipes/system/redbear-firmware" symlink "../../local/recipes/system/firmware-loader" "recipes/system/firmware-loader" symlink "../../local/recipes/system/iommu" "recipes/system/iommu" symlink "../../local/recipes/system/redbear-btctl" "recipes/system/redbear-btctl" symlink "../../local/recipes/system/redbear-info" "recipes/system/redbear-info" symlink "../../local/recipes/system/redbear-hwutils" "recipes/system/redbear-hwutils" symlink "../../local/recipes/system/redbear-netstat" "recipes/system/redbear-netstat" symlink "../../local/recipes/system/redbear-netctl" "recipes/system/redbear-netctl" symlink "../../local/recipes/system/redbear-netctl-console" "recipes/system/redbear-netctl-console" symlink "../../local/recipes/system/redbear-wifictl" "recipes/system/redbear-wifictl" symlink "../../local/recipes/system/redbear-traceroute" "recipes/system/redbear-traceroute" symlink "../../local/recipes/system/redbear-mtr" "recipes/system/redbear-mtr" symlink "../../local/recipes/system/redbear-nmap" "recipes/system/redbear-nmap" symlink "../../local/recipes/system/redbear-meta" "recipes/system/redbear-meta" symlink "../../local/recipes/system/udev-shim" "recipes/system/udev-shim" symlink "../../local/recipes/core/ext4d" "recipes/core/ext4d" symlink "../../local/recipes/tui/mc" "recipes/tui/mc" symlink "../../local/recipes/system/cub" "recipes/system/cub" symlink "../../../local/recipes/wayland/qt6-wayland-smoke" "recipes/wip/wayland/qt6-wayland-smoke" # KDE / Phase 6 recipes mkdir -p recipes/kde symlink "../../local/recipes/kde/plasma-desktop" "recipes/kde/plasma-desktop" symlink "../../local/recipes/kde/plasma-workspace" "recipes/kde/plasma-workspace" symlink "../../local/recipes/kde/plasma-framework" "recipes/kde/plasma-framework" symlink "../../local/recipes/kde/plasma-wayland-protocols" "recipes/kde/plasma-wayland-protocols" symlink "../../local/recipes/kde/kwin" "recipes/kde/kwin" symlink "../../local/recipes/kde/kirigami" "recipes/kde/kirigami" symlink "../../local/recipes/kde/kirigami" "recipes/kde/kf6-kirigami" symlink "../../local/recipes/kde/kdecoration" "recipes/kde/kdecoration" symlink "../../local/recipes/kde/kf6-extra-cmake-modules" "recipes/kde/kf6-extra-cmake-modules" symlink "../../local/recipes/kde/kf6-kcoreaddons" "recipes/kde/kf6-kcoreaddons" symlink "../../local/recipes/kde/kf6-kwidgetsaddons" "recipes/kde/kf6-kwidgetsaddons" symlink "../../local/recipes/kde/kf6-kconfig" "recipes/kde/kf6-kconfig" symlink "../../local/recipes/kde/kf6-ki18n" "recipes/kde/kf6-ki18n" symlink "../../local/recipes/kde/kf6-kcodecs" "recipes/kde/kf6-kcodecs" symlink "../../local/recipes/kde/kf6-kguiaddons" "recipes/kde/kf6-kguiaddons" symlink "../../local/recipes/kde/kf6-kcolorscheme" "recipes/kde/kf6-kcolorscheme" symlink "../../local/recipes/kde/kf6-kauth" "recipes/kde/kf6-kauth" symlink "../../local/recipes/kde/kf6-kitemmodels" "recipes/kde/kf6-kitemmodels" symlink "../../local/recipes/kde/kf6-kitemviews" "recipes/kde/kf6-kitemviews" symlink "../../local/recipes/kde/kf6-attica" "recipes/kde/kf6-attica" symlink "../../local/recipes/kde/kf6-karchive" "recipes/kde/kf6-karchive" symlink "../../local/recipes/kde/kf6-kwindowsystem" "recipes/kde/kf6-kwindowsystem" symlink "../../local/recipes/kde/kf6-knotifications" "recipes/kde/kf6-knotifications" symlink "../../local/recipes/kde/kf6-kjobwidgets" "recipes/kde/kf6-kjobwidgets" symlink "../../local/recipes/kde/kf6-kconfigwidgets" "recipes/kde/kf6-kconfigwidgets" symlink "../../local/recipes/kde/kf6-kcrash" "recipes/kde/kf6-kcrash" symlink "../../local/recipes/kde/kf6-kdbusaddons" "recipes/kde/kf6-kdbusaddons" symlink "../../local/recipes/kde/kf6-kglobalaccel" "recipes/kde/kf6-kglobalaccel" symlink "../../local/recipes/kde/kf6-kservice" "recipes/kde/kf6-kservice" symlink "../../local/recipes/kde/kf6-kpackage" "recipes/kde/kf6-kpackage" symlink "../../local/recipes/kde/kf6-kiconthemes" "recipes/kde/kf6-kiconthemes" symlink "../../local/recipes/kde/kf6-kxmlgui" "recipes/kde/kf6-kxmlgui" symlink "../../local/recipes/kde/kf6-ktextwidgets" "recipes/kde/kf6-ktextwidgets" symlink "../../local/recipes/kde/kf6-solid" "recipes/kde/kf6-solid" symlink "../../local/recipes/kde/kf6-sonnet" "recipes/kde/kf6-sonnet" symlink "../../local/recipes/kde/kf6-kio" "recipes/kde/kf6-kio" symlink "../../local/recipes/kde/kf6-kbookmarks" "recipes/kde/kf6-kbookmarks" symlink "../../local/recipes/kde/kf6-kcompletion" "recipes/kde/kf6-kcompletion" symlink "../../local/recipes/kde/kf6-kdeclarative" "recipes/kde/kf6-kdeclarative" symlink "../../local/recipes/kde/kf6-kcmutils" "recipes/kde/kf6-kcmutils" symlink "../../local/recipes/kde/kf6-kidletime" "recipes/kde/kf6-kidletime" symlink "../../local/recipes/kde/kf6-kwayland" "recipes/kde/kf6-kwayland" symlink "../../local/recipes/kde/kf6-knewstuff" "recipes/kde/kf6-knewstuff" symlink "../../local/recipes/kde/kf6-kwallet" "recipes/kde/kf6-kwallet" symlink "../../local/recipes/kde/kf6-prison" "recipes/kde/kf6-prison" symlink "../../local/recipes/kde/breeze" "recipes/kde/breeze" symlink "../../local/recipes/kde/kde-cli-tools" "recipes/kde/kde-cli-tools" symlink "../../local/recipes/kde/kdecoration" "recipes/kde/kdecoration" symlink "../../local/recipes/kde/kirigami" "recipes/kde/kirigami" symlink "../../local/recipes/kde/kwin" "recipes/kde/kwin" symlink "../../local/recipes/kde/plasma-desktop" "recipes/kde/plasma-desktop" symlink "../../local/recipes/kde/plasma-framework" "recipes/kde/plasma-framework" symlink "../../local/recipes/kde/plasma-workspace" "recipes/kde/plasma-workspace" symlink "../../local/recipes/kde/plasma-wayland-protocols" "recipes/kde/plasma-wayland-protocols" symlink "../../local/recipes/kde/kglobalacceld" "recipes/kde/kglobalacceld" symlink "../../local/recipes/wayland/qt6-wayland-smoke" "recipes/wayland/qt6-wayland-smoke" symlink "../../local/recipes/wayland/seatd-redox" "recipes/wayland/seatd-redox" symlink "../../local/recipes/wayland/smallvil" "recipes/wayland/smallvil" symlink "../../local/recipes/wayland/redbear-compositor" "recipes/wayland/redbear-compositor" symlink "../../local/recipes/tests/redox-drm-prime-test" "recipes/tests/redox-drm-prime-test" symlink "../../local/recipes/system/redbear-passwd" "recipes/system/redbear-passwd" symlink "../../local/recipes/gpu/redox-drm" "recipes/gpu/redox-drm" symlink "../../local/recipes/gpu/amdgpu" "recipes/gpu/amdgpu" status "Custom recipe symlinks ready" echo "" section "Ensuring recipe patch symlinks..." # Auto-discover patches from local/patches// and create/refresh # symlinks in the corresponding recipe directories. This replaces the # previous hardcoded-per-patch approach which went stale whenever patches # were reorganized (e.g. moved to absorbed/ subdirectories). declare -A PATCH_COMPONENT_TO_RECIPE=( [kernel]="recipes/core/kernel" [base]="recipes/core/base" [relibc]="recipes/core/relibc" [bootloader]="recipes/core/bootloader" [installer]="recipes/core/installer" [userutils]="recipes/core/userutils" ) linked=0 skipped=0 for component in "${!PATCH_COMPONENT_TO_RECIPE[@]}"; do recipe_dir="${PATCH_COMPONENT_TO_RECIPE[$component]}" [ -d "$recipe_dir" ] || continue patch_dir="local/patches/${component}" # Collect all .patch files from both the component dir and absorbed/ subdir. find "$patch_dir" -maxdepth 2 -name "*.patch" -type f 2>/dev/null | while read patch_file; do patch_name="$(basename "$patch_file")" # Resolve the relative path from recipe dir to patch file. # recipe_dir is e.g. recipes/core/base (2 levels deep) # patch_file is e.g. local/patches/base/absorbed/P0-foo.patch # We need to go up from recipe_dir to repo root, then into local/patches/... # For recipes/core/base → ../../.. → repo root → local/patches/base/absorbed/... # Number of directory components = slashes + 1 depth=$(($(echo "$recipe_dir" | tr -cd '/' | wc -c) + 1)) up="" for ((i=0; i