Make update-go-path.sh able to skip the Go bootstrap chain
Setting CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT on its own only skips the initial bootstrap step; OpenWrt still builds the rest of the chain from source because CONFIG_GOLANG_BUILD_BOOTSTRAP defaults to y. Add --external, which clears that symbol so the installed toolchain builds host Go directly. Fix the "no Go installed" detection, which never fired. An unmatched glob is left as a literal, so the array held the pattern itself and the script wrote CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT="/usr/lib/go-go-*/" and reported success. nullglob alone is not enough either, since it only drops words that contain a wildcard and the literal candidate paths survive regardless, so each candidate is now checked for existence. Also pick the Go version by asking bin/go rather than parsing the directory name, warn when the installed Go is older than the bootstrap version the tree expects, replace every existing form of a symbol instead of appending a duplicate, and run make defconfig afterwards. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,74 +1,172 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Automatically detect Go installation and update .config for OpenWRT
|
# Point the OpenWrt build at an installed Go toolchain.
|
||||||
|
#
|
||||||
|
# Go based packages (tailscale, adguardhome, easytier, cloudflared, ...) need a
|
||||||
|
# host Go. By default OpenWrt builds the whole bootstrap chain from source; an
|
||||||
|
# already installed Go can replace part or all of that:
|
||||||
|
#
|
||||||
|
# --external GOLANG_BUILD_BOOTSTRAP=n, host Go is built with the
|
||||||
|
# installed toolchain directly (skips the entire chain,
|
||||||
|
# requires a Go new enough for the target version)
|
||||||
|
# default keep GOLANG_BUILD_BOOTSTRAP=y and only set the root, which
|
||||||
|
# skips the initial bootstrap step
|
||||||
|
#
|
||||||
|
# Usage: ./update-go-path.sh [options]
|
||||||
|
#
|
||||||
|
# --external skip the bootstrap chain entirely (recommended)
|
||||||
|
# --go-root <dir> use this Go instead of auto-detecting
|
||||||
|
# --skip-defconfig do not run make defconfig afterwards
|
||||||
|
# -n, --dry-run show what would change, write nothing
|
||||||
|
# -h, --help show this help
|
||||||
|
#
|
||||||
|
# Run it from the OpenWrt root: ./helper/update-go-path.sh
|
||||||
|
#
|
||||||
# Author: Zhe Yuan
|
# Author: Zhe Yuan
|
||||||
|
|
||||||
set -e
|
set -euo pipefail
|
||||||
umask 022
|
umask 022
|
||||||
|
|
||||||
CONFIG_FILE=".config"
|
CONFIG_FILE=".config"
|
||||||
|
EXTERNAL=false
|
||||||
|
GO_ROOT=""
|
||||||
|
RUN_DEFCONFIG=true
|
||||||
|
DRY_RUN=false
|
||||||
|
|
||||||
echo "========================================"
|
info() { echo "[INFO] $*"; }
|
||||||
echo " Go Path Auto Updater for OpenWRT"
|
warn() { echo "[WARN] $*"; }
|
||||||
echo "========================================"
|
err() { echo "[ERROR] $*" >&2; }
|
||||||
|
|
||||||
# --- Check for .config file ---
|
usage() { sed -n '2,25p' "$0" | sed 's/^# \{0,1\}//;s/^#$//'; }
|
||||||
if [ ! -f "$CONFIG_FILE" ]; then
|
|
||||||
echo "[ERROR] No .config file found in current directory!"
|
|
||||||
echo "Please run this script inside your OpenWRT build root."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --- Detect available Go installations ---
|
while [ $# -gt 0 ]; do
|
||||||
GO_DIRS=(/usr/lib/go-*/)
|
case "$1" in
|
||||||
if [ ${#GO_DIRS[@]} -eq 0 ]; then
|
--external) EXTERNAL=true ;;
|
||||||
echo "[ERROR] No Go installation found under /usr/lib/go-*"
|
--go-root)
|
||||||
echo "Please install Go using: sudo apt install golang -y"
|
if [ $# -lt 2 ] || [ -z "${2:-}" ]; then err "--go-root requires a directory."; exit 1; fi
|
||||||
exit 1
|
GO_ROOT="$2"; shift ;;
|
||||||
fi
|
--skip-defconfig) RUN_DEFCONFIG=false ;;
|
||||||
|
-n|--dry-run) DRY_RUN=true ;;
|
||||||
# --- Extract version numbers ---
|
-h|--help) usage; exit 0 ;;
|
||||||
GO_VERSIONS=()
|
*) err "Unknown option: $1"; echo "Run '$0 --help' for usage." >&2; exit 1 ;;
|
||||||
for dir in "${GO_DIRS[@]}"; do
|
esac
|
||||||
ver=$(basename "$dir" | sed -E 's/^go-([0-9]+\.[0-9]+).*$/\1/')
|
shift
|
||||||
GO_VERSIONS+=("$ver")
|
|
||||||
done
|
done
|
||||||
|
|
||||||
# --- Sort versions and pick the latest ---
|
echo "========================================"
|
||||||
IFS=$'\n' sorted=($(sort -V <<<"${GO_VERSIONS[*]}"))
|
echo " Go Toolchain Setup for OpenWrt"
|
||||||
LATEST_VER="${sorted[-1]}"
|
echo "========================================"
|
||||||
LATEST_PATH="/usr/lib/go-${LATEST_VER}/"
|
|
||||||
|
|
||||||
echo "[INFO] Found Go versions: ${GO_VERSIONS[*]}"
|
if [ ! -f "$CONFIG_FILE" ]; then
|
||||||
echo "[INFO] Using latest Go version: $LATEST_VER"
|
err "No .config in the current directory."
|
||||||
echo "[INFO] Path: $LATEST_PATH"
|
err "From the OpenWrt root, run it as: ./helper/$(basename "$0")"
|
||||||
|
exit 1
|
||||||
# --- Check if multiple versions exist ---
|
|
||||||
if [ ${#GO_VERSIONS[@]} -gt 1 ]; then
|
|
||||||
echo "[WARN] Multiple Go versions detected!"
|
|
||||||
echo "If you prefer to use an older version, modify manually:"
|
|
||||||
echo " CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT=\"/usr/lib/go-X.XX/\""
|
|
||||||
echo
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Update .config ---
|
# --- Locate a Go installation --------------------------------------------
|
||||||
if grep -q '^CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT=' "$CONFIG_FILE"; then
|
if [ -z "$GO_ROOT" ]; then
|
||||||
echo "[INFO] Updating existing CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT..."
|
# nullglob only drops words that actually contain a wildcard; a literal path
|
||||||
sed -i "s|^CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT=.*|CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT=\"${LATEST_PATH}\"|" "$CONFIG_FILE"
|
# such as /usr/local/go/ survives even when it does not exist. So collect
|
||||||
|
# candidates and keep only the directories that are really there.
|
||||||
|
shopt -s nullglob
|
||||||
|
CANDIDATES=(/usr/lib/go-*/ /usr/local/go/ /usr/lib/golang/)
|
||||||
|
shopt -u nullglob
|
||||||
|
|
||||||
|
GO_DIRS=()
|
||||||
|
for dir in "${CANDIDATES[@]}"; do
|
||||||
|
[ -d "$dir" ] && GO_DIRS+=("$dir")
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#GO_DIRS[@]} -eq 0 ]; then
|
||||||
|
err "No Go installation found under /usr/lib/go-*, /usr/local/go or /usr/lib/golang."
|
||||||
|
err "Install one with: sudo apt install golang-1.24-go"
|
||||||
|
err "or keep the default, where OpenWrt builds its own bootstrap chain."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
BEST_VER=""
|
||||||
|
for dir in "${GO_DIRS[@]}"; do
|
||||||
|
[ -x "${dir}bin/go" ] || continue
|
||||||
|
ver="$("${dir}bin/go" version 2>/dev/null | awk '{print $3}' | sed 's/^go//')"
|
||||||
|
[ -n "$ver" ] || continue
|
||||||
|
if [ -z "$BEST_VER" ] ||
|
||||||
|
[ "$(printf '%s\n%s\n' "$BEST_VER" "$ver" | sort -V | tail -n 1)" = "$ver" ]; then
|
||||||
|
BEST_VER="$ver"
|
||||||
|
GO_ROOT="$dir"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$GO_ROOT" ]; then
|
||||||
|
err "Found Go directories but none contained a working bin/go."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ${#GO_DIRS[@]} -gt 1 ]; then
|
||||||
|
info "Go installations found: ${GO_DIRS[*]}"
|
||||||
|
info "Using the newest; override with --go-root <dir>."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
GO_ROOT="${GO_ROOT%/}/"
|
||||||
|
if [ ! -x "${GO_ROOT}bin/go" ]; then
|
||||||
|
err "No usable Go compiler at ${GO_ROOT}bin/go"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
GO_VER="$("${GO_ROOT}bin/go" version | awk '{print $3}' | sed 's/^go//')"
|
||||||
|
|
||||||
|
info "Go toolchain: $GO_ROOT (version $GO_VER)"
|
||||||
|
|
||||||
|
# --- Warn if it is older than what the tree wants -------------------------
|
||||||
|
BOOTSTRAP_MK="feeds/packages/lang/golang/golang-bootstrap/Makefile"
|
||||||
|
if [ -f "$BOOTSTRAP_MK" ]; then
|
||||||
|
NEED="$(awk -F':=' '/^GO_VERSION_MAJOR_MINOR/ {print $2; exit}' "$BOOTSTRAP_MK" | tr -d ' ')"
|
||||||
|
if [ -n "$NEED" ] &&
|
||||||
|
[ "$(printf '%s\n%s\n' "$NEED" "$GO_VER" | sort -V | head -n 1)" != "$NEED" ]; then
|
||||||
|
warn "Installed Go $GO_VER is older than the bootstrap version $NEED this tree expects."
|
||||||
|
warn "The build may fail; consider installing golang-$NEED-go."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Apply ----------------------------------------------------------------
|
||||||
|
set_config() {
|
||||||
|
local key="$1" val="$2"
|
||||||
|
if [ "$DRY_RUN" = true ]; then
|
||||||
|
echo "[DRY-RUN] $key=$val"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
# Drop every existing form of the symbol, then append once.
|
||||||
|
sed -i "/^${key}=/d;/^# ${key} is not set$/d" "$CONFIG_FILE"
|
||||||
|
if [ "$val" = "n" ]; then
|
||||||
|
echo "# $key is not set" >> "$CONFIG_FILE"
|
||||||
else
|
else
|
||||||
echo "[INFO] Adding CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT..."
|
echo "$key=$val" >> "$CONFIG_FILE"
|
||||||
echo "CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT=\"${LATEST_PATH}\"" >> "$CONFIG_FILE"
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
set_config CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT "\"$GO_ROOT\""
|
||||||
|
|
||||||
|
if [ "$EXTERNAL" = true ]; then
|
||||||
|
set_config CONFIG_GOLANG_BUILD_BOOTSTRAP n
|
||||||
|
info "Bootstrap chain disabled; host Go is built with the installed toolchain."
|
||||||
|
else
|
||||||
|
set_config CONFIG_GOLANG_BUILD_BOOTSTRAP y
|
||||||
|
info "Bootstrap chain kept (only the initial step is skipped)."
|
||||||
|
info "Pass --external to skip it entirely."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- Verify result ---
|
if [ "$DRY_RUN" = true ]; then
|
||||||
echo
|
echo
|
||||||
echo "[SUCCESS] Go path updated in .config:"
|
info "Dry run complete; .config was not modified."
|
||||||
grep 'CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT' "$CONFIG_FILE"
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$RUN_DEFCONFIG" = true ]; then
|
||||||
|
info "Running make defconfig..."
|
||||||
|
make defconfig >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "========================================"
|
echo "========================================"
|
||||||
echo "✅ Go path update complete!"
|
echo "OK Go configuration updated."
|
||||||
echo "========================================"
|
echo "========================================"
|
||||||
echo
|
grep -E '^(CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT|CONFIG_GOLANG_BUILD_BOOTSTRAP)|^# CONFIG_GOLANG_BUILD_BOOTSTRAP' "$CONFIG_FILE" | sed 's/^/ /'
|
||||||
echo "👉 If you wish to override manually, edit .config and change:"
|
|
||||||
echo " CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT=\"/usr/lib/go-X.XX/\""
|
|
||||||
echo
|
echo
|
||||||
|
|||||||
Reference in New Issue
Block a user