Rewrite the prepare scripts for current OpenWrt and more distros
prepare-openwrt-env.sh - Dispatch on the package manager instead of guessing from the distro version: apt, dnf/yum, pacman, zypper and apk are all supported. - Probe every package against the running release and skip the ones that no longer exist. Previously a single dropped package (on Ubuntu 26.04 arm64, gcc-multilib-s390x-linux-gnu) failed the whole apt command and set -e aborted the script, so nothing was installed at all. - Align the package lists with the official build system guide, adding libelf-dev, python3-dev, bc, xsltproc, zstd, u-boot-tools and others. - Make Go opt-in via --with-go rather than forced on arm64. - Add -y/--yes, -n/--dry-run and -h/--help; allow running as root. prepare-openwrt.sh - Split read-only discovery from mutation. Versions are resolved over git ls-remote before anything is moved, so aborting at the prompt leaves the helper checkout untouched. - Resume an interrupted first run instead of failing forever: a root with .git but no source tree was previously unrecoverable without a manual rm -rf. Also restore the worktree when HEAD already points at the target ref, where checkout is a no-op. - Detect the relocated layout by content rather than directory name, so renaming the root no longer triggers a second, nested relocation. - Replace the staged in-place relocation with a resumable content move, removing the window that could strand the checkout in a hidden dir. - Filter release candidates before sorting; sort -V orders v25.12.0-rc1 after v25.12.0, so the newest stable tag could be an rc. - Follow upstream: snapshots use main (master as fallback) and the dead -SNAPSHOT tag lookup is gone. - Use a partial clone (--filter=blob:none) by default. - Guard version switches on a dirty tree and back up .config first. - Add /helper/ to .git/info/exclude and warn that git clean -xdff still deletes it, since -x bypasses ignore rules by design. - Leave a symlink at the old checkout path so shells and editors whose working directory still points there keep working. - Add --stable/--branch/--snapshot plus -y, -n, --force, --full-clone, --allow-rc, --root, --skip-feeds, --skip-defconfig, --repo-url and --no-compat-link. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
46
README.md
46
README.md
@@ -5,14 +5,23 @@ This repository contains shell scripts that streamline preparing, configuring, a
|
||||
|
||||
## What’s included
|
||||
- prepare-openwrt-env.sh
|
||||
- Installs required build dependencies via apt on Ubuntu 22.04/24.04/26.04 and Debian 12/13+.
|
||||
- Handles x86_64 and ARM64 differences (Python/distutils, multilib notes, Go on ARM64).
|
||||
- Installs the build dependencies listed by the official OpenWrt build system guide.
|
||||
- Supports apt (Debian/Ubuntu/Mint), dnf/yum (Fedora/RHEL/Rocky/Alma), pacman (Arch/Manjaro), zypper (openSUSE) and apk (Alpine).
|
||||
- Probes each package against the running release and skips the ones that no longer exist, so a renamed or dropped package cannot abort the whole install.
|
||||
- Handles x86_64 and ARM64 differences (native vs. cross multilib).
|
||||
- Options: `-y/--yes` (no prompt), `-n/--dry-run` (only print), `--with-go` (also install the Go toolchain).
|
||||
- prepare-openwrt.sh
|
||||
- Clones or updates the OpenWrt source repo in the top-level `openwrt/` root.
|
||||
- Lets you select Stable, Beta, or Snapshot versions interactively.
|
||||
- Lets you select a stable tag, a release branch, or the snapshot (`main`) interactively, or non-interactively via flags.
|
||||
- Uses the script location as the source of truth, so running it from another current working directory is supported.
|
||||
- On first run from a helper checkout, relocates that checkout to `openwrt/helper/`.
|
||||
- On first run from a helper checkout, relocates that checkout to `openwrt/helper/` and leaves a symlink behind at the old path.
|
||||
- Prints a plan and asks for confirmation; nothing on disk is touched before you confirm.
|
||||
- Uses a partial clone (`--filter=blob:none`) by default, so the first fetch is far smaller than full history.
|
||||
- Resumes automatically if a previous run was interrupted.
|
||||
- Updates feeds and runs make defconfig.
|
||||
- Options: `--stable [<ver>]`, `--branch <name>`, `--snapshot`, `-y/--yes`, `-n/--dry-run`,
|
||||
`-f/--force`, `--full-clone`, `--allow-rc`, `--root <dir>`, `--skip-feeds`,
|
||||
`--skip-defconfig`, `--repo-url <url>`, `--no-compat-link`, `-h/--help`.
|
||||
- add-external-repos.sh
|
||||
- Clones or updates additional package repositories into package/.
|
||||
- Currently includes luci-app-netspeedtest and luci-app-easytier (adjust REPOS as needed).
|
||||
@@ -30,20 +39,24 @@ This repository contains shell scripts that streamline preparing, configuring, a
|
||||
- Fixes MAX macro naming collisions in multiple DAHDI modules for OpenWrt 24.10.4 builds.
|
||||
|
||||
## System requirements
|
||||
- OS: Ubuntu 22.04/24.04/26.04 or Debian 12/13+ (others may work with adjustments)
|
||||
- OS: Debian/Ubuntu, Fedora/RHEL, Arch, openSUSE or Alpine (the other scripts are developed and tested on Debian/Ubuntu)
|
||||
- Architectures: x86_64/amd64 and aarch64/arm64
|
||||
- Tools: git, wget, curl, bash
|
||||
- Internet access for feeds and package downloads
|
||||
- Optional: Go (required by some OpenWrt packages; auto-configured on ARM64 by prepare-openwrt-env.sh; configurable via update-go-path.sh)
|
||||
- Optional: Go (required by some OpenWrt packages; install it with `./prepare-openwrt-env.sh --with-go`; configurable via update-go-path.sh)
|
||||
- Note: with the default partial clone, switching to another tag or branch later fetches missing blobs on demand and therefore needs network access
|
||||
|
||||
## Quick start
|
||||
1) Prepare the host machine
|
||||
- Run: ./prepare-openwrt-env.sh
|
||||
- This installs compilers, headers, Python tooling, and other build prerequisites.
|
||||
- Preview without touching the system: ./prepare-openwrt-env.sh -n
|
||||
|
||||
2) Get OpenWrt sources
|
||||
- Run: ./prepare-openwrt.sh
|
||||
- Choose Stable, Beta, or Snapshot.
|
||||
- Choose a stable tag, a release branch, or the snapshot.
|
||||
- Non-interactive: ./prepare-openwrt.sh --stable 25.12.5 -y
|
||||
- Preview only, changes nothing: ./prepare-openwrt.sh --stable -n
|
||||
- The script:
|
||||
- Reuses or creates the top-level OpenWrt root at `./openwrt`.
|
||||
- Moves this helper checkout to `./openwrt/helper` on first run.
|
||||
@@ -120,11 +133,26 @@ This repository contains shell scripts that streamline preparing, configuring, a
|
||||
- Reuse or create `<parent>/openwrt/` as the OpenWrt source root.
|
||||
- Move the entire helper checkout, including its `.git`, to `<parent>/openwrt/helper/`.
|
||||
- Initialize or update the OpenWrt source tree directly in `<parent>/openwrt/`.
|
||||
- If you later rerun `openwrt/helper/prepare-openwrt.sh`, it reuses the parent `openwrt/` directory and does not move directories again.
|
||||
- Leave a symlink at the original checkout path pointing to `<parent>/openwrt/helper/`, so shells, editors and agent sessions whose working directory is still the old path keep working. Disable with `--no-compat-link`.
|
||||
- If you later rerun `prepare-openwrt.sh` — from `openwrt/helper/` or through the symlink at the old path — it reuses the parent `openwrt/` directory and does not move anything again.
|
||||
- The already-relocated layout is detected by content (the OpenWrt tree or its `origin` remote), not by directory name, so renaming `openwrt/` to something else does not trigger a second relocation.
|
||||
- If a run is interrupted after the repository was created but before the source tree was checked out, the next run detects that state, reports `resuming it`, and completes. No manual cleanup is needed.
|
||||
- If the script is already located in a real OpenWrt source root, it treats that directory as the source root and does not relocate it just because the directory name is `openwrt`.
|
||||
- Use `--root <dir>` to point at a different OpenWrt root in any ambiguous situation.
|
||||
|
||||
### Known hazard: `git clean -xdff`
|
||||
`helper/` lives inside the OpenWrt Git worktree but is not tracked by it. The script
|
||||
adds `/helper/` to `openwrt/.git/info/exclude`, which keeps `git status` clean and stops
|
||||
`git add -A` from staging it — but that does **not** protect it from `git clean -xdff`:
|
||||
`-x` deliberately includes ignored files and `-ff` removes Git's refusal to recurse into
|
||||
a nested repository. Running `git clean -xdff` in the OpenWrt root will delete the helper
|
||||
checkout including its `.git`. Use this instead:
|
||||
|
||||
git clean -xdf -e /helper
|
||||
|
||||
## Security and safety
|
||||
- Scripts use set -e to stop on errors.
|
||||
- Scripts use set -euo pipefail to stop on errors.
|
||||
- prepare-openwrt.sh backs up `.config` to `.config.<previous-ref>.bak` before switching versions, and refuses to switch a tree with modified tracked files unless you pass --force.
|
||||
- They modify .config and write under package/ and feeds/ inside your OpenWrt tree.
|
||||
- Backup your .config if you need a known baseline.
|
||||
|
||||
|
||||
@@ -1,154 +1,370 @@
|
||||
#!/bin/bash
|
||||
# Automatically prepare OpenWRT build dependencies for Debian/Ubuntu
|
||||
# Supports both x86_64 and arm64
|
||||
# Detects Ubuntu 22.04, 24.04, 26.04, Debian 12/13 and newer
|
||||
# Prepare the OpenWrt build dependencies.
|
||||
#
|
||||
# Supported distributions:
|
||||
# - Debian / Ubuntu / Linux Mint / Raspberry Pi OS (apt)
|
||||
# - Fedora / RHEL / CentOS / Rocky / AlmaLinux (dnf, yum)
|
||||
# - Arch / Manjaro / EndeavourOS (pacman)
|
||||
# - openSUSE / SLES (zypper)
|
||||
# - Alpine (apk)
|
||||
#
|
||||
# Package lists follow https://openwrt.org/docs/guide-developer/toolchain/install-buildsystem
|
||||
# Packages that do not exist on the running release are skipped instead of
|
||||
# aborting the whole installation.
|
||||
#
|
||||
# Usage: ./prepare-openwrt-env.sh [-y] [-n] [--with-go]
|
||||
# -y, --yes do not ask for confirmation
|
||||
# -n, --dry-run only print what would be installed
|
||||
# --with-go also install the Go toolchain
|
||||
#
|
||||
# Author: Zhe Yuan
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
umask 022
|
||||
|
||||
ASSUME_YES=false
|
||||
DRY_RUN=false
|
||||
WITH_GO=false
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-y|--yes) ASSUME_YES=true ;;
|
||||
-n|--dry-run) DRY_RUN=true ;;
|
||||
--with-go) WITH_GO=true ;;
|
||||
-h|--help)
|
||||
sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "[ERROR] Unknown option: $1" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
echo "========================================"
|
||||
echo " OpenWRT Build Environment Preparation"
|
||||
echo " OpenWrt Build Environment Preparation"
|
||||
echo "========================================"
|
||||
|
||||
# --- Detect architecture ---
|
||||
ARCH=$(uname -m)
|
||||
echo "[INFO] Detected architecture: $ARCH"
|
||||
ARCH="$(uname -m)"
|
||||
echo "[INFO] Architecture: $ARCH"
|
||||
|
||||
# --- Detect OS version ---
|
||||
if [ -f /etc/os-release ]; then
|
||||
# --- Detect distribution ---
|
||||
DISTRO="unknown"
|
||||
DISTRO_LIKE=""
|
||||
VERSION_ID="unknown"
|
||||
PRETTY_NAME="unknown"
|
||||
|
||||
if [ -r /etc/os-release ]; then
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/os-release
|
||||
DISTRO="$ID"
|
||||
DISTRO="${ID:-unknown}"
|
||||
DISTRO_LIKE="${ID_LIKE:-}"
|
||||
VERSION_ID="${VERSION_ID:-unknown}"
|
||||
PRETTY_NAME="${PRETTY_NAME:-$DISTRO $VERSION_ID}"
|
||||
else
|
||||
echo "[ERROR] Cannot detect system version (no /etc/os-release)"
|
||||
echo "[ERROR] Cannot detect the distribution (no /etc/os-release)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[INFO] Detected distribution: $DISTRO $VERSION_ID"
|
||||
echo "[INFO] Distribution: $PRETTY_NAME (id=$DISTRO)"
|
||||
|
||||
# --- Version helpers ---
|
||||
version_ge() {
|
||||
local current="${1:-unknown}"
|
||||
local minimum="$2"
|
||||
|
||||
if [[ "$current" == "unknown" ]]; then
|
||||
return 1
|
||||
# --- Detect package manager ---
|
||||
PKG_MGR=""
|
||||
for candidate in apt-get dnf yum pacman zypper apk; do
|
||||
if command -v "$candidate" >/dev/null 2>&1; then
|
||||
PKG_MGR="$candidate"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if command -v dpkg >/dev/null 2>&1; then
|
||||
dpkg --compare-versions "$current" ge "$minimum"
|
||||
if [ -z "$PKG_MGR" ]; then
|
||||
echo "[ERROR] No supported package manager found." >&2
|
||||
echo "[ERROR] Supported: apt-get, dnf, yum, pacman, zypper, apk." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[INFO] Package manager: $PKG_MGR"
|
||||
|
||||
# --- Privilege escalation ---
|
||||
SUDO=""
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
if command -v sudo >/dev/null 2>&1; then
|
||||
SUDO="sudo"
|
||||
else
|
||||
[[ "$(printf '%s\n%s\n' "$minimum" "$current" | sort -V | head -n1)" == "$minimum" ]]
|
||||
echo "[ERROR] Not running as root and 'sudo' is not available." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
is_x86_64() {
|
||||
[ "$ARCH" = "x86_64" ] || [ "$ARCH" = "amd64" ]
|
||||
}
|
||||
|
||||
IS_UBUNTU_24_OR_NEWER=false
|
||||
IS_UBUNTU_26_OR_NEWER=false
|
||||
IS_DEBIAN_13_OR_NEWER=false
|
||||
is_arm64() {
|
||||
[ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]
|
||||
}
|
||||
|
||||
if [[ "$DISTRO" == "ubuntu" ]] && version_ge "$VERSION_ID" "24.04"; then
|
||||
IS_UBUNTU_24_OR_NEWER=true
|
||||
fi
|
||||
# ---------------------------------------------------------------------------
|
||||
# Package lists
|
||||
#
|
||||
# REQUIRED_PACKAGES installation fails if one of them cannot be installed
|
||||
# OPTIONAL_PACKAGES nice to have; silently skipped when unavailable
|
||||
# ---------------------------------------------------------------------------
|
||||
REQUIRED_PACKAGES=""
|
||||
OPTIONAL_PACKAGES=""
|
||||
REFRESH_CMD=""
|
||||
INSTALL_CMD=""
|
||||
|
||||
if [[ "$DISTRO" == "ubuntu" ]] && version_ge "$VERSION_ID" "26.04"; then
|
||||
IS_UBUNTU_26_OR_NEWER=true
|
||||
fi
|
||||
case "$PKG_MGR" in
|
||||
apt-get)
|
||||
REFRESH_CMD="$SUDO apt-get update"
|
||||
INSTALL_CMD="$SUDO apt-get install -y --no-install-recommends"
|
||||
|
||||
if [[ "$DISTRO" == "debian" ]] && version_ge "$VERSION_ID" "13"; then
|
||||
IS_DEBIAN_13_OR_NEWER=true
|
||||
fi
|
||||
REQUIRED_PACKAGES="build-essential clang flex bison g++ gawk gcc gettext git \
|
||||
file wget unzip rsync swig time python3 python3-dev python3-setuptools \
|
||||
libncurses-dev libssl-dev zlib1g-dev libelf-dev make patch diffutils"
|
||||
|
||||
# --- Base packages (common to all) ---
|
||||
COMMON_PACKAGES="build-essential clang flex bison g++ gawk \
|
||||
gettext git libssl-dev rsync swig unzip zlib1g-dev file wget bzip2"
|
||||
# Extras from the OpenWrt 25.xx / Debian Trixie list. Names come and go
|
||||
# between releases, so everything here is filtered before installing.
|
||||
OPTIONAL_PACKAGES="bc binutils-gold ccache ecj fastjar help2man libbsd-dev \
|
||||
liblzma-dev meson mold mtd-utils ninja-build pbzip2 pigz pkg-config \
|
||||
subversion texinfo u-boot-tools xsltproc xxd zstd bzip2 quilt asciidoc \
|
||||
device-tree-compiler java-propose-classpath python3-distutils \
|
||||
python3-distutils-extra libncurses5-dev"
|
||||
|
||||
# --- Determine specific package set ---
|
||||
if [[ "$ARCH" == "x86_64" || "$ARCH" == "amd64" ]]; then
|
||||
echo "[INFO] Preparing environment for x86_64."
|
||||
|
||||
if [[ "$IS_UBUNTU_26_OR_NEWER" == "true" ]]; then
|
||||
echo "[INFO] Detected Ubuntu 26.04+ (no python3-distutils; OpenWrt docs use libncurses-dev)."
|
||||
EXTRA_PACKAGES="gcc-multilib g++-multilib glibc-source libncurses-dev python3-setuptools"
|
||||
elif [[ "$IS_UBUNTU_24_OR_NEWER" == "true" ]]; then
|
||||
echo "[INFO] Detected Ubuntu 24.04+ (Python 3.12+, no python3-distutils)."
|
||||
EXTRA_PACKAGES="gcc-multilib g++-multilib libncurses5-dev python3-setuptools"
|
||||
elif [[ "$IS_DEBIAN_13_OR_NEWER" == "true" ]]; then
|
||||
echo "[INFO] Detected Debian 13+ (no python3-distutils)."
|
||||
EXTRA_PACKAGES="gcc-multilib g++-multilib libncurses-dev python3-setuptools"
|
||||
else
|
||||
echo "[INFO] Detected older Ubuntu/Debian (with python3-distutils)."
|
||||
EXTRA_PACKAGES="gcc-multilib g++-multilib libncurses-dev python3-distutils python3-setuptools"
|
||||
if is_x86_64; then
|
||||
OPTIONAL_PACKAGES="$OPTIONAL_PACKAGES gcc-multilib g++-multilib glibc-source"
|
||||
elif is_arm64; then
|
||||
# arm64 has no native multilib; the cross variants are optional and the
|
||||
# available set differs a lot between releases (e.g. the s390x variants
|
||||
# were dropped in Ubuntu 26.04).
|
||||
OPTIONAL_PACKAGES="$OPTIONAL_PACKAGES \
|
||||
gcc-multilib-i686-linux-gnu g++-multilib-i686-linux-gnu \
|
||||
gcc-multilib-x86-64-linux-gnu g++-multilib-x86-64-linux-gnu \
|
||||
gcc-multilib-x86-64-linux-gnux32 g++-multilib-x86-64-linux-gnux32 \
|
||||
gcc-multilib-s390x-linux-gnu g++-multilib-s390x-linux-gnu \
|
||||
libc6-dev-i386-cross libc6-dev-i386-amd64-cross libc6-dev-i386-x32-cross \
|
||||
glibc-source"
|
||||
fi
|
||||
|
||||
INSTALL_PACKAGES="$COMMON_PACKAGES $EXTRA_PACKAGES"
|
||||
|
||||
elif [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then
|
||||
echo "[INFO] Preparing environment for ARM64."
|
||||
|
||||
# Note: arm64 has no native multilib; install cross multilib packages
|
||||
MULTILIB_PACKAGES="
|
||||
gcc-multilib-i686-linux-gnu gcc-multilib-s390x-linux-gnu \
|
||||
gcc-multilib-x86-64-linux-gnu gcc-multilib-x86-64-linux-gnux32 \
|
||||
g++-multilib-i686-linux-gnu g++-multilib-s390x-linux-gnu \
|
||||
g++-multilib-x86-64-linux-gnu g++-multilib-x86-64-linux-gnux32 \
|
||||
libc6-dev-i386-amd64-cross libc6-dev-i386-cross libc6-dev-i386-x32-cross"
|
||||
|
||||
if [[ "$IS_UBUNTU_26_OR_NEWER" == "true" ]]; then
|
||||
EXTRA_PACKAGES="glibc-source libncurses-dev python3-setuptools"
|
||||
elif [[ "$IS_UBUNTU_24_OR_NEWER" == "true" ]]; then
|
||||
EXTRA_PACKAGES="libncurses5-dev python3-setuptools"
|
||||
elif [[ "$IS_DEBIAN_13_OR_NEWER" == "true" ]]; then
|
||||
EXTRA_PACKAGES="libncurses-dev python3-setuptools"
|
||||
else
|
||||
EXTRA_PACKAGES="libncurses-dev python3-distutils python3-setuptools"
|
||||
if [ "$WITH_GO" = true ]; then
|
||||
OPTIONAL_PACKAGES="$OPTIONAL_PACKAGES golang golang-go"
|
||||
fi
|
||||
;;
|
||||
|
||||
INSTALL_PACKAGES="$COMMON_PACKAGES $EXTRA_PACKAGES $MULTILIB_PACKAGES golang"
|
||||
dnf|yum)
|
||||
REFRESH_CMD="$SUDO $PKG_MGR makecache"
|
||||
INSTALL_CMD="$SUDO $PKG_MGR install -y --setopt=install_weak_deps=False"
|
||||
|
||||
REQUIRED_PACKAGES="gcc gcc-c++ make git-core patch diffutils file wget \
|
||||
unzip rsync tar which bzip2 ncurses-devel openssl-devel zlib-devel \
|
||||
python3 python3-devel python3-setuptools"
|
||||
|
||||
OPTIONAL_PACKAGES="bash-completion elfutils-libelf-devel zlib-static \
|
||||
glibc-static swig quilt ccache perl-base perl-Data-Dumper \
|
||||
perl-File-Compare perl-File-Copy perl-FindBin perl-IPC-Cmd perl-JSON-PP \
|
||||
perl-lib perl-Thread-Queue perl-Time-Piece libxslt bc texinfo \
|
||||
dtc zstd pkgconf-pkg-config"
|
||||
|
||||
if [ "$WITH_GO" = true ]; then
|
||||
OPTIONAL_PACKAGES="$OPTIONAL_PACKAGES golang"
|
||||
fi
|
||||
;;
|
||||
|
||||
pacman)
|
||||
REFRESH_CMD="$SUDO pacman -Sy"
|
||||
INSTALL_CMD="$SUDO pacman -S --needed --noconfirm"
|
||||
|
||||
REQUIRED_PACKAGES="base-devel bash bzip2 git libelf libxslt ncurses openssl \
|
||||
rsync swig time unzip util-linux wget which zlib python python-setuptools"
|
||||
|
||||
OPTIONAL_PACKAGES="ccache quilt pkgconf diffutils patch tar make gawk \
|
||||
subversion asciidoc dtc zstd"
|
||||
|
||||
if [ "$WITH_GO" = true ]; then
|
||||
OPTIONAL_PACKAGES="$OPTIONAL_PACKAGES go"
|
||||
fi
|
||||
;;
|
||||
|
||||
zypper)
|
||||
REFRESH_CMD="$SUDO zypper --non-interactive refresh"
|
||||
INSTALL_CMD="$SUDO zypper --non-interactive install --no-recommends"
|
||||
|
||||
REQUIRED_PACKAGES="bash bc binutils bzip2 flex gawk gcc gcc-c++ \
|
||||
gettext-tools git-core make ncurses-devel patch rsync unzip util-linux \
|
||||
wget zlib-devel libopenssl-devel python3-devel python3-setuptools"
|
||||
|
||||
OPTIONAL_PACKAGES="asciidoc fastjar intltool libxslt-tools mercurial \
|
||||
perl-ExtUtils-MakeMaker sdcc quilt ccache libelf-devel swig zstd dtc"
|
||||
|
||||
if [ "$WITH_GO" = true ]; then
|
||||
OPTIONAL_PACKAGES="$OPTIONAL_PACKAGES go"
|
||||
fi
|
||||
;;
|
||||
|
||||
apk)
|
||||
REFRESH_CMD="$SUDO apk update"
|
||||
INSTALL_CMD="$SUDO apk add"
|
||||
|
||||
REQUIRED_PACKAGES="argp-standalone bash bc binutils bzip2 coreutils \
|
||||
diffutils elfutils-dev findutils flex g++ gawk gcc gettext git grep gzip \
|
||||
linux-headers make ncurses-dev openssl-dev patch perl python3-dev rsync \
|
||||
tar unzip util-linux wget zlib-dev"
|
||||
|
||||
OPTIONAL_PACKAGES="asciidoc cdrkit intltool libxslt musl-fts-dev \
|
||||
musl-libintl musl-obstack-dev swig quilt ccache zstd"
|
||||
|
||||
if [ "$WITH_GO" = true ]; then
|
||||
OPTIONAL_PACKAGES="$OPTIONAL_PACKAGES go"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Availability filtering
|
||||
# ---------------------------------------------------------------------------
|
||||
pkg_available() {
|
||||
local pkg="$1"
|
||||
|
||||
case "$PKG_MGR" in
|
||||
apt-get)
|
||||
# apt-cache policy prints no "Candidate:" line for purely virtual names
|
||||
# and "(none)" when no installable version exists in the repositories.
|
||||
local policy=""
|
||||
policy="$(apt-cache policy "$pkg" 2>/dev/null || true)"
|
||||
case "$policy" in
|
||||
*"Candidate: (none)"*) return 1 ;;
|
||||
*"Candidate:"*) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
;;
|
||||
dnf) dnf -q info "$pkg" >/dev/null 2>&1 ;;
|
||||
yum) yum -q info "$pkg" >/dev/null 2>&1 ;;
|
||||
pacman) pacman -Si "$pkg" >/dev/null 2>&1 || pacman -Sg "$pkg" >/dev/null 2>&1 ;;
|
||||
zypper) zypper --non-interactive --quiet search --match-exact "$pkg" >/dev/null 2>&1 ;;
|
||||
apk) [ -n "$(apk search -x "$pkg" 2>/dev/null)" ] ;;
|
||||
*) return 0 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
filter_available() {
|
||||
local pkg
|
||||
local kept=""
|
||||
local dropped=""
|
||||
|
||||
for pkg in $1; do
|
||||
if pkg_available "$pkg"; then
|
||||
kept="$kept $pkg"
|
||||
else
|
||||
dropped="$dropped $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
FILTER_KEPT="${kept# }"
|
||||
FILTER_DROPPED="${dropped# }"
|
||||
}
|
||||
|
||||
echo
|
||||
echo "[INFO] Refreshing package metadata..."
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
echo "[DRY-RUN] $REFRESH_CMD"
|
||||
else
|
||||
echo "[WARN] Unknown architecture: $ARCH"
|
||||
echo "[WARN] Attempting to use x86_64 package list."
|
||||
if [[ "$IS_UBUNTU_26_OR_NEWER" == "true" ]]; then
|
||||
INSTALL_PACKAGES="$COMMON_PACKAGES gcc-multilib g++-multilib glibc-source libncurses-dev python3-setuptools"
|
||||
else
|
||||
INSTALL_PACKAGES="$COMMON_PACKAGES gcc-multilib g++-multilib libncurses-dev python3-setuptools"
|
||||
fi
|
||||
$REFRESH_CMD
|
||||
fi
|
||||
|
||||
echo "[INFO] Checking package availability for this release..."
|
||||
|
||||
filter_available "$REQUIRED_PACKAGES"
|
||||
REQUIRED_AVAILABLE="$FILTER_KEPT"
|
||||
REQUIRED_MISSING="$FILTER_DROPPED"
|
||||
|
||||
filter_available "$OPTIONAL_PACKAGES"
|
||||
OPTIONAL_AVAILABLE="$FILTER_KEPT"
|
||||
OPTIONAL_MISSING="$FILTER_DROPPED"
|
||||
|
||||
INSTALL_PACKAGES="$REQUIRED_AVAILABLE $OPTIONAL_AVAILABLE"
|
||||
INSTALL_PACKAGES="$(echo "$INSTALL_PACKAGES" | tr -s '[:space:]' ' ' | sed 's/^ //;s/ $//')"
|
||||
|
||||
if [ -z "$INSTALL_PACKAGES" ]; then
|
||||
echo "[ERROR] No installable package found. Are the repositories configured?" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Display package list ---
|
||||
echo
|
||||
echo "========================================"
|
||||
echo "📦 Packages to install:"
|
||||
echo "$INSTALL_PACKAGES"
|
||||
echo "$INSTALL_PACKAGES" | tr ' ' '\n' | sed 's/^/ /'
|
||||
echo "========================================"
|
||||
echo
|
||||
|
||||
echo "[INFO] Updating APT repositories..."
|
||||
sudo apt update -y
|
||||
if [ -n "$REQUIRED_MISSING" ]; then
|
||||
echo
|
||||
echo "[WARN] Required packages not offered by this release (build may fail):"
|
||||
echo " $REQUIRED_MISSING"
|
||||
fi
|
||||
|
||||
echo "[INFO] Installing packages..."
|
||||
sudo apt install -y $INSTALL_PACKAGES
|
||||
if [ -n "$OPTIONAL_MISSING" ]; then
|
||||
echo
|
||||
echo "[INFO] Optional packages unavailable here, skipped:"
|
||||
echo " $OPTIONAL_MISSING"
|
||||
fi
|
||||
|
||||
# --- Post installation notice ---
|
||||
echo
|
||||
echo "========================================"
|
||||
echo "✅ OpenWRT build environment setup complete!"
|
||||
echo "========================================"
|
||||
echo
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
echo
|
||||
echo "[DRY-RUN] $INSTALL_CMD $INSTALL_PACKAGES"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$ARCH" == "x86_64" || "$ARCH" == "amd64" ]]; then
|
||||
echo "👉 [NOTE] Go language is optional on x86_64."
|
||||
echo " If you plan to compile packages requiring Go (e.g. firewall4, netifd), install it manually:"
|
||||
echo " sudo apt install golang -y"
|
||||
else
|
||||
echo "👉 [INFO] Go language installed for ARM64 cross compilation."
|
||||
if [ "$ASSUME_YES" != true ]; then
|
||||
echo
|
||||
read -r -p "Proceed with installation? [Y/n]: " reply
|
||||
case "$reply" in
|
||||
[nN]|[nN][oO]) echo "[INFO] Aborted by user."; exit 0 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "⚙️ After running 'make menuconfig', set Go toolchain path if required:"
|
||||
echo " Example: /usr/lib/go-1.18"
|
||||
echo "[INFO] Installing packages..."
|
||||
|
||||
FAILED_PACKAGES=""
|
||||
if ! $INSTALL_CMD $INSTALL_PACKAGES; then
|
||||
echo
|
||||
echo "[WARN] Bulk installation failed. Retrying package by package..."
|
||||
for pkg in $INSTALL_PACKAGES; do
|
||||
if ! $INSTALL_CMD "$pkg" >/dev/null 2>&1; then
|
||||
FAILED_PACKAGES="$FAILED_PACKAGES $pkg"
|
||||
echo " [FAIL] $pkg"
|
||||
fi
|
||||
done
|
||||
FAILED_PACKAGES="${FAILED_PACKAGES# }"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "========================================"
|
||||
if [ -n "$FAILED_PACKAGES" ]; then
|
||||
echo "⚠️ Setup finished with errors."
|
||||
echo " Failed packages: $FAILED_PACKAGES"
|
||||
else
|
||||
echo "✅ OpenWrt build environment setup complete!"
|
||||
fi
|
||||
echo "========================================"
|
||||
echo
|
||||
|
||||
if [ "$WITH_GO" != true ]; then
|
||||
echo "👉 [NOTE] The Go toolchain is only needed for Go based packages"
|
||||
echo " (e.g. xray-core, v2ray). Install it with:"
|
||||
echo " ./prepare-openwrt-env.sh --with-go"
|
||||
echo
|
||||
fi
|
||||
|
||||
if is_arm64; then
|
||||
echo "👉 [NOTE] arm64 has no native multilib. The cross-multilib packages are"
|
||||
echo " optional and only needed for x86 targets; missing ones were skipped."
|
||||
echo
|
||||
fi
|
||||
|
||||
echo "👉 Next step:"
|
||||
echo " ./prepare-openwrt.sh # to clone and set up OpenWRT source"
|
||||
echo " ./prepare-openwrt.sh # clone and set up the OpenWrt source"
|
||||
echo
|
||||
|
||||
1211
prepare-openwrt.sh
1211
prepare-openwrt.sh
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user