From b939f2b94e6789f5d52e501cfde39898bed0d042 Mon Sep 17 00:00:00 2001 From: Olia Lisa Date: Wed, 24 Jun 2026 08:39:18 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=B0=86=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E4=BB=A5=E5=87=BD=E6=95=B0=E5=BD=A2=E5=BC=8F=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=88=B0main.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.sh | 162 ------------------------------------------ init.sh | 25 ------- main.sh | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 202 insertions(+), 196 deletions(-) delete mode 100644 build.sh delete mode 100644 init.sh diff --git a/build.sh b/build.sh deleted file mode 100644 index 17cafae..0000000 --- a/build.sh +++ /dev/null @@ -1,162 +0,0 @@ -#!/bin/bash -# ============================================================= -# OpenWrt Image Builder 构建脚本 -# 使用方法: 将本脚本放在 imagebuilder 根目录下运行 -# 运行: bash main.sh -# ============================================================= - -# ──────────────────────────────────────────── -# 设备 Profile -# 运行 `make info` 查看所有可用 profile -# ──────────────────────────────────────────── -PROFILE="generic" # x86_64 通用 profile,可改为 x86_64 等 - -# ──────────────────────────────────────────── -# 自定义文件目录(映射到固件根文件系统) -# ──────────────────────────────────────────── -FILES_DIR="files" - -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -BUILDER_DIR="$(pwd)" - -# ──────────────────────────────────────────── -# 固件输出目录 -# ──────────────────────────────────────────── -OUTPUT_DIR="$BUILDER_DIR/output" -PROJECT_OUTPUT_DIR="$SCRIPT_DIR/output" - -# ──────────────────────────────────────────── -# 固件文件名附加标识(可留空) -# ──────────────────────────────────────────── -EXTRA_IMAGE_NAME="" - -# ============================================================= -# 插件包列表 -# - 前面加 - 表示从固件中移除该包,例如 -dnsmasq -# - 每行一个,方便增删注释 -# ============================================================= -PKG_LIST=( - -dropbear - openssh-server - openssh-sftp-server - vim-full - nano-plus - luci-i18n-vlmcsd-zh-cn - luci-i18n-argon-config-zh-cn - luci-i18n-package-manager-zh-cn - luci-i18n-firewall-zh-cn - luci-i18n-arpbind-zh-cn - - # 现代终端工具 - ripgrep - diffutils - less - eza - fish - - # 分区扩容 - luci-i18n-diskman-zh-cn - cfdisk - resize2fs - e2fsprogs - losetup - - # 代理插件 - luci-i18n-daed-zh-cn - luci-i18n-homeproxy-zh-cn - sing-box - -) - -# 动态拼接成字符串 -PACKAGES=$(printf "%s " "${PKG_LIST[@]}") - - -# ============================================================= -# 以下内容一般无需修改 -# ============================================================= - -# 颜色输出 -GREEN="\033[0;32m" -YELLOW="\033[1;33m" -RED="\033[0;31m" -NC="\033[0m" - -echo -e "${GREEN}========================================${NC}" -echo -e "${GREEN} OpenWrt Image Builder 开始构建${NC}" -echo -e "${GREEN}========================================${NC}" -echo -e " Profile : ${YELLOW}${PROFILE}${NC}" -echo -e " Files 目录 : ${YELLOW}${FILES_DIR}${NC}" -echo -e " 输出目录 : ${YELLOW}${OUTPUT_DIR}${NC}" -echo -e " 项目输出目录: ${YELLOW}${PROJECT_OUTPUT_DIR}${NC}" -echo -e " 镜像标识 : ${YELLOW}${EXTRA_IMAGE_NAME}${NC}" -echo "" - - -# 修改.config文件, 不构建以下格式, -sed -i \ --e 's/^CONFIG_ISO_IMAGES=y/# CONFIG_ISO_IMAGES is not set/' \ --e 's/^CONFIG_QCOW2_IMAGES=y/# CONFIG_QCOW2_IMAGES is not set/' \ --e 's/^CONFIG_VDI_IMAGES=y/# CONFIG_VDI_IMAGES is not set/' \ --e 's/^CONFIG_VMDK_IMAGES=y/# CONFIG_VMDK_IMAGES is not set/' \ --e 's/^CONFIG_VHDX_IMAGES=y/# CONFIG_VHDX_IMAGES is not set/' \ -.config - - -# 检查是否在 imagebuilder 目录下 -if [ ! -f "Makefile" ]; then - echo -e "${RED}[错误] 未找到 Makefile,请在 imagebuilder 根目录下运行本脚本!${NC}" - exit 1 -fi - -# 创建 files 目录(如果不存在) -if [ ! -d "$FILES_DIR" ]; then - echo -e "${YELLOW}[提示] files/ 目录不存在,已自动创建${NC}" - mkdir -p "$FILES_DIR" -fi - -mkdir -p "$OUTPUT_DIR" - -# 执行构建 -make image \ - PROFILE="$PROFILE" \ - PACKAGES="$PACKAGES" \ - FILES="$FILES_DIR" \ - BIN_DIR="$OUTPUT_DIR" \ - EXTRA_IMAGE_NAME="$EXTRA_IMAGE_NAME" - -# 构建结果判断 -if [ $? -eq 0 ]; then - if [ "$OUTPUT_DIR" != "$PROJECT_OUTPUT_DIR" ]; then - if [ ! -d "$OUTPUT_DIR" ]; then - echo -e "${RED} 未找到构建输出目录: ${OUTPUT_DIR}${NC}" - exit 1 - fi - - if [ -e "$PROJECT_OUTPUT_DIR" ]; then - BACKUP_OUTPUT_DIR="${PROJECT_OUTPUT_DIR}.bak.$(date +%Y%m%d%H%M%S)" - if ! mv "$PROJECT_OUTPUT_DIR" "$BACKUP_OUTPUT_DIR"; then - echo -e "${RED} 备份已有输出目录失败: ${PROJECT_OUTPUT_DIR}${NC}" - exit 1 - fi - echo -e "${YELLOW} 已有输出目录,已备份到: ${BACKUP_OUTPUT_DIR}${NC}" - fi - - if ! mv "$OUTPUT_DIR" "$PROJECT_OUTPUT_DIR"; then - echo -e "${RED} 移动构建输出目录失败: ${OUTPUT_DIR} -> ${PROJECT_OUTPUT_DIR}${NC}" - exit 1 - fi - fi - - echo "" - echo -e "${GREEN}========================================${NC}" - echo -e "${GREEN} 构建成功!${NC}" - echo -e "${GREEN} 固件路径: ${PROJECT_OUTPUT_DIR}${NC}" - echo -e "${GREEN}========================================${NC}" -else - echo "" - echo -e "${RED}========================================${NC}" - echo -e "${RED} 构建失败,请检查上方错误日志${NC}" - echo -e "${RED}========================================${NC}" - exit 1 -fi diff --git a/init.sh b/init.sh deleted file mode 100644 index b657cba..0000000 --- a/init.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -# 安装 Image Builder 构建所需依赖 -install() { - apt install -y build-essential libncurses-dev zlib1g-dev gawk git \ - gettext libssl-dev xsltproc rsync wget unzip python3 qemu-utils mkisofs zstd -} - -# 下载并解压 x86-64 的 Image Builder -# 参数 1: ImmortalWrt 版本号,例如 25.12.0 -# 输出: 解压后的 Image Builder 目录绝对路径 -download_imagebuilder() { - local version="$1" - local file="immortalwrt-imagebuilder-$version-x86-64.Linux-x86_64.tar.zst" - local url="https://downloads.immortalwrt.org/releases/$version/targets/x86/64/$file" - local folder - - wget -q --show-progress -O "$file" "$url" >&2 - - folder="$(tar -I zstd -tf "$file" | head -n 1 | cut -d/ -f1)" - - tar -I zstd -xvf "$file" >&2 - - echo "$(pwd)/$folder" -} diff --git a/main.sh b/main.sh index 7ad01e7..e4e4125 100644 --- a/main.sh +++ b/main.sh @@ -1,22 +1,215 @@ #!/bin/bash set -e +# 安装 Image Builder 构建所需依赖 +install_dependencies() { + apt install -y build-essential libncurses-dev zlib1g-dev gawk git \ + gettext libssl-dev xsltproc rsync wget unzip python3 qemu-utils mkisofs zstd +} + +# 下载并解压 x86-64 的 Image Builder +# 参数 1: ImmortalWrt 版本号,例如 25.12.0 +# 输出: 解压的后 Image Builder 目录绝对路径 +download_imagebuilder() { + local version="$1" + local file="immortalwrt-imagebuilder-$version-x86-64.Linux-x86_64.tar.zst" + local url="https://downloads.immortalwrt.org/releases/$version/targets/x86/64/$file" + local folder="immortalwrt-imagebuilder-$version-x86-64.Linux-x86_64" + local marker="$folder/.ready" + + if [ -f "$marker" ]; then + echo "$(pwd)/$folder" + return 0 + fi + + # 如果目录存在但不完整,清理 + if [ -d "$folder" ] && [ ! -f "$marker" ]; then + echo "[WARN] found incomplete folder, cleaning..." >&2 + rm -rf "$folder" + fi + + # 下载(强制覆盖) + wget -O "$file" "$url" >&2 + + # 解压 + tar -I zstd -xvf "$file" >&2 + + touch "$marker" + + echo "$(pwd)/$folder" +} + + +build(){ + # ──────────────────────────────────────────── + # 设备 Profile + # 运行 `make info` 查看所有可用 profile + # ──────────────────────────────────────────── + PROFILE="generic" # x86_64 通用 profile,可改为 x86_64 等 + + # ──────────────────────────────────────────── + # 自定义文件目录(映射到固件根文件系统) + # ──────────────────────────────────────────── + FILES_DIR="files" + + SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + BUILDER_DIR="${1}" + + # ──────────────────────────────────────────── + # 固件输出目录 + # ──────────────────────────────────────────── + OUTPUT_DIR="$BUILDER_DIR/output" + PROJECT_OUTPUT_DIR="$SCRIPT_DIR/output" + + # ──────────────────────────────────────────── + # 固件文件名附加标识(可留空) + # ──────────────────────────────────────────── + EXTRA_IMAGE_NAME="" + + # ============================================================= + # 插件包列表 + # - 前面加 - 表示从固件中移除该包,例如 -dnsmasq + # - 每行一个,方便增删注释 + # ============================================================= + PKG_LIST=( + -dropbear + openssh-server + openssh-sftp-server + vim-full + nano-plus + luci-i18n-vlmcsd-zh-cn + luci-i18n-argon-config-zh-cn + luci-i18n-package-manager-zh-cn + luci-i18n-firewall-zh-cn + luci-i18n-arpbind-zh-cn + + # 现代终端工具 + ripgrep + diffutils + less + eza + fish + + # 分区扩容 + luci-i18n-diskman-zh-cn + cfdisk + resize2fs + e2fsprogs + losetup + + # 代理插件 + luci-i18n-daed-zh-cn + luci-i18n-homeproxy-zh-cn + sing-box + + ) + + # 动态拼接成字符串 + PACKAGES=$(printf "%s " "${PKG_LIST[@]}") + + + # 颜色输出 + GREEN="\033[0;32m" + YELLOW="\033[1;33m" + RED="\033[0;31m" + NC="\033[0m" + + echo -e "${GREEN}========================================${NC}" + echo -e "${GREEN} OpenWrt Image Builder 开始构建${NC}" + echo -e "${GREEN}========================================${NC}" + echo -e " Profile : ${YELLOW}${PROFILE}${NC}" + echo -e " Files 目录 : ${YELLOW}${FILES_DIR}${NC}" + echo -e " 输出目录 : ${YELLOW}${OUTPUT_DIR}${NC}" + echo -e " 项目输出目录: ${YELLOW}${PROJECT_OUTPUT_DIR}${NC}" + echo -e " 镜像标识 : ${YELLOW}${EXTRA_IMAGE_NAME}${NC}" + echo "" + + # 切换到 Image Builder 目录 + cd "$BUILDER_DIR" + + # 修改.config文件, 不构建以下格式固件 + sed -i \ + -e 's/^CONFIG_ISO_IMAGES=y/# CONFIG_ISO_IMAGES is not set/' \ + -e 's/^CONFIG_QCOW2_IMAGES=y/# CONFIG_QCOW2_IMAGES is not set/' \ + -e 's/^CONFIG_VDI_IMAGES=y/# CONFIG_VDI_IMAGES is not set/' \ + -e 's/^CONFIG_VMDK_IMAGES=y/# CONFIG_VMDK_IMAGES is not set/' \ + -e 's/^CONFIG_VHDX_IMAGES=y/# CONFIG_VHDX_IMAGES is not set/' \ + .config + + + # 检查是否在 imagebuilder 目录下 + if [ ! -f "Makefile" ]; then + echo -e "${RED}[错误] 未找到 Makefile,请在 imagebuilder 根目录下运行本脚本!${NC}" + exit 1 + fi + + # 创建 files 目录(如果不存在) + if [ ! -d "$FILES_DIR" ]; then + echo -e "${YELLOW}[提示] files/ 目录不存在,已自动创建${NC}" + mkdir -p "$FILES_DIR" + fi + + mkdir -p "$OUTPUT_DIR" + + # 执行构建 + make image \ + PROFILE="$PROFILE" \ + PACKAGES="$PACKAGES" \ + FILES="$FILES_DIR" \ + BIN_DIR="$OUTPUT_DIR" \ + EXTRA_IMAGE_NAME="$EXTRA_IMAGE_NAME" + + # 构建结果判断 + if [ $? -eq 0 ]; then + if [ "$OUTPUT_DIR" != "$PROJECT_OUTPUT_DIR" ]; then + if [ ! -d "$OUTPUT_DIR" ]; then + echo -e "${RED} 未找到构建输出目录: ${OUTPUT_DIR}${NC}" + exit 1 + fi + + if [ -e "$PROJECT_OUTPUT_DIR" ]; then + BACKUP_OUTPUT_DIR="${PROJECT_OUTPUT_DIR}.bak.$(date +%Y%m%d%H%M%S)" + if ! mv "$PROJECT_OUTPUT_DIR" "$BACKUP_OUTPUT_DIR"; then + echo -e "${RED} 备份已有输出目录失败: ${PROJECT_OUTPUT_DIR}${NC}" + exit 1 + fi + echo -e "${YELLOW} 已有输出目录,已备份到: ${BACKUP_OUTPUT_DIR}${NC}" + fi + + if ! mv "$OUTPUT_DIR" "$PROJECT_OUTPUT_DIR"; then + echo -e "${RED} 移动构建输出目录失败: ${OUTPUT_DIR} -> ${PROJECT_OUTPUT_DIR}${NC}" + exit 1 + fi + fi + + echo "" + echo -e "${GREEN}========================================${NC}" + echo -e "${GREEN} 构建成功!${NC}" + echo -e "${GREEN} 固件路径: ${PROJECT_OUTPUT_DIR}${NC}" + echo -e "${GREEN}========================================${NC}" + else + echo "" + echo -e "${RED}========================================${NC}" + echo -e "${RED} 构建失败,请检查上方错误日志${NC}" + echo -e "${RED}========================================${NC}" + exit 1 + fi + +} + + # 项目根目录,用来保证从任意位置执行 main.sh 都能找到其他脚本 project_dir="$(cd "$(dirname "$0")" && pwd)" cd "$project_dir" -# 在这里修改要构建的 ImmortalWrt 版本 -version="25.12.0" - -# 加载初始化函数 -source "$project_dir/init.sh" +# 要构建的 ImmortalWrt 版本, 可以在 https://github.com/immortalwrt/immortalwrt 查询版本号 +version="25.12.0" # 安装依赖 -install +install_dependencies # 下载并解压 Image Builder,返回解压后的目录路径 builder_dir="$(download_imagebuilder "$version")" -# 进入 Image Builder 目录后执行构建脚本 -cd "$builder_dir" -bash "$project_dir/build.sh" +# 构建固件 +build $builder_dir