Skip to content

Instantly share code, notes, and snippets.

@DarkGhostHunter
Created November 18, 2025 05:07
Show Gist options
  • Select an option

  • Save DarkGhostHunter/5104535432754c60872c2ea8c2b3bf7b to your computer and use it in GitHub Desktop.

Select an option

Save DarkGhostHunter/5104535432754c60872c2ea8c2b3bf7b to your computer and use it in GitHub Desktop.
Creates a full-features OpenWRT firmware for Dynalink DL-WRX36
#!/bin/bash
# Script to update jkool702's Quality build with AgustinLorenzo's NSS base
# Run from ~/openwrt directory in Distrobox (Debian stable)
#
# This was curated by using Claude AI. Source at:
# https://claude.ai/public/artifacts/7be7051b-b5d1-40d5-88d4-5603860fc2cf
set -e # Exit on error
# Check if this is a continuation of a previous build
CONTINUE_BUILD=false
if [ -f ~/openwrt/.build_in_progress ] && [ -d ~/openwrt/nss-base ]; then
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "⚠️ PREVIOUS BUILD DETECTED"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "It looks like a previous build was interrupted or failed."
echo "You can continue from where it left off, or start fresh."
echo ""
echo -n "Continue previous build? [Y/n] (auto-yes in 10s): "
CONTINUE_CHOICE=""
if read -t 10 -r CONTINUE_CHOICE; then
echo ""
else
echo ""
echo "Timeout reached, continuing previous build"
CONTINUE_CHOICE="y"
fi
case "${CONTINUE_CHOICE,,}" in
n|no)
echo "Starting fresh build. Cleaning previous state..."
rm -f ~/openwrt/.build_in_progress
cd ~/openwrt/nss-base
make clean 2>/dev/null || true
echo "✓ Cleaned previous build state"
echo ""
;;
*)
echo "Continuing from previous build..."
CONTINUE_BUILD=true
echo ""
# Skip to build section
;;
esac
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
fi
if [ "$CONTINUE_BUILD" = false ]; then
echo "=== OpenWRT NSS Build Update Script ==="
echo "This script will merge the Quality build customizations with the latest NSS base"
echo ""
# Step 0: Offer to install ccache for better performance
echo "[0/11] Build Performance Setup"
echo ""
if command -v ccache &> /dev/null; then
echo "✓ ccache is already installed"
else
echo "ccache is a compiler cache that dramatically speeds up rebuilds."
echo ""
echo "Benefits:"
echo " - First build: Same speed as without ccache"
echo " - Rebuilds: 5-10x faster (1-2 hours → 10-20 minutes)"
echo " - Cache can be saved and reused across build sessions"
echo ""
echo -n "Install ccache? [Y/n] (auto-yes in 10s): "
INSTALL_CCACHE=""
if read -t 10 -r INSTALL_CCACHE; then
echo ""
else
echo ""
echo "Timeout reached, defaulting to YES"
INSTALL_CCACHE="y"
fi
case "${INSTALL_CCACHE,,}" in
n|no)
echo "Skipping ccache installation. You can install it later with:"
echo " sudo apt-get install ccache"
;;
*)
echo "Installing ccache..."
sudo apt-get update && sudo apt-get install -y ccache
echo "✓ ccache installed successfully"
;;
esac
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "⚡ PERFORMANCE TIP: RAM-based build directory"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "For 20-30% faster builds, you can mount build_dir on tmpfs (RAM)."
echo ""
# Detect if running in Distrobox or Toolbox
if [ -f /run/.containerenv ] || [ -n "$DISTROBOX_ENTER_PATH" ] || [ -n "$TOOLBOX_PATH" ]; then
echo "✓ Container environment detected (Distrobox/Toolbox)"
echo ""
echo "Would you like to enable RAM-based builds now?"
echo ""
echo "Recommended sizes:"
echo " • 30GB - Sufficient for most builds (default)"
echo " • 42GB - Recommended for feature-complete builds with all packages"
echo " • Custom - Specify your own size"
echo ""
echo -n "Enable RAM-based builds? [Y/n] (auto-no in 10s): "
ENABLE_TMPFS=""
if read -t 10 -r ENABLE_TMPFS; then
echo ""
else
echo ""
echo "Timeout reached, skipping RAM-based builds"
ENABLE_TMPFS="n"
fi
case "${ENABLE_TMPFS,,}" in
y|yes)
echo "Setting up RAM-based build directory..."
echo ""
echo "Select tmpfs size:"
echo " 1) 30GB (default - sufficient for most builds)"
echo " 2) 42GB (recommended for feature-complete builds)"
echo " 3) Custom size"
echo ""
echo -n "Choice [1/2/3] (auto-select 1 in 10s): "
TMPFS_CHOICE=""
if read -t 10 -r TMPFS_CHOICE; then
echo ""
else
echo ""
echo "Timeout reached, using 30GB"
TMPFS_CHOICE="1"
fi
case "$TMPFS_CHOICE" in
2)
TMPFS_SIZE="42G"
echo "✓ Selected 42GB (feature-complete builds)"
;;
3)
echo -n "Enter custom size (e.g., 50G, 64G): "
read -r CUSTOM_SIZE
if [[ "$CUSTOM_SIZE" =~ ^[0-9]+[GgMm]$ ]]; then
TMPFS_SIZE="${CUSTOM_SIZE^^}"
echo "✓ Selected custom size: $TMPFS_SIZE"
else
echo "Invalid size format. Using default 30GB"
TMPFS_SIZE="30G"
fi
;;
*)
TMPFS_SIZE="30G"
echo "✓ Selected 30GB (default)"
;;
esac
# This will be created later, but we need to ensure the path exists for mounting
BUILD_DIR_PATH=~/openwrt/nss-base/build_dir
# Create a marker file to indicate tmpfs should be mounted before build
mkdir -p ~/openwrt
echo "$BUILD_DIR_PATH" > ~/openwrt/.tmpfs_mount_requested
echo "$TMPFS_SIZE" >> ~/openwrt/.tmpfs_mount_requested
echo ""
echo "✓ RAM-based builds will be enabled before compilation"
echo " Size: $TMPFS_SIZE"
echo " Location: $BUILD_DIR_PATH"
;;
*)
echo "Skipping RAM-based builds. You can enable it manually later:"
echo ""
echo " For 30GB (default):"
echo " mkdir -p ~/openwrt/nss-base/build_dir"
echo " sudo mount -t tmpfs -o size=30G tmpfs ~/openwrt/nss-base/build_dir"
echo ""
echo " For 42GB (feature-complete):"
echo " mkdir -p ~/openwrt/nss-base/build_dir"
echo " sudo mount -t tmpfs -o size=42G tmpfs ~/openwrt/nss-base/build_dir"
;;
esac
else
echo "Running outside container environment (Docker or bare metal)."
echo ""
echo "Recommended tmpfs sizes:"
echo " • 30GB - Sufficient for most builds"
echo " • 42GB - Recommended for feature-complete builds"
echo ""
echo "For Docker, add this to your docker run command:"
echo " --tmpfs /home/user/openwrt/nss-base/build_dir:rw,size=42G,mode=1777"
echo ""
echo "For bare metal, you can run after the script completes:"
echo " mkdir -p ~/openwrt/nss-base/build_dir"
echo " sudo mount -t tmpfs -o size=42G tmpfs ~/openwrt/nss-base/build_dir"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "Press Enter to continue..."
read -r
# Step 1: Install required dependencies for Debian
echo "[1/11] Installing build dependencies..."
sudo apt-get update
sudo apt-get install -y build-essential clang flex bison g++ gawk \
gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev \
python3-setuptools rsync swig unzip zlib1g-dev file wget \
python3 python3-dev python3-pip libpython3-dev curl libelf-dev \
xsltproc libxml-parser-perl patch diffutils findutils quilt
# Step 2: Create working directory structure
echo "[2/11] Setting up directory structure..."
cd ~
mkdir -p openwrt/backup
cd openwrt
# Step 3: Clone or update the NSS repository (AgustinLorenzo)
echo "[3/11] Cloning/updating NSS base repository..."
if [ -d "nss-base" ]; then
echo "NSS base directory exists, updating..."
cd nss-base
git pull
cd ..
else
echo "Cloning NSS base repository (shallow clone for faster download)..."
git clone --depth 1 https://github.com/AgustinLorenzo/openwrt.git nss-base
fi
# Step 4: Download Quality build config and package list
echo "[4/11] Downloading Quality build configuration..."
cd ~/openwrt
mkdir -p quality-config
# Download the config.buildinfo from Quality build
wget -O quality-config/config.buildinfo \
"https://github.com/jkool702/openwrt-custom-builds/raw/main-NSS/WRX36/bin/targets/qualcommax/ipq807x/config.buildinfo"
# Download feeds.buildinfo for package information
wget -O quality-config/feeds.buildinfo \
"https://github.com/jkool702/openwrt-custom-builds/raw/main-NSS/WRX36/bin/targets/qualcommax/ipq807x/feeds.buildinfo"
# Step 5: Prepare the NSS base for building
echo "[5/11] Preparing NSS base build environment..."
cd ~/openwrt/nss-base
# Update feeds first
./scripts/feeds update -a
# Step 5.5: Fix python3-distutils dependencies in feed Makefiles BEFORE installing
echo "[5.5/11] Fixing deprecated python3-distutils references in feeds..."
# Fix distutils references in the feeds directory (before installation)
find feeds -type f -name Makefile -exec grep -l "python3-distutils" {} \; | while read -r makefile; do
echo " Patching feed: $makefile"
# Remove python3-distutils from DEPENDS lines
sed -i 's/+python3-distutils//g' "$makefile"
sed -i 's/python3-distutils //g' "$makefile"
# Replace it with python3-setuptools if it was the only dependency
sed -i 's/DEPENDS:=\s*$/DEPENDS:=+python3-setuptools/g' "$makefile"
done
echo " Feed Makefiles patched successfully"
# Now install feeds with patched Makefiles
./scripts/feeds install -a
# Also fix any remaining references in installed packages (belt and suspenders approach)
find package/feeds -type f -name Makefile -exec grep -l "python3-distutils" {} \; 2>/dev/null | while read -r makefile; do
echo " Patching installed package: $makefile"
sed -i 's/+python3-distutils//g' "$makefile"
sed -i 's/python3-distutils //g' "$makefile"
done
echo " All distutils references removed"
# Step 6: Apply Quality build configuration to NSS base
echo "[6/11] Applying Quality build configuration to NSS base..."
# Copy the config.buildinfo as .config
cp ~/openwrt/quality-config/config.buildinfo .config
# Make sure the config is for the correct target
echo "CONFIG_TARGET_qualcommax=y" >> .config
echo "CONFIG_TARGET_qualcommax_ipq807x=y" >> .config
echo "CONFIG_TARGET_qualcommax_ipq807x_DEVICE_dynalink_dl-wrx36=y" >> .config
# Step 7: Update the configuration for the new base
echo "[7/11] Updating configuration for current NSS base..."
# Expand the config to include all new options with defaults
make defconfig
# Step 8: Extract package list from Quality build
echo "[8/11] Creating package installation list..."
cd ~/openwrt
# Parse the config to find all packages that are built into firmware (=y)
# Exclude packages that are modules (=m) as they can be installed later
echo "Extracting firmware-integrated packages only (excluding optional modules)..."
grep "^CONFIG_PACKAGE_.*=y" quality-config/config.buildinfo | \
sed 's/CONFIG_PACKAGE_//g' | \
sed 's/=y//g' > quality-config/package-list.txt
# Also extract modules for informational purposes and optional building
grep "^CONFIG_PACKAGE_.*=m" quality-config/config.buildinfo | \
sed 's/CONFIG_PACKAGE_//g' | \
sed 's/=m//g' > quality-config/module-list.txt || touch quality-config/module-list.txt
MODULE_COUNT=$(wc -l < quality-config/module-list.txt)
echo "Found $(wc -l < quality-config/package-list.txt) packages to build into firmware"
echo "Found $MODULE_COUNT optional modules available"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "⚙️ OPTIONAL: Build All Modules"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "By default, only firmware-integrated packages are built."
echo "Optional modules can be installed later using opkg."
echo ""
echo "Would you like to also BUILD all $MODULE_COUNT optional modules now?"
echo ""
echo "⚠️ WARNING: Building all modules will:"
echo " • Increase build time by 30-50% (add 15-45 minutes)"
echo " • Require 10-15GB additional disk space during build"
echo " • Create larger package repository"
echo ""
echo "Benefits:"
echo " • All packages immediately available after flashing"
echo " • No need for internet connection to install packages later"
echo " • Useful for offline deployment or package distribution"
echo ""
echo -n "Build all modules? [y/N] (auto-no in 10s): "
BUILD_MODULES=""
if read -t 10 -r BUILD_MODULES; then
echo ""
else
echo ""
echo "Timeout reached, building firmware packages only"
BUILD_MODULES="n"
fi
case "${BUILD_MODULES,,}" in
y|yes)
echo "✓ Will build all $MODULE_COUNT optional modules"
echo " This will increase build time and space requirements"
# Append modules to the package list
cat quality-config/module-list.txt >> quality-config/package-list.txt
BUILD_ALL_MODULES=true
echo ""
echo "Updated package count: $(wc -l < quality-config/package-list.txt) packages"
;;
*)
echo "✓ Building firmware packages only ($MODULE_COUNT modules excluded)"
echo " Modules can be installed post-flash with: opkg install <package>"
BUILD_ALL_MODULES=false
;;
esac
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Step 9: Install Quality packages in NSS base
echo "[9/11] Installing Quality build packages..."
cd ~/openwrt/nss-base
# Count total packages for progress tracking
TOTAL_PACKAGES=$(wc -l < ~/openwrt/quality-config/package-list.txt)
if [ "$BUILD_ALL_MODULES" = true ]; then
echo "Installing $TOTAL_PACKAGES packages (firmware + all modules) in batch mode..."
echo "⚠️ This will take significantly longer than firmware-only builds"
else
echo "Installing $TOTAL_PACKAGES firmware-integrated packages in batch mode..."
fi
echo ""
# Install all packages in one go (much faster than individual installs)
cat ~/openwrt/quality-config/package-list.txt | xargs -n 50 ./scripts/feeds install 2>&1 | \
grep -v "WARNING: No feed for package" | \
grep -v "is already installed" || true
# Install additional essential packages
echo ""
echo "Installing additional essential packages..."
echo " - aria2 (download manager)"
echo " - ariang (aria2 web frontend)"
echo " - luci-app-aria2 (LuCI integration for aria2)"
echo " - unzip, curl, squashfs-tools-mksquashfs (required for Plex)"
./scripts/feeds install aria2 ariang luci-app-aria2 unzip curl squashfs-tools-mksquashfs 2>&1 | \
grep -v "WARNING: No feed for package" | \
grep -v "is already installed" || true
echo ""
if [ "$BUILD_ALL_MODULES" = true ]; then
echo "✓ Package installation complete (firmware + all modules)"
echo " All $TOTAL_PACKAGES packages will be built"
else
echo "✓ Package installation complete (firmware packages only)"
echo " Optional modules excluded - install later with opkg"
fi
# Step 9.5: Setup Plex Media Server init script
echo ""
echo "[9.5/11] Setting up Plex Media Server system service..."
# Create the files directory structure for custom files
mkdir -p files/etc/init.d
mkdir -p files/etc/uci-defaults
# Download the Plex Media Server init script
echo "Downloading Plex Media Server init script..."
curl -s 'https://raw.githubusercontent.com/jkool702/openwrt-plexmediaserver/main/etc/init.d/plexmediaserver' \
> files/etc/init.d/plexmediaserver
# Make it executable
chmod +x files/etc/init.d/plexmediaserver
# Create a uci-defaults script to enable the service on first boot
cat > files/etc/uci-defaults/99-enable-plexmediaserver << 'EOF'
#!/bin/sh
# Enable Plex Media Server service on first boot
/etc/init.d/plexmediaserver enabled || {
/etc/init.d/plexmediaserver enable
}
exit 0
EOF
chmod +x files/etc/uci-defaults/99-enable-plexmediaserver
echo "✓ Plex Media Server init script added to firmware"
echo ""
echo "Plex Media Server Features:"
echo " • Runs as a native system service (no Docker required)"
echo " • Uses built-in libraries and compressed squashfs images"
echo " • Auto-detects external drives with Plex libraries"
echo " • Supports ARMv7 and ARMv8 architectures (IPQ807x)"
echo " • Web interface accessible at: http://10.0.0.1:32400/web"
echo ""
echo "Post-installation usage:"
echo " service plexmediaserver start - Start Plex"
echo " service plexmediaserver stop - Stop Plex"
echo " service plexmediaserver update - Update to latest version"
echo " service plexmediaserver restart - Restart Plex"
echo ""
echo "To initialize on an external drive:"
echo " mkdir -p /mnt/your_drive/.plex/Library"
echo " service plexmediaserver start"
echo ""
# Step 10: Final configuration menu
echo "[10/11] Opening configuration menu for final adjustments..."
echo ""
echo "IMPORTANT: You can now review and adjust the configuration."
echo "The Quality build's packages and settings have been applied."
echo ""
echo "Key things to verify:"
echo " - Target Device: Should be set to Dynalink DL-WRX36"
echo " - NSS Support: Should be enabled (from NSS base)"
echo " - Packages: All Quality build packages should be selected"
echo ""
echo "Additional packages included:"
echo " ✓ aria2 + ariang + luci-app-aria2 (download manager with web UI)"
echo " ✓ Plex Media Server init script (system service, no Docker)"
echo " ✓ unzip, curl, squashfs-tools-mksquashfs (Plex dependencies)"
echo ""
echo "Plex Media Server will be available as a system service after flashing."
echo "Access it at: http://10.0.0.1:32400/web"
echo ""
echo "Press Enter to open menuconfig, or Ctrl+C to skip..."
read -r
make menuconfig
# Step 11: Setup ccache directory and restore cache if available
echo "[11/11] Setting up ccache and custom configuration..."
export CCACHE_DIR=~/openwrt/.ccache
mkdir -p "$CCACHE_DIR"
if [ -f ~/openwrt/ccache.tar.gz ]; then
echo "Found existing ccache archive, restoring..."
tar -xzf ~/openwrt/ccache.tar.gz -C ~/openwrt/ 2>/dev/null || echo "Note: Could not extract cache (may be first run)"
if [ -d "$CCACHE_DIR" ]; then
CACHE_SIZE=$(du -sh "$CCACHE_DIR" 2>/dev/null | cut -f1)
echo "✓ Restored ccache ($CACHE_SIZE)"
fi
else
echo "No existing ccache found (this is normal for first run)"
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "⚙️ OPTIONAL: Custom Default Configuration Files"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "You can provide custom default configuration files to be included"
echo "in the firmware. This is useful for:"
echo ""
echo " • Setting custom default IP addresses (network, dhcp)"
echo " • Pre-configuring WiFi SSIDs and passwords (wireless)"
echo " • Setting up adblock, firewall, or other service configs"
echo " • Any /etc/config/ file you want to customize"
echo ""
echo "Default location: ~/openwrt/config_defaults/"
echo ""
CONFIG_DEFAULTS_DIR=~/openwrt/config_defaults
if [ -d "$CONFIG_DEFAULTS_DIR" ] && [ "$(ls -A "$CONFIG_DEFAULTS_DIR" 2>/dev/null)" ]; then
echo "✓ Found custom configuration directory with files:"
ls -1 "$CONFIG_DEFAULTS_DIR" | sed 's/^/ - /'
echo ""
echo -n "Apply these custom configurations to firmware? [Y/n] (auto-yes in 10s): "
APPLY_CONFIGS=""
if read -t 10 -r APPLY_CONFIGS; then
echo ""
else
echo ""
echo "Timeout reached, applying custom configurations"
APPLY_CONFIGS="y"
fi
case "${APPLY_CONFIGS,,}" in
n|no)
echo "Skipping custom configurations"
USE_CUSTOM_CONFIGS=false
;;
*)
echo "Applying custom configurations to firmware..."
cd ~/openwrt/nss-base
# Create the /etc/config directory in files/ if it doesn't exist
mkdir -p files/etc/config
# Copy all config files from config_defaults to files/etc/config
APPLIED_COUNT=0
for config_file in "$CONFIG_DEFAULTS_DIR"/*; do
if [ -f "$config_file" ]; then
filename=$(basename "$config_file")
cp "$config_file" "files/etc/config/$filename"
echo " ✓ Applied: $filename"
APPLIED_COUNT=$((APPLIED_COUNT + 1))
fi
done
echo ""
echo "✓ Applied $APPLIED_COUNT custom configuration files"
echo " These will be included as defaults in the firmware"
USE_CUSTOM_CONFIGS=true
;;
esac
else
echo "No custom configuration directory found at:"
echo " $CONFIG_DEFAULTS_DIR"
echo ""
echo "To use custom configs, create this directory and add config files:"
echo " mkdir -p ~/openwrt/config_defaults"
echo " cp /etc/config/network ~/openwrt/config_defaults/"
echo " cp /etc/config/wireless ~/openwrt/config_defaults/"
echo " # Edit files in ~/openwrt/config_defaults/ as needed"
echo ""
echo "Then re-run this script to include them in the build."
USE_CUSTOM_CONFIGS=false
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Create build info file
echo "=== Build Information ===" > ~/openwrt/BUILD_INFO.txt
echo "NSS Base: AgustinLorenzo/openwrt" >> ~/openwrt/BUILD_INFO.txt
echo "Quality Config: jkool702/openwrt-custom-builds (main-NSS)" >> ~/openwrt/BUILD_INFO.txt
echo "Build Date: $(date)" >> ~/openwrt/BUILD_INFO.txt
echo "Git Commit (NSS): $(cd ~/openwrt/nss-base && git rev-parse HEAD)" >> ~/openwrt/BUILD_INFO.txt
echo "Build All Modules: ${BUILD_ALL_MODULES:-false}" >> ~/openwrt/BUILD_INFO.txt
echo "Custom Configs Applied: ${USE_CUSTOM_CONFIGS:-false}" >> ~/openwrt/BUILD_INFO.txt
if [ "$USE_CUSTOM_CONFIGS" = true ]; then
echo "Custom Config Files:" >> ~/openwrt/BUILD_INFO.txt
ls -1 "$CONFIG_DEFAULTS_DIR" 2>/dev/null | sed 's/^/ - /' >> ~/openwrt/BUILD_INFO.txt
fi
echo "" >> ~/openwrt/BUILD_INFO.txt
echo ""
echo "=== Configuration Complete ==="
echo ""
echo "Build information saved to ~/openwrt/BUILD_INFO.txt"
echo ""
echo "The compiled firmware will be in:"
echo " ~/openwrt/nss-base/bin/targets/qualcommax/ipq807x/"
echo ""
if [ "$BUILD_ALL_MODULES" = true ]; then
echo "Note: Package repository with all modules will be available at:"
echo " ~/openwrt/nss-base/bin/packages/aarch64_cortex-a53/"
echo ""
fi
fi # End of CONTINUE_BUILD check
echo "=========================================="
echo "Ready to build firmware!"
echo "=========================================="
echo ""
echo "Build Configuration:"
echo " System has $(nproc) CPU cores available"
echo " Using ccache for faster rebuilds (if available)"
echo " Downloads will be cached for future builds"
if [ "$BUILD_ALL_MODULES" = true ]; then
echo " Building ALL packages (firmware + modules)"
echo " ⚠️ Build will take 30-50% longer"
else
echo " Building firmware packages only"
fi
echo ""
echo "Options:"
echo " - Press ENTER (or wait 15 seconds) to start automatic build"
echo " - Press 'v' + ENTER for verbose build (single-threaded, readable output)"
echo " - Press 'm' + ENTER for multi-threaded verbose build (faster but harder to read)"
echo " - Press 'n' + ENTER to skip and build manually later"
echo ""
echo -n "Your choice: "
# Read user input with 15 second timeout
BUILD_CHOICE=""
if read -t 15 -r BUILD_CHOICE; then
echo ""
else
echo ""
echo "Timeout reached, starting automatic build..."
BUILD_CHOICE=""
fi
# Mark build as in progress
touch ~/openwrt/.build_in_progress
case "${BUILD_CHOICE,,}" in
v)
echo ""
echo "=== Starting VERBOSE build (single-threaded) ==="
echo "This will take longer but show detailed compilation progress..."
echo "Output will be readable and every command will be visible."
echo ""
# Create log file with UTC timestamp
UTC_TIMESTAMP=$(date -u +"%Y%m%d_%H%M%S_UTC")
LOG_FILE=~/openwrt/build-log_${UTC_TIMESTAMP}.txt
echo "Build output will be logged to:"
echo " $LOG_FILE"
echo ""
echo "This log can be shared with LLMs for build analysis."
echo ""
# Performance optimizations
cd ~/openwrt/nss-base
# Enable ccache if available
if command -v ccache &> /dev/null; then
echo "Enabling ccache for faster compilation..."
export PATH="/usr/lib/ccache:$PATH"
export CCACHE_DIR=~/openwrt/.ccache
mkdir -p "$CCACHE_DIR"
fi
# Set optimal MAKE flags for single-threaded verbose
export MAKEFLAGS="-j1"
sleep 2
# Start logging with header
{
echo "=========================================="
echo "OpenWRT NSS Build - Verbose Log (Single-threaded)"
echo "=========================================="
echo "Build started: $(date -u) UTC"
echo "Local time: $(date)"
echo "NSS Base: AgustinLorenzo/openwrt"
echo "Quality Config: jkool702/openwrt-custom-builds (main-NSS)"
echo "Git Commit: $(git rev-parse HEAD)"
echo "System: $(uname -a)"
echo "CPU cores: $(nproc)"
echo "Parallel jobs: 1 (verbose mode)"
echo "ccache enabled: $(command -v ccache &> /dev/null && echo 'yes' || echo 'no')"
echo "=========================================="
echo ""
} > "$LOG_FILE"
echo ""
echo "[Build Step 1/2] Downloading source packages..."
# Mount tmpfs if requested
if [ -f ~/openwrt/.tmpfs_mount_requested ]; then
BUILD_DIR_PATH=$(sed -n '1p' ~/openwrt/.tmpfs_mount_requested)
TMPFS_SIZE=$(sed -n '2p' ~/openwrt/.tmpfs_mount_requested)
echo ""
echo "Setting up RAM-based build directory..."
mkdir -p "$BUILD_DIR_PATH"
if sudo mount -t tmpfs -o size=$TMPFS_SIZE tmpfs "$BUILD_DIR_PATH" 2>/dev/null; then
echo "✓ RAM-based build directory mounted ($TMPFS_SIZE tmpfs)"
echo " Location: $BUILD_DIR_PATH"
else
echo "⚠ Failed to mount tmpfs (continuing with disk-based build)"
echo " This is not critical - build will use regular disk storage"
fi
echo ""
fi
# Restore ccache if available
if [ -f ~/openwrt/ccache.tar.gz ] && command -v ccache &> /dev/null; then
echo "Restoring compiler cache..."
tar -xzf ~/openwrt/ccache.tar.gz -C ~/openwrt/ 2>/dev/null || true
fi
make -j$(nproc) download V=s 2>&1 | tee -a "$LOG_FILE" || {
echo ""
echo "ERROR: Download failed. Please check your internet connection."
echo "Full log available at: $LOG_FILE"
exit 1
}
echo ""
echo "[Build Step 2/2] Compiling firmware (verbose single-threaded mode)..."
echo "This can take 2-4 hours depending on your system..."
echo "Note: Single-threaded for readable output"
echo ""
{
echo ""
echo "=== COMPILATION PHASE STARTED ==="
echo "Time: $(date -u) UTC"
echo ""
} >> "$LOG_FILE"
make -j1 V=s 2>&1 | tee -a "$LOG_FILE" || {
echo ""
echo "ERROR: Build failed. Check the output above for errors."
echo "Full log available at: $LOG_FILE"
echo ""
echo "You can continue this build by running the script again."
exit 1
}
{
echo ""
echo "=== BUILD COMPLETED SUCCESSFULLY ==="
echo "Time: $(date -u) UTC"
echo ""
} >> "$LOG_FILE"
# Save ccache after successful build
if command -v ccache &> /dev/null && [ -d "$CCACHE_DIR" ]; then
echo ""
echo "Saving compiler cache for future builds..."
tar -czf ~/openwrt/ccache.tar.gz -C ~/openwrt .ccache 2>/dev/null || echo "Warning: Could not save cache"
if [ -f ~/openwrt/ccache.tar.gz ]; then
CACHE_ARCHIVE_SIZE=$(du -sh ~/openwrt/ccache.tar.gz | cut -f1)
echo "✓ Cache saved to ~/openwrt/ccache.tar.gz ($CACHE_ARCHIVE_SIZE)"
fi
fi
# Remove build in progress marker
rm -f ~/openwrt/.build_in_progress
echo ""
echo "=== BUILD SUCCESSFUL (VERBOSE) ==="
echo ""
echo "Complete build log saved to:"
echo " $LOG_FILE"
echo ""
echo "Log file size: $(du -h "$LOG_FILE" | cut -f1)"
;;
m)
echo ""
echo "=== Starting VERBOSE build (multi-threaded) ==="
echo ""
echo "⚠️ WARNING: Multi-threaded verbose output will be interleaved!"
echo " The terminal output will be difficult to read as multiple"
echo " compilation jobs print simultaneously. However, everything"
echo " will still be logged to the file for later analysis."
echo ""
echo "This mode is faster than single-threaded verbose but slower"
echo "than regular multi-threaded (due to verbose overhead)."
echo ""
# Create log file with UTC timestamp
UTC_TIMESTAMP=$(date -u +"%Y%m%d_%H%M%S_UTC")
LOG_FILE=~/openwrt/build-log_${UTC_TIMESTAMP}.txt
echo "Build output will be logged to:"
echo " $LOG_FILE"
echo ""
# Performance optimizations
cd ~/openwrt/nss-base
# Enable ccache if available
if command -v ccache &> /dev/null; then
echo "Enabling ccache for faster compilation..."
export PATH="/usr/lib/ccache:$PATH"
export CCACHE_DIR=~/openwrt/.ccache
mkdir -p "$CCACHE_DIR"
fi
# Calculate optimal parallel jobs
PARALLEL_JOBS=$(($(nproc) + 2))
echo "Using $PARALLEL_JOBS parallel jobs ($(nproc) cores + 2)"
export MAKEFLAGS="-j$PARALLEL_JOBS"
sleep 3
# Start logging with header
{
echo "=========================================="
echo "OpenWRT NSS Build - Verbose Log (Multi-threaded)"
echo "=========================================="
echo "Build started: $(date -u) UTC"
echo "Local time: $(date)"
echo "NSS Base: AgustinLorenzo/openwrt"
echo "Quality Config: jkool702/openwrt-custom-builds (main-NSS)"
echo "Git Commit: $(git rev-parse HEAD)"
echo "System: $(uname -a)"
echo "CPU cores: $(nproc)"
echo "Parallel jobs: $PARALLEL_JOBS"
echo "ccache enabled: $(command -v ccache &> /dev/null && echo 'yes' || echo 'no')"
echo "=========================================="
echo ""
} > "$LOG_FILE"
echo ""
echo "[Build Step 1/2] Downloading source packages..."
# Mount tmpfs if requested
if [ -f ~/openwrt/.tmpfs_mount_requested ]; then
BUILD_DIR_PATH=$(sed -n '1p' ~/openwrt/.tmpfs_mount_requested)
TMPFS_SIZE=$(sed -n '2p' ~/openwrt/.tmpfs_mount_requested)
echo ""
echo "Setting up RAM-based build directory..."
mkdir -p "$BUILD_DIR_PATH"
if sudo mount -t tmpfs -o size=$TMPFS_SIZE tmpfs "$BUILD_DIR_PATH" 2>/dev/null; then
echo "✓ RAM-based build directory mounted ($TMPFS_SIZE tmpfs)"
echo " Location: $BUILD_DIR_PATH"
else
echo "⚠ Failed to mount tmpfs (continuing with disk-based build)"
echo " This is not critical - build will use regular disk storage"
fi
echo ""
fi
# Restore ccache if available
if [ -f ~/openwrt/ccache.tar.gz ] && command -v ccache &> /dev/null; then
echo "Restoring compiler cache..."
tar -xzf ~/openwrt/ccache.tar.gz -C ~/openwrt/ 2>/dev/null || true
fi
make -j$(nproc) download V=s 2>&1 | tee -a "$LOG_FILE" || {
echo ""
echo "ERROR: Download failed. Please check your internet connection."
echo "Full log available at: $LOG_FILE"
exit 1
}
echo ""
echo "[Build Step 2/2] Compiling firmware (verbose multi-threaded mode)..."
echo "This can take 1-2 hours depending on your system..."
echo "Note: Terminal output will be jumbled but log file will contain everything"
echo ""
{
echo ""
echo "=== COMPILATION PHASE STARTED ==="
echo "Time: $(date -u) UTC"
echo ""
} >> "$LOG_FILE"
make -j$PARALLEL_JOBS V=s 2>&1 | tee -a "$LOG_FILE" || {
echo ""
echo "ERROR: Build failed. Check the log file for details."
echo "Full log available at: $LOG_FILE"
echo ""
echo "You can continue this build by running the script again."
exit 1
}
{
echo ""
echo "=== BUILD COMPLETED SUCCESSFULLY ==="
echo "Time: $(date -u) UTC"
echo ""
} >> "$LOG_FILE"
# Save ccache after successful build
if command -v ccache &> /dev/null && [ -d "$CCACHE_DIR" ]; then
echo ""
echo "Saving compiler cache for future builds..."
tar -czf ~/openwrt/ccache.tar.gz -C ~/openwrt .ccache 2>/dev/null || echo "Warning: Could not save cache"
if [ -f ~/openwrt/ccache.tar.gz ]; then
CACHE_ARCHIVE_SIZE=$(du -sh ~/openwrt/ccache.tar.gz | cut -f1)
echo "✓ Cache saved to ~/openwrt/ccache.tar.gz ($CACHE_ARCHIVE_SIZE)"
fi
fi
# Remove build in progress marker
rm -f ~/openwrt/.build_in_progress
echo ""
echo "=== BUILD SUCCESSFUL (VERBOSE MULTI-THREADED) ==="
echo ""
echo "Complete build log saved to:"
echo " $LOG_FILE"
echo ""
echo "Log file size: $(du -h "$LOG_FILE" | cut -f1)"
echo ""
if [ "$USE_CUSTOM_CONFIGS" = true ]; then
echo "✓ Custom configurations included in firmware:"
ls -1 "$CONFIG_DEFAULTS_DIR" 2>/dev/null | sed 's/^/ - /'
echo ""
fi
;;
n)
echo ""
echo "Build skipped. To build manually later with optimizations, run:"
echo " cd ~/openwrt/nss-base"
echo " export MAKEFLAGS=\"-j\$(($(nproc) + 2))\""
echo " make download"
echo " make"
echo ""
echo "For verbose output: make -j1 V=s"
echo ""
echo "Optional performance tips:"
echo " - Install ccache: sudo apt-get install ccache"
echo " - Enable ccache: export PATH=\"/usr/lib/ccache:\$PATH\""
echo " - Use tmpfs for build (if you have enough RAM):"
echo " sudo mount -t tmpfs -o size=32G tmpfs ~/openwrt/nss-base/build_dir"
# Remove build in progress marker
rm -f ~/openwrt/.build_in_progress
exit 0
;;
*)
echo ""
echo "=== Starting VERBOSE build ==="
echo "This will take longer but show detailed compilation progress..."
echo ""
# Create log file with UTC timestamp
UTC_TIMESTAMP=$(date -u +"%Y%m%d_%H%M%S_UTC")
LOG_FILE=~/openwrt/build-log_${UTC_TIMESTAMP}.txt
echo "Build output will be logged to:"
echo " $LOG_FILE"
echo ""
echo "This log can be shared with LLMs for build analysis."
echo ""
# Performance optimizations
cd ~/openwrt/nss-base
# Enable ccache if available
if command -v ccache &> /dev/null; then
echo "Enabling ccache for faster compilation..."
export PATH="/usr/lib/ccache:$PATH"
export CCACHE_DIR=~/openwrt/.ccache
mkdir -p "$CCACHE_DIR"
fi
# Set optimal MAKE flags
export MAKEFLAGS="-j$(($(nproc) + 2))"
sleep 2
# Start logging with header
{
echo "=========================================="
echo "OpenWRT NSS Build - Verbose Log"
echo "=========================================="
echo "Build started: $(date -u) UTC"
echo "Local time: $(date)"
echo "NSS Base: AgustinLorenzo/openwrt"
echo "Quality Config: jkool702/openwrt-custom-builds (main-NSS)"
echo "Git Commit: $(git rev-parse HEAD)"
echo "System: $(uname -a)"
echo "CPU cores: $(nproc)"
echo "Parallel jobs: $MAKEFLAGS"
echo "ccache enabled: $(command -v ccache &> /dev/null && echo 'yes' || echo 'no')"
echo "=========================================="
echo ""
} > "$LOG_FILE"
echo ""
echo ""
echo "[Build Step 1/2] Downloading source packages in parallel..."
# Mount tmpfs if requested
if [ -f ~/openwrt/.tmpfs_mount_requested ]; then
BUILD_DIR_PATH=$(sed -n '1p' ~/openwrt/.tmpfs_mount_requested)
TMPFS_SIZE=$(sed -n '2p' ~/openwrt/.tmpfs_mount_requested)
echo ""
echo "Setting up RAM-based build directory..."
mkdir -p "$BUILD_DIR_PATH"
if sudo mount -t tmpfs -o size=$TMPFS_SIZE tmpfs "$BUILD_DIR_PATH" 2>/dev/null; then
echo "✓ RAM-based build directory mounted ($TMPFS_SIZE tmpfs)"
echo " Location: $BUILD_DIR_PATH"
else
echo "⚠ Failed to mount tmpfs (continuing with disk-based build)"
echo " This is not critical - build will use regular disk storage"
fi
echo ""
fi
# Restore ccache if available
if [ -f ~/openwrt/ccache.tar.gz ] && command -v ccache &> /dev/null; then
echo "Restoring compiler cache..."
tar -xzf ~/openwrt/ccache.tar.gz -C ~/openwrt/ 2>/dev/null || true
fi
make -j$(nproc) download V=s 2>&1 | tee -a "$LOG_FILE" || {
echo ""
echo "ERROR: Download failed. Please check your internet connection."
echo "Full log available at: $LOG_FILE"
exit 1
}
echo ""
echo "[Build Step 2/2] Compiling firmware (verbose mode)..."
echo "This can take 1-3 hours depending on your system..."
echo "Note: Verbose mode uses single-threaded compilation for readable output"
echo ""
{
echo ""
echo "=== COMPILATION PHASE STARTED ==="
echo "Time: $(date -u) UTC"
echo ""
} >> "$LOG_FILE"
make -j1 V=s 2>&1 | tee -a "$LOG_FILE" || {
echo ""
echo "ERROR: Build failed. Check the output above for errors."
echo "Full log available at: $LOG_FILE"
exit 1
}
{
echo ""
echo "=== BUILD COMPLETED SUCCESSFULLY ==="
echo "Time: $(date -u) UTC"
echo ""
} >> "$LOG_FILE"
# Save ccache after successful build
if command -v ccache &> /dev/null && [ -d "$CCACHE_DIR" ]; then
echo ""
echo "Saving compiler cache for future builds..."
tar -czf ~/openwrt/ccache.tar.gz -C ~/openwrt .ccache 2>/dev/null || echo "Warning: Could not save cache"
if [ -f ~/openwrt/ccache.tar.gz ]; then
CACHE_ARCHIVE_SIZE=$(du -sh ~/openwrt/ccache.tar.gz | cut -f1)
echo "✓ Cache saved to ~/openwrt/ccache.tar.gz ($CACHE_ARCHIVE_SIZE)"
fi
fi
echo ""
echo "=== BUILD SUCCESSFUL (VERBOSE) ==="
echo ""
echo "Complete build log saved to:"
echo " $LOG_FILE"
echo ""
echo "Log file size: $(du -h "$LOG_FILE" | cut -f1)"
;;
n)
echo ""
echo "Build skipped. To build manually later with optimizations, run:"
echo " cd ~/openwrt/nss-base"
echo " export MAKEFLAGS=\"-j\$(($(nproc) + 2))\""
echo " make download"
echo " make"
echo ""
echo "For verbose output: make -j1 V=s"
echo ""
echo "Optional performance tips:"
echo " - Install ccache: sudo apt-get install ccache"
echo " - Enable ccache: export PATH=\"/usr/lib/ccache:\$PATH\""
echo " - Use tmpfs for build (if you have enough RAM):"
echo " sudo mount -t tmpfs -o size=32G tmpfs ~/openwrt/nss-base/build_dir"
exit 0
;;
*)
echo ""
echo "=== Starting optimized automatic build ==="
echo ""
cd ~/openwrt/nss-base
# Enable ccache if available
if command -v ccache &> /dev/null; then
echo "✓ Enabling ccache for faster compilation..."
export PATH="/usr/lib/ccache:$PATH"
export CCACHE_DIR=~/openwrt/.ccache
mkdir -p "$CCACHE_DIR"
ccache -M 10G # Set 10GB cache limit
else
echo "⚠ ccache not found. Install it for faster rebuilds:"
echo " sudo apt-get install ccache"
echo ""
fi
# Calculate optimal parallel jobs (CPU cores + 2 for I/O overlap)
PARALLEL_JOBS=$(($(nproc) + 2))
echo "✓ Using $PARALLEL_JOBS parallel jobs ($(nproc) cores + 2 for I/O)"
export MAKEFLAGS="-j$PARALLEL_JOBS"
# Enable download job parallelism
echo "✓ Enabling parallel downloads..."
echo ""
echo "[Build Step 1/2] Downloading source packages in parallel..."
# Mount tmpfs if requested
if [ -f ~/openwrt/.tmpfs_mount_requested ]; then
BUILD_DIR_PATH=$(sed -n '1p' ~/openwrt/.tmpfs_mount_requested)
TMPFS_SIZE=$(sed -n '2p' ~/openwrt/.tmpfs_mount_requested)
echo ""
echo "Setting up RAM-based build directory..."
mkdir -p "$BUILD_DIR_PATH"
if sudo mount -t tmpfs -o size=$TMPFS_SIZE tmpfs "$BUILD_DIR_PATH" 2>/dev/null; then
echo "✓ RAM-based build directory mounted ($TMPFS_SIZE tmpfs)"
echo " Location: $BUILD_DIR_PATH"
else
echo "⚠ Failed to mount tmpfs (continuing with disk-based build)"
echo " This is not critical - build will use regular disk storage"
fi
echo ""
fi
# Restore ccache if available
if [ -f ~/openwrt/ccache.tar.gz ] && command -v ccache &> /dev/null; then
echo "Restoring compiler cache..."
tar -xzf ~/openwrt/ccache.tar.gz -C ~/openwrt/ 2>/dev/null || true
CACHE_SIZE=$(du -sh "$CCACHE_DIR" 2>/dev/null | cut -f1)
echo "✓ Cache restored ($CACHE_SIZE)"
fi
make -j$(nproc) download || {
echo ""
echo "ERROR: Download failed. Please check your internet connection."
exit 1
}
echo ""
echo "[Build Step 2/2] Compiling firmware with $PARALLEL_JOBS parallel jobs..."
echo "This can take 30 minutes to 2 hours depending on your system..."
echo ""
echo "Build started at: $(date)"
BUILD_START=$(date +%s)
make -j$PARALLEL_JOBS || {
echo ""
echo "ERROR: Build failed. Try running with verbose mode to see details:"
echo " cd ~/openwrt/nss-base && make -j1 V=s"
exit 1
}
BUILD_END=$(date +%s)
BUILD_DURATION=$((BUILD_END - BUILD_START))
BUILD_MINUTES=$((BUILD_DURATION / 60))
BUILD_SECONDS=$((BUILD_DURATION % 60))
# Save ccache after successful build
if command -v ccache &> /dev/null && [ -d "$CCACHE_DIR" ]; then
echo ""
echo "Saving compiler cache for future builds..."
tar -czf ~/openwrt/ccache.tar.gz -C ~/openwrt .ccache 2>/dev/null || echo "Warning: Could not save cache"
if [ -f ~/openwrt/ccache.tar.gz ]; then
CACHE_ARCHIVE_SIZE=$(du -sh ~/openwrt/ccache.tar.gz | cut -f1)
echo "✓ Cache saved to ~/openwrt/ccache.tar.gz ($CACHE_ARCHIVE_SIZE)"
echo " This cache will be automatically restored on the next build"
fi
fi
# Remove build in progress marker
rm -f ~/openwrt/.build_in_progress
echo ""
echo "=== BUILD SUCCESSFUL ==="
echo "Build completed in ${BUILD_MINUTES}m ${BUILD_SECONDS}s"
# Show ccache stats if available
if command -v ccache &> /dev/null; then
echo ""
echo "ccache statistics:"
ccache -s | grep -E "(cache hit|cache miss|cache size)"
fi
if [ "$USE_CUSTOM_CONFIGS" = true ]; then
echo ""
echo "✓ Custom configurations included in firmware:"
ls -1 "$CONFIG_DEFAULTS_DIR" 2>/dev/null | sed 's/^/ - /'
fi
;;
esac
echo ""
echo "=========================================="
echo "Firmware built successfully!"
echo "=========================================="
echo ""
echo "Your firmware images are located at:"
echo " ~/openwrt/nss-base/bin/targets/qualcommax/ipq807x/"
echo ""
echo "Files to flash:"
ls -lh ~/openwrt/nss-base/bin/targets/qualcommax/ipq807x/*.bin 2>/dev/null || echo " (No .bin files found - check build output)"
echo ""
echo "Installation instructions:"
echo " 1. Copy the appropriate .bin file to your device"
echo " 2. Follow the flashing procedure for your specific device model"
echo " 3. For WRX36, typically use the factory or sysupgrade image"
echo ""
if [ "$USE_CUSTOM_CONFIGS" = true ]; then
echo "Your custom configurations are pre-applied in this firmware:"
ls -1 "$CONFIG_DEFAULTS_DIR" 2>/dev/null | sed 's/^/ - /'
echo ""
echo "These defaults will be active immediately after flashing."
echo ""
fi
echo "Build completed at: $(date)"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment