#!/bin/bash # carla-build.sh — Build Carla plugin host from source for RPi4B (ARM Cortex-A72) # Run on the Raspberry Pi 4B directly. Estimated build time: 30-60 min. # # Usage: # chmod +x carla-build.sh # ./carla-build.sh # Build only # ./carla-build.sh --install # Build + install to /usr/local # ./carla-build.sh --clean # Clean and rebuild set -euo pipefail CARLA_VERSION="2.6.0-alpha1" CARLA_REPO="https://github.com/falkTX/Carla.git" CARLA_DIR="/tmp/carla-build" INSTALL_PREFIX="/usr/local" JOBS=$(nproc 2>/dev/null || echo 4) # Cortex-A72 optimized flags for aarch64 # -march=armv8-a+crc+crypto covers baseline A72 features # -mtune=cortex-a72 schedules for A72 pipeline # -O3 -ffast-math: aggressive math (safe for audio) A72_CFLAGS="-march=armv8-a+crc+crypto -mtune=cortex-a72 -O3 -ffast-math -fdata-sections -ffunction-sections -fvisibility=hidden" A72_CXXFLAGS="-march=armv8-a+crc+crypto -mtune=cortex-a72 -O3 -ffast-math -fdata-sections -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' log() { echo -e "${GREEN}[carla-build]${NC} $*"; } warn() { echo -e "${YELLOW}[carla-build] WARN:${NC} $*"; } err() { echo -e "${RED}[carla-build] ERROR:${NC} $*" >&2; exit 1; } # ── Installation mode ────────────────────────────────── INSTALL=false CLEAN=false while [[ $# -gt 0 ]]; do case "$1" in --install) INSTALL=true; shift ;; --clean) CLEAN=true; shift ;; *) echo "Unknown flag: $1"; exit 1 ;; esac done # ── Check platform ───────────────────────────────────── ARCH=$(uname -m) if [[ "$ARCH" != "aarch64" ]] && [[ "$ARCH" != "armv7l" ]]; then warn "Not running on ARM (detected $ARCH). Cross-compilation not supported by this script." warn "Run this script directly on the Raspberry Pi 4B." fi # ── Install build dependencies ───────────────────────── log "Installing build dependencies..." sudo apt update -qq sudo apt install -y \ build-essential \ git \ cmake \ pkg-config \ g++ \ gcc \ make \ libasound2-dev \ libjack-jackd2-dev \ libpulse-dev \ libsndfile1-dev \ libx11-dev \ libxcursor-dev \ libxext-dev \ libxrandr-dev \ libfreetype6-dev \ libfontconfig1-dev \ libgl1-mesa-dev \ liblo-dev \ libmagic-dev \ libfluidsynth-dev \ libsmf-dev \ python3-pyqt5 \ python3-pyqt5.qtsvg \ python3-rdflib \ pyqt5-dev-tools \ python3-dev \ python3-liblo \ qtbase5-dev \ qtbase5-dev-tools \ libfftw3-dev \ librtmidi-dev \ libzita-resampler-dev # Optional: VST3 SDK (needed for VST3 plugin hosting) # The VST3 SDK must be obtained separately from Steinberg. # We check for it but don't error if absent. VST3_SDK_DIR="/opt/vst3sdk" VST3_AVAILABLE=false if [ -d "$VST3_SDK_DIR" ]; then log "VST3 SDK found at $VST3_SDK_DIR" VST3_AVAILABLE=true else warn "VST3 SDK not found at $VST3_SDK_DIR" warn "To add VST3 plugin hosting, download from:" warn " https://github.com/steinbergmedia/vst3sdk.git" warn " sudo git clone --recursive https://github.com/steinbergmedia/vst3sdk.git /opt/vst3sdk" warn "Continuing without VST3 support..." fi # ── Clone Carla ──────────────────────────────────────── if [ "$CLEAN" = true ] || [ ! -d "$CARLA_DIR" ]; then log "Cloning Carla repository..." rm -rf "$CARLA_DIR" git clone --depth 1 --branch main "$CARLA_REPO" "$CARLA_DIR" fi cd "$CARLA_DIR" # ── Patch Makefile for ARM Cortex-A72 ───────────────── log "Patching Carla Makefile for Cortex-A72 optimization..." # Back up original if [ ! -f source/Makefile.mk.orig ]; then cp source/Makefile.mk source/Makefile.mk.orig fi # Add ARM64 optimization flags after the ARM32 section if ! grep -q "CPU_ARM64_OR_AARCH64" source/Makefile.mk; then sed -i '/^ifeq .*CPU_ARM_OR_AARCH64.*/,/^endif/{ /^endif/{ i\ \ ifeq ($(CPU_ARM64_OR_AARCH64),true)\ BASE_OPTS += -march=armv8-a+crc+crypto -mtune=cortex-a72\ endif } }' source/Makefile.mk log "Added ARM64 optimization block to Makefile.mk" fi # Check for features log "Checking available features..." make features 2>&1 | tee /tmp/carla-features.log || true # ── Build Carla ──────────────────────────────────────── log "Building Carla (${JOBS} parallel jobs)..." export CFLAGS="$A72_CFLAGS" export CXXFLAGS="$A72_CXXFLAGS" # Build with all available features # NOOPT= removes CPU-specific flags so we can supply our own # WITH_LTO=true enables link-time optimization for smaller/faster binary make -j"$JOBS" \ PREFIX="$INSTALL_PREFIX" \ WITH_LTO=true \ 2>&1 | tee /tmp/carla-build.log log "Carla build complete." # ── Check build results ─────────────────────────────── if [ -f "source/frontend/carla" ]; then log "✓ Carla frontend binary built successfully." else err "Carla frontend binary not found. Check /tmp/carla-build.log" fi # ── Install (optional) ───────────────────────────────── if [ "$INSTALL" = true ]; then log "Installing Carla to $INSTALL_PREFIX..." sudo make install PREFIX="$INSTALL_PREFIX" sudo ldconfig # Verify installation if command -v carla >/dev/null 2>&1; then log "✓ Carla installed successfully: $(which carla)" else warn "Carla binary not on PATH. It may be in /usr/local/bin/carla" fi # Create desktop integration if [ -f "resources/carla.desktop" ]; then sudo cp resources/carla.desktop /usr/local/share/applications/ fi fi # ── Output summary ───────────────────────────────────── log "" log "╔══════════════════════════════════════════════╗" log "║ Carla Build Summary ║" log "╚══════════════════════════════════════════════╝" log "" log " Binary: $CARLA_DIR/source/frontend/carla" log " Install: $([ "$INSTALL" = true ] && echo "yes" || echo "no (use --install)")" log " Platform: $ARCH (Cortex-A72 optimized)" log " Plugins: LV2, LADSPA, DSSI, SF2/SFZ" log " VST3: $([ "$VST3_AVAILABLE" = true ] && echo "yes" || echo "no (install VST3 SDK)")" log " JACK: yes (ALSA backend)" log " OSC: yes (liblo)" log " FluidSynth: yes (SF2/SFZ)" log "" log " Next steps:" log " 1. Start JACK: sudo audio-stack-start" log " 2. Run Carla: carla ./config/carla-default.carxp" log " 3. Build NAM: ./scripts/nam-build.sh" log ""