From 45b6fe4d5a9ec3996ef9b2c26c161ea13c97c460 Mon Sep 17 00:00:00 2001 From: Ilya Voronin Date: Sat, 25 Oct 2025 03:24:28 +0300 Subject: [PATCH] Format build scripts with shfmt --- .editorconfig | 18 +- package-appimage.sh | 8 +- package-debian.sh | 6 +- package-osx.sh | 18 +- package-rhel.sh | 402 ++++++++++++++++++++++++++------------------ 5 files changed, 269 insertions(+), 183 deletions(-) diff --git a/.editorconfig b/.editorconfig index 3aa0aa54..a1dfcf39 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,6 +9,10 @@ end_of_line = crlf trim_trailing_whitespace = true insert_final_newline = true +[*.sh] +end_of_line = lf +indent_size = 2 + [*.{yml,yaml}] indent_style = space indent_size = 2 @@ -157,14 +161,14 @@ dotnet_naming_rule.non_field_members_should_be_pascal.symbols = non_field_member dotnet_naming_rule.non_field_members_should_be_pascal.style = pascal dotnet_naming_symbols.interface.applicable_kinds = interface dotnet_naming_symbols.interface.applicable_accessibilities = * -dotnet_naming_symbols.interface.required_modifiers = +dotnet_naming_symbols.interface.required_modifiers = dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum dotnet_naming_symbols.types.applicable_accessibilities = * -dotnet_naming_symbols.types.required_modifiers = +dotnet_naming_symbols.types.required_modifiers = dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method dotnet_naming_symbols.non_field_members.applicable_accessibilities = * -dotnet_naming_symbols.non_field_members.required_modifiers = -dotnet_naming_style.pascal.required_prefix = -dotnet_naming_style.pascal.required_suffix = -dotnet_naming_style.pascal.word_separator = -dotnet_naming_style.pascal.capitalization = pascal_case \ No newline at end of file +dotnet_naming_symbols.non_field_members.required_modifiers = +dotnet_naming_style.pascal.required_prefix = +dotnet_naming_style.pascal.required_suffix = +dotnet_naming_style.pascal.word_separator = +dotnet_naming_style.pascal.capitalization = pascal_case diff --git a/package-appimage.sh b/package-appimage.sh index 6a8bfcca..994e9dc8 100755 --- a/package-appimage.sh +++ b/package-appimage.sh @@ -17,10 +17,10 @@ cp -rf "$OutputPath64"/* "$APPDIR_X64/usr/lib/v2rayN" || true [ -f "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_X64/usr/share/pixmaps/v2rayN.png" || true [ -f "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" ] && cp "$APPDIR_X64/usr/lib/v2rayN/v2rayN.png" "$APPDIR_X64/v2rayN.png" || true -printf '%s\n' '#!/bin/sh' 'HERE="$(dirname "$(readlink -f "$0")")"' 'cd "$HERE/usr/lib/v2rayN"' 'exec "$HERE/usr/lib/v2rayN/v2rayN" "$@"' > "$APPDIR_X64/AppRun" +printf '%s\n' '#!/bin/sh' 'HERE="$(dirname "$(readlink -f "$0")")"' 'cd "$HERE/usr/lib/v2rayN"' 'exec "$HERE/usr/lib/v2rayN/v2rayN" "$@"' >"$APPDIR_X64/AppRun" chmod +x "$APPDIR_X64/AppRun" ln -sf usr/lib/v2rayN/v2rayN "$APPDIR_X64/usr/bin/v2rayN" -cat > "$APPDIR_X64/v2rayN.desktop" <"$APPDIR_X64/v2rayN.desktop" < "$APPDIR_ARM64/AppRun" +printf '%s\n' '#!/bin/sh' 'HERE="$(dirname "$(readlink -f "$0")")"' 'cd "$HERE/usr/lib/v2rayN"' 'exec "$HERE/usr/lib/v2rayN/v2rayN" "$@"' >"$APPDIR_ARM64/AppRun" chmod +x "$APPDIR_ARM64/AppRun" ln -sf usr/lib/v2rayN/v2rayN "$APPDIR_ARM64/usr/bin/v2rayN" -cat > "$APPDIR_ARM64/v2rayN.desktop" <"$APPDIR_ARM64/v2rayN.desktop" < "${PackagePath}/opt/v2rayN/NotStoreConfigHere.txt" +echo "When this file exists, app will not store configs under this folder" >"${PackagePath}/opt/v2rayN/NotStoreConfigHere.txt" if [ $Arch = "linux-64" ]; then - Arch2="amd64" + Arch2="amd64" else - Arch2="arm64" + Arch2="arm64" fi echo $Arch2 diff --git a/package-osx.sh b/package-osx.sh index 042e29b7..aaee58b5 100755 --- a/package-osx.sh +++ b/package-osx.sh @@ -13,7 +13,7 @@ PackagePath="v2rayN-Package-${Arch}" mkdir -p "$PackagePath/v2rayN.app/Contents/Resources" cp -rf "$OutputPath" "$PackagePath/v2rayN.app/Contents/MacOS" cp -f "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN.icns" "$PackagePath/v2rayN.app/Contents/Resources/AppIcon.icns" -echo "When this file exists, app will not store configs under this folder" > "$PackagePath/v2rayN.app/Contents/MacOS/NotStoreConfigHere.txt" +echo "When this file exists, app will not store configs under this folder" >"$PackagePath/v2rayN.app/Contents/MacOS/NotStoreConfigHere.txt" chmod +x "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN" cat >"$PackagePath/v2rayN.app/Contents/Info.plist" <<-EOF @@ -48,11 +48,11 @@ cat >"$PackagePath/v2rayN.app/Contents/Info.plist" <<-EOF EOF create-dmg \ - --volname "v2rayN Installer" \ - --window-size 700 420 \ - --icon-size 100 \ - --icon "v2rayN.app" 160 185 \ - --hide-extension "v2rayN.app" \ - --app-drop-link 500 185 \ - "v2rayN-${Arch}.dmg" \ - "$PackagePath/v2rayN.app" \ No newline at end of file + --volname "v2rayN Installer" \ + --window-size 700 420 \ + --icon-size 100 \ + --icon "v2rayN.app" 160 185 \ + --hide-extension "v2rayN.app" \ + --app-drop-link 500 185 \ + "v2rayN-${Arch}.dmg" \ + "$PackagePath/v2rayN.app" diff --git a/package-rhel.sh b/package-rhel.sh index ea537c62..0eeca661 100755 --- a/package-rhel.sh +++ b/package-rhel.sh @@ -5,14 +5,14 @@ set -euo pipefail if [[ -r /etc/os-release ]]; then . /etc/os-release case "$ID" in - rhel|rocky|almalinux|fedora|centos|ubuntu|debian) - echo "[OK] Detected supported system: $NAME $VERSION_ID" - ;; - *) - echo "[ERROR] Unsupported system: $NAME ($ID)." - echo "This script only supports Red Hat Enterprise Linux/RockyLinux/AlmaLinux/CentOS or Ubuntu/Debian." - exit 1 - ;; + rhel | rocky | almalinux | fedora | centos | ubuntu | debian) + echo "[OK] Detected supported system: $NAME $VERSION_ID" + ;; + *) + echo "[ERROR] Unsupported system: $NAME ($ID)." + echo "This script only supports Red Hat Enterprise Linux/RockyLinux/AlmaLinux/CentOS or Ubuntu/Debian." + exit 1 + ;; esac else echo "[ERROR] Cannot detect system (missing /etc/os-release)." @@ -20,12 +20,12 @@ else fi # ===== Config & Parse arguments ========================================================= -VERSION_ARG="${1:-}" # Pass version number like 7.13.8, or leave empty -WITH_CORE="both" # Default: bundle both xray+sing-box -AUTOSTART=0 # 1 = enable system-wide autostart (/etc/xdg/autostart) -FORCE_NETCORE=0 # --netcore => skip archive bundle, use separate downloads -ARCH_OVERRIDE="" # --arch x64|arm64|all (optional compile target) -BUILD_FROM="" # --buildfrom 1|2|3 to select channel non-interactively +VERSION_ARG="${1:-}" # Pass version number like 7.13.8, or leave empty +WITH_CORE="both" # Default: bundle both xray+sing-box +AUTOSTART=0 # 1 = enable system-wide autostart (/etc/xdg/autostart) +FORCE_NETCORE=0 # --netcore => skip archive bundle, use separate downloads +ARCH_OVERRIDE="" # --arch x64|arm64|all (optional compile target) +BUILD_FROM="" # --buildfrom 1|2|3 to select channel non-interactively # If the first argument starts with --, do not treat it as a version number if [[ "${VERSION_ARG:-}" == --* ]]; then @@ -37,16 +37,38 @@ if [[ -n "${VERSION_ARG:-}" ]]; then shift || true; fi # Parse remaining optional arguments while [[ $# -gt 0 ]]; do case "$1" in - --with-core) WITH_CORE="${2:-both}"; shift 2;; - --autostart) AUTOSTART=1; shift;; - --xray-ver) XRAY_VER="${2:-}"; shift 2;; - --singbox-ver) SING_VER="${2:-}"; shift 2;; - --netcore) FORCE_NETCORE=1; shift;; - --arch) ARCH_OVERRIDE="${2:-}"; shift 2;; - --buildfrom) BUILD_FROM="${2:-}"; shift 2;; - *) - if [[ -z "${VERSION_ARG:-}" ]]; then VERSION_ARG="$1"; fi - shift;; + --with-core) + WITH_CORE="${2:-both}" + shift 2 + ;; + --autostart) + AUTOSTART=1 + shift + ;; + --xray-ver) + XRAY_VER="${2:-}" + shift 2 + ;; + --singbox-ver) + SING_VER="${2:-}" + shift 2 + ;; + --netcore) + FORCE_NETCORE=1 + shift + ;; + --arch) + ARCH_OVERRIDE="${2:-}" + shift 2 + ;; + --buildfrom) + BUILD_FROM="${2:-}" + shift 2 + ;; + *) + if [[ -z "${VERSION_ARG:-}" ]]; then VERSION_ARG="$1"; fi + shift + ;; esac done @@ -59,75 +81,79 @@ fi # ===== Environment check + Dependencies ======================================== host_arch="$(uname -m)" -[[ "$host_arch" == "aarch64" || "$host_arch" == "x86_64" ]] || { echo "Only supports aarch64 / x86_64"; exit 1; } +[[ "$host_arch" == "aarch64" || "$host_arch" == "x86_64" ]] || { + echo "Only supports aarch64 / x86_64" + exit 1 +} install_ok=0 case "$ID" in - # ------------------------------ RHEL family (UNCHANGED) ------------------------------ - rhel|rocky|almalinux|centos) - if command -v dnf >/dev/null 2>&1; then - sudo dnf -y install dotnet-sdk-8.0 rpm-build rpmdevtools curl unzip tar rsync || \ +# ------------------------------ RHEL family (UNCHANGED) ------------------------------ +rhel | rocky | almalinux | centos) + if command -v dnf >/dev/null 2>&1; then + sudo dnf -y install dotnet-sdk-8.0 rpm-build rpmdevtools curl unzip tar rsync || sudo dnf -y install dotnet-sdk rpm-build rpmdevtools curl unzip tar rsync - install_ok=1 - elif command -v yum >/dev/null 2>&1; then - sudo yum -y install dotnet-sdk-8.0 rpm-build rpmdevtools curl unzip tar rsync || \ + install_ok=1 + elif command -v yum >/dev/null 2>&1; then + sudo yum -y install dotnet-sdk-8.0 rpm-build rpmdevtools curl unzip tar rsync || sudo yum -y install dotnet-sdk rpm-build rpmdevtools curl unzip tar rsync - install_ok=1 - fi - ;; - # ------------------------------ Ubuntu ---------------------------------------------- - ubuntu) + install_ok=1 + fi + ;; +# ------------------------------ Ubuntu ---------------------------------------------- +ubuntu) + sudo apt-get update + # Ensure 'universe' (Ubuntu) to get 'rpm' + if ! apt-cache policy | grep -q '^500 .*ubuntu.com/ubuntu.* universe'; then + sudo apt-get -y install software-properties-common || true + sudo add-apt-repository -y universe || true sudo apt-get update - # Ensure 'universe' (Ubuntu) to get 'rpm' - if ! apt-cache policy | grep -q '^500 .*ubuntu.com/ubuntu.* universe'; then - sudo apt-get -y install software-properties-common || true - sudo add-apt-repository -y universe || true - sudo apt-get update - fi - # Base tools + rpm (provides rpmbuild) - sudo apt-get -y install curl unzip tar rsync rpm || true - # Cross-arch binutils so strip matches target arch + objdump for brp scripts - sudo apt-get -y install binutils binutils-x86-64-linux-gnu binutils-aarch64-linux-gnu || true - # rpmbuild presence check - if ! command -v rpmbuild >/dev/null 2>&1; then - echo "[ERROR] 'rpmbuild' not found after installing 'rpm'." - echo " Please ensure the 'rpm' package is available from your repos (universe on Ubuntu)." + fi + # Base tools + rpm (provides rpmbuild) + sudo apt-get -y install curl unzip tar rsync rpm || true + # Cross-arch binutils so strip matches target arch + objdump for brp scripts + sudo apt-get -y install binutils binutils-x86-64-linux-gnu binutils-aarch64-linux-gnu || true + # rpmbuild presence check + if ! command -v rpmbuild >/dev/null 2>&1; then + echo "[ERROR] 'rpmbuild' not found after installing 'rpm'." + echo " Please ensure the 'rpm' package is available from your repos (universe on Ubuntu)." + exit 1 + fi + # .NET SDK 8 (best effort via apt) + if ! command -v dotnet >/dev/null 2>&1; then + sudo apt-get -y install dotnet-sdk-8.0 || true + sudo apt-get -y install dotnet-sdk-8 || true + sudo apt-get -y install dotnet-sdk || true + fi + install_ok=1 + ;; +# ------------------------------ Debian (KEEP, with local dotnet install) ------------ +debian) + sudo apt-get update + # Base tools + rpm (provides rpmbuild on Debian) + objdump/strip + sudo apt-get -y install curl unzip tar rsync rpm binutils || true + # rpmbuild presence check + if ! command -v rpmbuild >/dev/null 2>&1; then + echo "[ERROR] 'rpmbuild' not found after installing 'rpm'." + echo " Please ensure 'rpm' is available from Debian repos." + exit 1 + fi + # Try apt for dotnet; fallback to official installer into $HOME/.dotnet + if ! command -v dotnet >/dev/null 2>&1; then + echo "[INFO] 'dotnet' not found. Installing .NET 8 SDK locally to \$HOME/.dotnet ..." + tmp="$(mktemp -d)" + trap '[[ -n "${tmp:-}" ]] && rm -rf "$tmp"' RETURN + curl -fsSL https://dot.net/v1/dotnet-install.sh -o "$tmp/dotnet-install.sh" + bash "$tmp/dotnet-install.sh" --channel 8.0 --install-dir "$HOME/.dotnet" + export PATH="$HOME/.dotnet:$HOME/.dotnet/tools:$PATH" + export DOTNET_ROOT="$HOME/.dotnet" + if ! command -v dotnet >/dev/null 2>&1; then + echo "[ERROR] dotnet installation failed." exit 1 fi - # .NET SDK 8 (best effort via apt) - if ! command -v dotnet >/dev/null 2>&1; then - sudo apt-get -y install dotnet-sdk-8.0 || true - sudo apt-get -y install dotnet-sdk-8 || true - sudo apt-get -y install dotnet-sdk || true - fi - install_ok=1 - ;; - # ------------------------------ Debian (KEEP, with local dotnet install) ------------ - debian) - sudo apt-get update - # Base tools + rpm (provides rpmbuild on Debian) + objdump/strip - sudo apt-get -y install curl unzip tar rsync rpm binutils || true - # rpmbuild presence check - if ! command -v rpmbuild >/dev/null 2>&1; then - echo "[ERROR] 'rpmbuild' not found after installing 'rpm'." - echo " Please ensure 'rpm' is available from Debian repos." - exit 1 - fi - # Try apt for dotnet; fallback to official installer into $HOME/.dotnet - if ! command -v dotnet >/dev/null 2>&1; then - echo "[INFO] 'dotnet' not found. Installing .NET 8 SDK locally to \$HOME/.dotnet ..." - tmp="$(mktemp -d)"; trap '[[ -n "${tmp:-}" ]] && rm -rf "$tmp"' RETURN - curl -fsSL https://dot.net/v1/dotnet-install.sh -o "$tmp/dotnet-install.sh" - bash "$tmp/dotnet-install.sh" --channel 8.0 --install-dir "$HOME/.dotnet" - export PATH="$HOME/.dotnet:$HOME/.dotnet/tools:$PATH" - export DOTNET_ROOT="$HOME/.dotnet" - if ! command -v dotnet >/dev/null 2>&1; then - echo "[ERROR] dotnet installation failed." - exit 1 - fi - fi - install_ok=1 - ;; + fi + install_ok=1 + ;; esac if [[ "$install_ok" -ne 1 ]]; then @@ -152,7 +178,10 @@ PROJECT="v2rayN.Desktop/v2rayN.Desktop.csproj" if [[ ! -f "$PROJECT" ]]; then PROJECT="$(find . -maxdepth 3 -name 'v2rayN.Desktop.csproj' | head -n1 || true)" fi -[[ -f "$PROJECT" ]] || { echo "v2rayN.Desktop.csproj not found"; exit 1; } +[[ -f "$PROJECT" ]] || { + echo "v2rayN.Desktop.csproj not found" + exit 1 +} # ===== Resolve GUI version & auto checkout ============================================ VERSION="" @@ -161,10 +190,22 @@ choose_channel() { # If --buildfrom provided, map it directly and skip interaction. if [[ -n "${BUILD_FROM:-}" ]]; then case "$BUILD_FROM" in - 1) echo "latest"; return 0;; - 2) echo "prerelease"; return 0;; - 3) echo "keep"; return 0;; - *) echo "[ERROR] Invalid --buildfrom value: ${BUILD_FROM}. Use 1|2|3." >&2; exit 1;; + 1) + echo "latest" + return 0 + ;; + 2) + echo "prerelease" + return 0 + ;; + 3) + echo "keep" + return 0 + ;; + *) + echo "[ERROR] Invalid --buildfrom value: ${BUILD_FROM}. Use 1|2|3." >&2 + exit 1 + ;; esac fi @@ -178,9 +219,9 @@ choose_channel() { printf "Enter 1, 2 or 3 [default 1]: " >&2 if read -r sel /dev/null 2>&1; then - tag="$(printf '%s' "$json" \ - | jq -r '[.[] | select(.prerelease==true)][0].tag_name' 2>/dev/null \ - | sed 's/^v//')" || true + tag="$(printf '%s' "$json" | + jq -r '[.[] | select(.prerelease==true)][0].tag_name' 2>/dev/null | + sed 's/^v//')" || true fi # 2) Fallback to sed/grep only if [[ -z "${tag:-}" || "${tag:-}" == "null" ]]; then - tag="$(printf '%s' "$json" \ - | tr '\n' ' ' \ - | sed 's/},[[:space:]]*{/\n/g' \ - | grep -m1 -E '"prerelease"[[:space:]]*:[[:space:]]*true' \ - | grep -Eo '"tag_name"[[:space:]]*:[[:space:]]*"v?[^"]+"' \ - | head -n1 \ - | sed -E 's/.*"tag_name"[[:space:]]*:[[:space:]]*"v?([^"]+)".*/\1/')" || true + tag="$(printf '%s' "$json" | + tr '\n' ' ' | + sed 's/},[[:space:]]*{/\n/g' | + grep -m1 -E '"prerelease"[[:space:]]*:[[:space:]]*true' | + grep -Eo '"tag_name"[[:space:]]*:[[:space:]]*"v?[^"]+"' | + head -n1 | + sed -E 's/.*"tag_name"[[:space:]]*:[[:space:]]*"v?([^"]+)".*/\1/')" || true fi [[ -n "${tag:-}" && "${tag:-}" != "null" ]] || return 1 @@ -279,9 +320,15 @@ if git rev-parse --git-dir >/dev/null 2>&1; then else tag="$(get_latest_tag_latest || true)" fi - [[ -n "$tag" ]] || { echo "[ERROR] Failed to resolve latest tag for channel '${ch}'."; exit 1; } + [[ -n "$tag" ]] || { + echo "[ERROR] Failed to resolve latest tag for channel '${ch}'." + exit 1 + } echo "[*] Latest tag for '${ch}': ${tag}" - git_try_checkout "$tag" || { echo "[ERROR] Failed to checkout '${tag}'."; exit 1; } + git_try_checkout "$tag" || { + echo "[ERROR] Failed to checkout '${tag}'." + exit 1 + } VERSION="${tag#v}" fi fi @@ -307,9 +354,15 @@ if git rev-parse --git-dir >/dev/null 2>&1; then else tag="$(get_latest_tag_latest || true)" fi - [[ -n "$tag" ]] || { echo "[ERROR] Failed to resolve latest tag for channel '${ch}'."; exit 1; } + [[ -n "$tag" ]] || { + echo "[ERROR] Failed to resolve latest tag for channel '${ch}'." + exit 1 + } echo "[*] Latest tag for '${ch}': ${tag}" - git_try_checkout "$tag" || { echo "[ERROR] Failed to checkout '${tag}'."; exit 1; } + git_try_checkout "$tag" || { + echo "[ERROR] Failed to checkout '${tag}'." + exit 1 + } VERSION="${tag#v}" fi fi @@ -334,17 +387,21 @@ download_xray() { mkdir -p "$outdir" if [[ -n "${XRAY_VER:-}" ]]; then ver="${XRAY_VER}"; fi if [[ -z "$ver" ]]; then - ver="$(curl -fsSL https://api.github.com/repos/XTLS/Xray-core/releases/latest \ - | grep -Eo '"tag_name":\s*"v[^"]+"' | sed -E 's/.*"v([^"]+)".*/\1/' | head -n1)" || true + ver="$(curl -fsSL https://api.github.com/repos/XTLS/Xray-core/releases/latest | + grep -Eo '"tag_name":\s*"v[^"]+"' | sed -E 's/.*"v([^"]+)".*/\1/' | head -n1)" || true fi - [[ -n "$ver" ]] || { echo "[xray] Failed to get version"; return 1; } + [[ -n "$ver" ]] || { + echo "[xray] Failed to get version" + return 1 + } if [[ "$RID_DIR" == "linux-arm64" ]]; then url="https://github.com/XTLS/Xray-core/releases/download/v${ver}/Xray-linux-arm64-v8a.zip" else url="https://github.com/XTLS/Xray-core/releases/download/v${ver}/Xray-linux-64.zip" fi echo "[+] Download xray: $url" - tmp="$(mktemp -d)"; trap '[[ -n "${tmp:-}" ]] && rm -rf "$tmp"' RETURN + tmp="$(mktemp -d)" + trap '[[ -n "${tmp:-}" ]] && rm -rf "$tmp"' RETURN curl -fL "$url" -o "$tmp/$zipname" unzip -q "$tmp/$zipname" -d "$tmp" install -Dm755 "$tmp/xray" "$outdir/xray" @@ -356,21 +413,28 @@ download_singbox() { mkdir -p "$outdir" if [[ -n "${SING_VER:-}" ]]; then ver="${SING_VER}"; fi if [[ -z "$ver" ]]; then - ver="$(curl -fsSL https://api.github.com/repos/SagerNet/sing-box/releases/latest \ - | grep -Eo '"tag_name":\s*"v[^"]+"' | sed -E 's/.*"v([^"]+)".*/\1/' | head -n1)" || true + ver="$(curl -fsSL https://api.github.com/repos/SagerNet/sing-box/releases/latest | + grep -Eo '"tag_name":\s*"v[^"]+"' | sed -E 's/.*"v([^"]+)".*/\1/' | head -n1)" || true fi - [[ -n "$ver" ]] || { echo "[sing-box] Failed to get version"; return 1; } + [[ -n "$ver" ]] || { + echo "[sing-box] Failed to get version" + return 1 + } if [[ "$RID_DIR" == "linux-arm64" ]]; then url="https://github.com/SagerNet/sing-box/releases/download/v${ver}/sing-box-${ver}-linux-arm64.tar.gz" else url="https://github.com/SagerNet/sing-box/releases/download/v${ver}/sing-box-${ver}-linux-amd64.tar.gz" fi echo "[+] Download sing-box: $url" - tmp="$(mktemp -d)"; trap '[[ -n "${tmp:-}" ]] && rm -rf "$tmp"' RETURN + tmp="$(mktemp -d)" + trap '[[ -n "${tmp:-}" ]] && rm -rf "$tmp"' RETURN curl -fL "$url" -o "$tmp/$tarname" tar -C "$tmp" -xzf "$tmp/$tarname" bin="$(find "$tmp" -type f -name 'sing-box' | head -n1 || true)" - [[ -n "$bin" ]] || { echo "[!] sing-box unpack failed"; return 1; } + [[ -n "$bin" ]] || { + echo "[!] sing-box unpack failed" + return 1 + } install -Dm755 "$bin" "$outdir/sing-box" } @@ -394,12 +458,12 @@ download_mihomo() { unify_geo_layout() { local outroot="$1" mkdir -p "$outroot/bin" - local names=( \ - "geosite.dat" \ - "geoip.dat" \ - "geoip-only-cn-private.dat" \ - "Country.mmdb" \ - "geoip.metadb" \ + local names=( + "geosite.dat" + "geoip.dat" + "geoip-only-cn-private.dat" + "Country.mmdb" + "geoip.metadb" ) for n in "${names[@]}"; do # If file exists under bin/xray/, move it up to bin/ @@ -462,9 +526,16 @@ download_v2rayn_bundle() { fi echo "[+] Try v2rayN bundle archive: $url" local tmp zipname - tmp="$(mktemp -d)"; zipname="$tmp/v2rayn.zip" - curl -fL "$url" -o "$zipname" || { echo "[!] Bundle download failed"; return 1; } - unzip -q "$zipname" -d "$tmp" || { echo "[!] Bundle unzip failed"; return 1; } + tmp="$(mktemp -d)" + zipname="$tmp/v2rayn.zip" + curl -fL "$url" -o "$zipname" || { + echo "[!] Bundle download failed" + return 1 + } + unzip -q "$zipname" -d "$tmp" || { + echo "[!] Bundle unzip failed" + return 1 + } if [[ -d "$tmp/bin" ]]; then mkdir -p "$outroot/bin" @@ -492,8 +563,8 @@ download_v2rayn_bundle() { } # ===== Build results collection for --arch all ======================================== -BUILT_RPMS=() # Will collect absolute paths of built RPMs -BUILT_ALL=0 # Flag to know if we should print the final summary +BUILT_RPMS=() # Will collect absolute paths of built RPMs +BUILT_ALL=0 # Flag to know if we should print the final summary # ===== Build (single-arch) function ==================================================== build_for_arch() { @@ -501,9 +572,20 @@ build_for_arch() { local short="$1" local rid rpm_target archdir case "$short" in - x64) rid="linux-x64"; rpm_target="x86_64"; archdir="x86_64" ;; - arm64) rid="linux-arm64"; rpm_target="aarch64"; archdir="aarch64" ;; - *) echo "[ERROR] Unknown arch '$short' (use x64|arm64)"; return 1;; + x64) + rid="linux-x64" + rpm_target="x86_64" + archdir="x86_64" + ;; + arm64) + rid="linux-arm64" + rpm_target="aarch64" + archdir="aarch64" + ;; + *) + echo "[ERROR] Unknown arch '$short' (use x64|arm64)" + return 1 + ;; esac echo "[*] Building for target: $short (RID=$rid, RPM --target $rpm_target)" @@ -596,7 +678,7 @@ build_for_arch() { # SPEC local SPECFILE="$SPECDIR/v2rayN.spec" mkdir -p "$SPECDIR" - cat > "$SPECFILE" <<'SPEC' + cat >"$SPECFILE" <<'SPEC' %global debug_package %{nil} %undefine _debuginfo_subpackages %undefine _debugsource_packages @@ -707,7 +789,7 @@ SPEC ins=1 } {print} - ' "$SPECFILE" > "${SPECFILE}.tmp" && mv "${SPECFILE}.tmp" "$SPECFILE" + ' "$SPECFILE" >"${SPECFILE}.tmp" && mv "${SPECFILE}.tmp" "$SPECFILE" awk ' BEGIN{infiles=0; done=0} @@ -719,7 +801,7 @@ SPEC next } {print} - ' "$SPECFILE" > "${SPECFILE}.tmp" && mv "${SPECFILE}.tmp" "$SPECFILE" + ' "$SPECFILE" >"${SPECFILE}.tmp" && mv "${SPECFILE}.tmp" "$SPECFILE" fi # Replace placeholders @@ -738,7 +820,7 @@ SPEC STRIP_BIN="/usr/bin/aarch64-linux-gnu-strip" fi if [[ -x "$STRIP_BIN" ]]; then - STRIP_ARGS=( --define "__strip $STRIP_BIN" ) + STRIP_ARGS=(--define "__strip $STRIP_BIN") fi fi @@ -767,30 +849,30 @@ SPEC # ===== Arch selection and build orchestration ========================================= case "${ARCH_OVERRIDE:-}" in - "") - # No --arch: use host architecture - if [[ "$host_arch" == "aarch64" ]]; then - build_for_arch arm64 - else - build_for_arch x64 - fi - ;; - x64|amd64) - build_for_arch x64 - ;; - arm64|aarch64) +"") + # No --arch: use host architecture + if [[ "$host_arch" == "aarch64" ]]; then build_for_arch arm64 - ;; - all) - BUILT_ALL=1 - # Build x64 and arm64 separately; each package contains its own arch-only binaries. + else build_for_arch x64 - build_for_arch arm64 - ;; - *) - echo "[ERROR] Unknown --arch '${ARCH_OVERRIDE}'. Use x64|arm64|all." - exit 1 - ;; + fi + ;; +x64 | amd64) + build_for_arch x64 + ;; +arm64 | aarch64) + build_for_arch arm64 + ;; +all) + BUILT_ALL=1 + # Build x64 and arm64 separately; each package contains its own arch-only binaries. + build_for_arch x64 + build_for_arch arm64 + ;; +*) + echo "[ERROR] Unknown --arch '${ARCH_OVERRIDE}'. Use x64|arm64|all." + exit 1 + ;; esac # ===== Final summary if building both arches ==========================================