Files
openwrt-build-helper/prepare-openwrt.sh

342 lines
8.8 KiB
Bash
Executable File

#!/bin/bash
# Automatically prepare OpenWRT build environment.
# - Clone or update repository
# - Support selecting release/beta/snapshot versions
# - Normalize helper checkout into openwrt/helper
# - Update and install feeds
# - Prepare .config for build
set -e
umask 022
REPO_URL="https://github.com/openwrt/openwrt.git"
SCRIPT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)/$(basename "${BASH_SOURCE[0]}")"
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
WORK_ROOT=""
HELPER_DIR=""
echo "========================================"
echo " OpenWRT Build Environment Setup Script"
echo "========================================"
# --- Helpers ---
is_openwrt_repo() {
local dir="$1"
[ -f "$dir/feeds.conf.default" ] &&
[ -f "$dir/Makefile" ] &&
git -C "$dir" rev-parse --is-inside-work-tree >/dev/null 2>&1
}
is_helper_checkout() {
local dir="$1"
[ -f "$dir/prepare-openwrt.sh" ] &&
[ -f "$dir/prepare-openwrt-env.sh" ] &&
[ -f "$dir/add-external-repos.sh" ]
}
has_remote_branch() {
local branch="$1"
git show-ref --verify --quiet "refs/remotes/origin/$branch"
}
has_tag() {
local tag="$1"
git rev-parse --verify "refs/tags/$tag" >/dev/null 2>&1
}
ensure_helper_target_available() {
local target_helper="$1"
local source_dir="$2"
local existing_path=""
local source_path=""
if [ ! -e "$target_helper" ]; then
return
fi
existing_path="$(cd "$target_helper" && pwd -P)"
source_path="$(cd "$source_dir" && pwd -P)"
if [ "$existing_path" = "$source_path" ]; then
return
fi
echo "[ERROR] Helper destination already exists at '$target_helper'."
echo "[ERROR] Refusing to overwrite a different helper checkout."
exit 1
}
ensure_target_root_ready() {
local target_root="$1"
local first_entry=""
if [ ! -e "$target_root" ]; then
return
fi
if [ ! -d "$target_root" ]; then
echo "[ERROR] Target OpenWrt root '$target_root' exists but is not a directory."
exit 1
fi
if is_openwrt_repo "$target_root"; then
return
fi
first_entry="$(find "$target_root" -mindepth 1 -maxdepth 1 ! -name helper -print -quit 2>/dev/null || true)"
if [ -z "$first_entry" ]; then
return
fi
echo "[ERROR] Target OpenWrt root '$target_root' already contains unexpected files."
echo "[ERROR] Refusing to merge the helper checkout into a non-OpenWrt directory."
exit 1
}
normalize_structure() {
local source_dir="$SCRIPT_DIR"
local source_name
local parent_dir
local target_root
local target_helper
local temp_dir
source_name="$(basename "$source_dir")"
parent_dir="$(dirname "$source_dir")"
if [ "$source_name" = "helper" ] && [ "$(basename "$parent_dir")" = "openwrt" ]; then
WORK_ROOT="$parent_dir"
HELPER_DIR="$source_dir"
cd "$WORK_ROOT"
echo "[INFO] Reusing existing normalized layout at '$WORK_ROOT'."
return
fi
if is_openwrt_repo "$source_dir"; then
WORK_ROOT="$source_dir"
HELPER_DIR="$source_dir/helper"
cd "$WORK_ROOT"
echo "[INFO] Script is already running from an OpenWrt source root at '$WORK_ROOT'."
echo "[INFO] Skipping relocation to avoid moving an existing OpenWrt tree."
return
fi
if ! is_helper_checkout "$source_dir"; then
echo "[ERROR] '$source_dir' does not look like a helper checkout."
echo "[ERROR] Refusing to relocate an unexpected directory."
exit 1
fi
target_root="$parent_dir/openwrt"
target_helper="$target_root/helper"
if [ "$source_dir" != "$target_root" ]; then
ensure_target_root_ready "$target_root"
fi
ensure_helper_target_available "$target_helper" "$source_dir"
if [ "$source_dir" = "$target_root" ]; then
echo "[INFO] Helper checkout already uses the target root name. Normalizing in place."
temp_dir="$parent_dir/.openwrt-helper-relocate-$$"
if [ -e "$temp_dir" ]; then
echo "[ERROR] Temporary relocation path already exists: '$temp_dir'."
exit 1
fi
cd "$parent_dir"
mv "$source_dir" "$temp_dir"
mkdir -p "$target_root"
mv "$temp_dir" "$target_helper"
else
echo "[INFO] Relocating helper checkout to '$target_helper'."
mkdir -p "$target_root"
cd "$parent_dir"
mv "$source_dir" "$target_helper"
fi
WORK_ROOT="$target_root"
HELPER_DIR="$target_helper"
cd "$WORK_ROOT"
echo "[INFO] OpenWrt source root: '$WORK_ROOT'."
echo "[INFO] Helper checkout: '$HELPER_DIR'."
}
ensure_origin_remote() {
local current_url=""
if git remote get-url origin >/dev/null 2>&1; then
current_url="$(git remote get-url origin)"
if [ "$current_url" != "$REPO_URL" ]; then
echo "[INFO] Updating git remote 'origin' to '$REPO_URL'."
git remote set-url origin "$REPO_URL"
fi
else
git remote add origin "$REPO_URL"
fi
}
prepare_openwrt_repo() {
cd "$WORK_ROOT"
if is_openwrt_repo "$WORK_ROOT"; then
echo "[INFO] Existing OpenWrt repository detected at '$WORK_ROOT'. Updating refs..."
ensure_origin_remote
git fetch --tags origin
return
fi
if [ -e "$WORK_ROOT/.git" ]; then
echo "[ERROR] '$WORK_ROOT' already contains a Git repository that does not look like OpenWrt."
exit 1
fi
if [ -f "$WORK_ROOT/feeds.conf.default" ] || [ -f "$WORK_ROOT/Makefile" ] || [ -d "$WORK_ROOT/package" ]; then
echo "[ERROR] '$WORK_ROOT' contains files that look like an incomplete OpenWrt tree."
echo "[ERROR] Refusing to initialize over an unexpected directory state."
exit 1
fi
echo "[INFO] Initializing OpenWrt repository in '$WORK_ROOT'..."
git init .
ensure_origin_remote
git fetch --tags origin
}
checkout_or_update_branch() {
local branch="$1"
if [ ! "$(git rev-parse --abbrev-ref HEAD 2>/dev/null)" = "$branch" ]; then
if git show-ref --verify --quiet "refs/heads/$branch"; then
git checkout "$branch"
else
git checkout -b "$branch" --track "origin/$branch"
fi
fi
git pull --ff-only origin "$branch"
}
# --- Function: choose version ---
choose_version() {
echo
echo "Select OpenWRT version type:"
echo " 1) Stable release (e.g., 24.10.4)"
echo " 2) Beta (e.g., 24.10-SNAPSHOT or openwrt-24.10)"
echo " 3) Latest snapshot (master branch)"
echo -n "Enter choice [1-3, default=1]: "
read -r choice
case "$choice" in
2)
echo -n "Enter beta version (e.g. 24.10 or openwrt-24.10): "
read -r VERSION
SELECTED_TYPE="beta"
;;
3)
SELECTED_TYPE="snapshot"
VERSION="master"
;;
*)
echo -n "Enter stable version number (e.g. 24.10.4, default: latest): "
read -r VERSION
SELECTED_TYPE="stable"
;;
esac
}
# --- Start ---
normalize_structure
choose_version
prepare_openwrt_repo
pushd "$WORK_ROOT" >/dev/null
# --- Version selection logic ---
if [ "$SELECTED_TYPE" == "snapshot" ]; then
echo "[INFO] Checking out latest master (snapshot)..."
if has_remote_branch "master"; then
checkout_or_update_branch "master"
else
echo "[ERROR] Remote branch 'master' not found."
exit 1
fi
elif [ "$SELECTED_TYPE" == "beta" ]; then
local_branch=""
local_tag=""
if [[ "$VERSION" == openwrt-* ]]; then
local_branch="$VERSION"
local_tag="v${VERSION#openwrt-}-SNAPSHOT"
elif [[ "$VERSION" == v*-SNAPSHOT ]]; then
local_tag="$VERSION"
local_branch="openwrt-${VERSION#v}"
local_branch="${local_branch%-SNAPSHOT}"
else
local_branch="openwrt-${VERSION}"
local_tag="v${VERSION}-SNAPSHOT"
fi
if has_remote_branch "$local_branch"; then
echo "[INFO] Checking out beta branch '$local_branch'..."
checkout_or_update_branch "$local_branch"
elif has_tag "$local_tag"; then
echo "[INFO] Checking out beta tag '$local_tag'..."
git checkout "$local_tag"
else
echo "[ERROR] Beta branch or tag not found for version '$VERSION'."
exit 1
fi
else
# Stable version
if [ -z "$VERSION" ]; then
LATEST_TAG=$(git tag -l "v*" | sort -V | tail -n 1)
if [ -z "$LATEST_TAG" ]; then
echo "[ERROR] No stable tags found in remote repository."
exit 1
fi
echo "[INFO] No version specified, using latest stable tag: $LATEST_TAG"
VERSION="$LATEST_TAG"
else
if [[ "$VERSION" != v* ]]; then
VERSION="v${VERSION}"
fi
fi
if has_tag "$VERSION"; then
git checkout "$VERSION"
else
echo "[ERROR] Version tag '$VERSION' not found."
exit 1
fi
fi
# --- Update feeds ---
echo "[INFO] Updating and installing all feeds..."
./scripts/feeds update -a
./scripts/feeds install -a
# --- Run defconfig ---
echo "[INFO] Running make defconfig..."
make defconfig
CURRENT_VERSION=$(git describe --tags 2>/dev/null || git rev-parse --abbrev-ref HEAD)
popd >/dev/null
echo
echo "========================================"
echo "✅ OpenWRT source is ready."
echo " Version: $CURRENT_VERSION"
echo " Root: $WORK_ROOT"
echo "========================================"
echo
echo "👉 Next steps:"
echo " cd $WORK_ROOT"
echo " make menuconfig"
echo " make -j\$(nproc) download world"
echo