163 lines
4.0 KiB
Bash
Executable File
163 lines
4.0 KiB
Bash
Executable File
#!/bin/bash
|
||
# Add specified OpenWRT packages (from a text file) to .config without removing existing ones
|
||
# Author: Zhe Yuan
|
||
# Usage:
|
||
# ./add-openwrt-packages.sh packages.txt
|
||
# Description:
|
||
# - Reads package names from a text file (supports both newline or space separation)
|
||
# - Supports ##built-in and ##module sections to control build mode (=y or =m)
|
||
# - Packages default to built-in (=y) if no section header is specified
|
||
# - Adds missing CONFIG_PACKAGE_xxx entries to .config
|
||
# - Keeps existing settings intact
|
||
# - Reports missing packages
|
||
# - Runs make defconfig at the end to sync dependencies
|
||
|
||
set -e
|
||
umask 022
|
||
|
||
# Check argument
|
||
if [ "$#" -ne 1 ]; then
|
||
echo "❌ Usage: $0 <package_list.txt>"
|
||
exit 1
|
||
fi
|
||
|
||
PKG_FILE="$1"
|
||
|
||
# Verify file exists
|
||
if [ ! -f "$PKG_FILE" ]; then
|
||
echo "❌ Error: File not found: $PKG_FILE"
|
||
exit 1
|
||
fi
|
||
|
||
# Verify we are in OpenWRT source root
|
||
if [ ! -d "package" ] || [ ! -f "Makefile" ]; then
|
||
echo "❌ Error: Please run this script in the OpenWRT source root directory."
|
||
exit 1
|
||
fi
|
||
|
||
# Ensure .config exists
|
||
if [ ! -f ".config" ]; then
|
||
echo "⚙️ Generating initial .config..."
|
||
make defconfig
|
||
fi
|
||
|
||
PACKAGE_INDEX="tmp/.config-package.in"
|
||
PACKAGE_INFO="tmp/.packageinfo"
|
||
|
||
# Ensure package metadata exists for reliable package name lookups.
|
||
if [ ! -f "$PACKAGE_INDEX" ] && [ ! -f "$PACKAGE_INFO" ]; then
|
||
echo "⚙️ Generating package metadata..."
|
||
make defconfig >/dev/null
|
||
fi
|
||
|
||
is_already_builtin() {
|
||
local pkg="$1"
|
||
|
||
awk -v package_y="CONFIG_PACKAGE_${pkg}=y" \
|
||
-v default_y="CONFIG_DEFAULT_${pkg}=y" \
|
||
'$0 == package_y || $0 == default_y { found=1; exit }
|
||
END { exit !found }' .config
|
||
}
|
||
|
||
is_module() {
|
||
local pkg="$1"
|
||
|
||
grep -qx "CONFIG_PACKAGE_${pkg}=m" .config
|
||
}
|
||
|
||
package_exists() {
|
||
local pkg="$1"
|
||
|
||
if [ -f "$PACKAGE_INDEX" ] &&
|
||
awk -v key="PACKAGE_${pkg}" '$1 == "config" && $2 == key { found=1; exit }
|
||
END { exit !found }' "$PACKAGE_INDEX"; then
|
||
return 0
|
||
fi
|
||
|
||
if [ -f "$PACKAGE_INFO" ] && grep -Fqx "Package: $pkg" "$PACKAGE_INFO"; then
|
||
return 0
|
||
fi
|
||
|
||
return 1
|
||
}
|
||
|
||
echo "📦 Reading packages from $PKG_FILE ..."
|
||
|
||
# Parse the file into "package:mode" pairs, respecting ##built-in / ##module sections.
|
||
# Default mode is "y" (built-in). Inline comments (#xxx but not ##) are stripped.
|
||
ENTRIES=$(awk '
|
||
BEGIN { mode = "y" }
|
||
/^##built-in/ { mode = "y"; next }
|
||
/^##module/ { mode = "m"; next }
|
||
{
|
||
sub(/#[^#].*/, "") # strip inline comments (single #), preserve ## headers
|
||
for (i = 1; i <= NF; i++) print $i ":" mode
|
||
}
|
||
' "$PKG_FILE")
|
||
|
||
ADDED=()
|
||
UPGRADED=()
|
||
MISSING=()
|
||
|
||
for entry in $ENTRIES; do
|
||
pkg="${entry%:*}"
|
||
mode="${entry##*:}"
|
||
CONFIG_NAME="CONFIG_PACKAGE_${pkg}"
|
||
|
||
if [ "$mode" = "y" ]; then
|
||
# --- built-in mode ---
|
||
if is_already_builtin "$pkg"; then
|
||
echo "✅ Already built-in: $pkg"
|
||
continue
|
||
fi
|
||
|
||
if is_module "$pkg"; then
|
||
sed -i "s/^CONFIG_PACKAGE_${pkg}=m$/CONFIG_PACKAGE_${pkg}=y/" .config
|
||
UPGRADED+=("$pkg")
|
||
echo "⬆️ Module → built-in: $pkg"
|
||
continue
|
||
fi
|
||
else
|
||
# --- module mode ---
|
||
if is_module "$pkg"; then
|
||
echo "✅ Already module: $pkg"
|
||
continue
|
||
fi
|
||
|
||
if is_already_builtin "$pkg"; then
|
||
echo "✅ Already built-in (keeping): $pkg"
|
||
continue
|
||
fi
|
||
fi
|
||
|
||
# Check if package exists in OpenWrt package metadata.
|
||
if ! package_exists "$pkg"; then
|
||
echo "⚠️ Package not found: $pkg"
|
||
MISSING+=("$pkg")
|
||
continue
|
||
fi
|
||
|
||
# Append package config
|
||
echo "${CONFIG_NAME}=${mode}" >> .config
|
||
ADDED+=("$pkg (=${mode})")
|
||
echo "➕ Added: $pkg (=${mode})"
|
||
done
|
||
|
||
# Run defconfig to sync dependencies
|
||
echo
|
||
echo "⚙️ Running make defconfig..."
|
||
make defconfig >/dev/null
|
||
|
||
echo
|
||
echo "✅ Done!"
|
||
echo "📋 Packages newly added: ${#ADDED[@]}"
|
||
[ ${#ADDED[@]} -gt 0 ] && echo " → ${ADDED[*]}"
|
||
echo "📋 Packages upgraded to built-in: ${#UPGRADED[@]}"
|
||
[ ${#UPGRADED[@]} -gt 0 ] && echo " → ${UPGRADED[*]}"
|
||
if [ ${#MISSING[@]} -gt 0 ]; then
|
||
echo "⚠️ Packages not found (check feeds or spelling):"
|
||
for m in "${MISSING[@]}"; do
|
||
echo " - $m"
|
||
done
|
||
fi
|