From 819b2ab371183a7ad130e545c6deb883d30533cd Mon Sep 17 00:00:00 2001 From: Zhe Yuan Date: Sun, 31 May 2026 03:43:40 +0000 Subject: [PATCH] update prepare openwrt script --- README.md | 33 ++--- prepare-openwrt.sh | 302 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 260 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index a9d726a..52f9ec8 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,10 @@ This repository contains shell scripts that streamline preparing, configuring, a - 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). - prepare-openwrt.sh - - Clones or updates the OpenWrt source repo. + - Clones or updates the OpenWrt source repo in the top-level `openwrt/` root. - Lets you select Stable, Beta, or Snapshot versions interactively. - - Normalizes folder layout if run from an “openwrt-build-helper” directory. + - 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/`. - Updates feeds and runs make defconfig. - add-external-repos.sh - Clones or updates additional package repositories into package/. @@ -44,27 +45,28 @@ This repository contains shell scripts that streamline preparing, configuring, a - Run: ./prepare-openwrt.sh - Choose Stable, Beta, or Snapshot. - The script: - - Clones/updates the OpenWrt repo into ./openwrt (or uses the current repo if you’re already inside it). + - Reuses or creates the top-level OpenWrt root at `./openwrt`. + - Moves this helper checkout to `./openwrt/helper` on first run. - Updates/install feeds and runs make defconfig. 3) Add optional external packages - From the OpenWrt root: - - ../add-external-repos.sh + - ./helper/add-external-repos.sh - This pulls extra LuCI packages into package/. 4) Import a device config.buildinfo (optional but convenient) - From the OpenWrt root: - - ../download-config.sh + - ./helper/download-config.sh - Pick a device, and the script writes .config and runs make defconfig. 5) Enable additional packages from a list (optional) - Create a file packages.txt containing package names (whitespace or newlines). - From the OpenWrt root: - - ../add-openwrt-packages.sh packages.txt + - ./helper/add-openwrt-packages.sh packages.txt 6) Configure Go bootstrap path (if needed) - From the OpenWrt root: - - ../update-go-path.sh + - ./helper/update-go-path.sh - This sets CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT to the latest /usr/lib/go-X.XX/ found. - You can override it manually in .config if necessary. @@ -73,7 +75,7 @@ This repository contains shell scripts that streamline preparing, configuring, a - ./scripts/feeds update telephony - ./scripts/feeds install -a - Then run: - - ../apply-dahdi-patches.sh + - ./helper/config_24.10.4/apply-dahdi-patches.sh - Build the package: - make package/feeds/telephony/dahdi-linux/{clean,prepare} V=s - make package/feeds/telephony/dahdi-linux/compile V=s @@ -86,8 +88,9 @@ This repository contains shell scripts that streamline preparing, configuring, a ## Script usage notes and tips - Run locations: - - prepare-openwrt-env.sh, prepare-openwrt.sh: from anywhere (they manage/enter ./openwrt). - - All others: run from inside the OpenWrt source root unless otherwise indicated. + - `prepare-openwrt.sh`: resolves paths from the script location, not your current shell directory. + - `prepare-openwrt-env.sh`: can be run before the first normalization from the fresh helper checkout. + - All other helper scripts: run them from inside the OpenWrt source root as `./helper/...` unless otherwise indicated. - Feeds: - If a package can’t be found, ensure feeds are updated/installed: - ./scripts/feeds update -a && ./scripts/feeds install -a @@ -113,10 +116,12 @@ This repository contains shell scripts that streamline preparing, configuring, a - make clean; make -j$(nproc) download world ## Directory behavior -- If you run prepare-openwrt.sh from inside a directory named openwrt-build-helper, it will: - - Move your helper files to openwrt/helper/ - - Rename the top-level folder to openwrt/ - - Continue setup within openwrt/ +- If you start from a freshly cloned helper checkout at `/`, `prepare-openwrt.sh` will: + - Reuse or create `/openwrt/` as the OpenWrt source root. + - Move the entire helper checkout, including its `.git`, to `/openwrt/helper/`. + - Initialize or update the OpenWrt source tree directly in `/openwrt/`. +- If you later rerun `openwrt/helper/prepare-openwrt.sh`, it reuses the parent `openwrt/` directory and does not move directories again. +- 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`. ## Security and safety - Scripts use set -e to stop on errors. diff --git a/prepare-openwrt.sh b/prepare-openwrt.sh index 2cbdf83..92e1040 100755 --- a/prepare-openwrt.sh +++ b/prepare-openwrt.sh @@ -2,7 +2,7 @@ # Automatically prepare OpenWRT build environment. # - Clone or update repository # - Support selecting release/beta/snapshot versions -# - Adjust directory layout automatically if run from openwrt-build-helper +# - Normalize helper checkout into openwrt/helper # - Update and install feeds # - Prepare .config for build @@ -10,38 +10,214 @@ set -e umask 022 REPO_URL="https://github.com/openwrt/openwrt.git" -DEFAULT_DIR="openwrt" +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 "========================================" -# --- Function: detect and normalize directory structure --- -normalize_structure() { - local current_dir=$(basename "$(pwd)") +# --- Helpers --- +is_openwrt_repo() { + local dir="$1" - if [ "$current_dir" == "openwrt-build-helper" ]; then - echo "[INFO] Detected helper directory structure." + [ -f "$dir/feeds.conf.default" ] && + [ -f "$dir/Makefile" ] && + git -C "$dir" rev-parse --is-inside-work-tree >/dev/null 2>&1 +} - mkdir -p helper - # Move everything except helper into helper/ - for f in * .*; do - [[ "$f" == "." || "$f" == ".." || "$f" == "helper" ]] && continue - mv "$f" helper/ 2>/dev/null || true - done +is_helper_checkout() { + local dir="$1" - cd .. - mv openwrt-build-helper openwrt - cd openwrt - echo "[INFO] Directory renamed to 'openwrt', helper files moved to 'openwrt/helper/'." + [ -f "$dir/prepare-openwrt.sh" ] && + [ -f "$dir/prepare-openwrt-env.sh" ] && + [ -f "$dir/add-external-repos.sh" ] +} - elif [ "$current_dir" == "openwrt" ]; then - echo "[INFO] Running directly inside openwrt build directory." - else - echo "[INFO] Not inside openwrt folder, ensuring 'openwrt' subdirectory exists." - mkdir -p openwrt - cd openwrt +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 --- @@ -75,62 +251,65 @@ choose_version() { # --- Start --- normalize_structure choose_version +prepare_openwrt_repo -REPO_DIR="$DEFAULT_DIR" - -# If already inside openwrt repo, use current path -if [ -d ".git" ] && [ -f "feeds.conf.default" ]; then - REPO_DIR="." -fi - -# --- Clone or update repository --- -if [ "$REPO_DIR" == "." ]; then - echo "[INFO] Existing OpenWRT repository detected. Updating..." - git fetch --tags origin -else - if [ -d "$REPO_DIR/.git" ]; then - echo "[INFO] Repository exists, updating..." - pushd "$REPO_DIR" >/dev/null - git fetch --tags origin - git pull --ff-only - popd >/dev/null - else - echo "[INFO] Cloning repository..." - git clone "$REPO_URL" "$REPO_DIR" - fi -fi - -pushd "$REPO_DIR" >/dev/null +pushd "$WORK_ROOT" >/dev/null # --- Version selection logic --- if [ "$SELECTED_TYPE" == "snapshot" ]; then echo "[INFO] Checking out latest master (snapshot)..." - git checkout master - git pull origin master -elif [ "$SELECTED_TYPE" == "beta" ]; then - # Try both openwrt- and v-SNAPSHOT - if git rev-parse --verify "openwrt-${VERSION}" >/dev/null 2>&1; then - git checkout "openwrt-${VERSION}" - elif git rev-parse --verify "v${VERSION}-SNAPSHOT" >/dev/null 2>&1; then - git checkout "v${VERSION}-SNAPSHOT" + if has_remote_branch "master"; then + checkout_or_update_branch "master" else - echo "[ERROR] Beta branch or tag not found for version $VERSION." + 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 - VERSION="v${VERSION}" + if [[ "$VERSION" != v* ]]; then + VERSION="v${VERSION}" + fi fi - if git rev-parse --verify "$VERSION" >/dev/null 2>&1; then + if has_tag "$VERSION"; then git checkout "$VERSION" else - echo "[ERROR] Version tag $VERSION not found." + echo "[ERROR] Version tag '$VERSION' not found." exit 1 fi fi @@ -152,10 +331,11 @@ echo echo "========================================" echo "✅ OpenWRT source is ready." echo " Version: $CURRENT_VERSION" +echo " Root: $WORK_ROOT" echo "========================================" echo echo "👉 Next steps:" -echo " cd openwrt" +echo " cd $WORK_ROOT" echo " make menuconfig" echo " make -j\$(nproc) download world" echo