501 lines
14 KiB
Bash
501 lines
14 KiB
Bash
#!/bin/bash
|
|
|
|
#====================================================
|
|
# System Required: OpenWrt
|
|
# Description: OpenWrt Compile Script
|
|
# Author: Modified from 281677160
|
|
#====================================================
|
|
|
|
# 字体颜色配置
|
|
Green="\033[32m"
|
|
Red="\033[31m"
|
|
Yellow="\033[33m"
|
|
Blue="\033[36m"
|
|
Purple="\033[35m"
|
|
Font="\033[0m"
|
|
GreenBG="\033[42;37m"
|
|
RedBG="\033[41;37m"
|
|
BlueBG="\033[44;37m"
|
|
OK="${Green}[OK]${Font}"
|
|
ERROR="${Red}[ERROR]${Font}"
|
|
|
|
# 变量
|
|
export GITHUB_WORKSPACE="$PWD"
|
|
export HOME_PATH="${GITHUB_WORKSPACE}/openwrt"
|
|
export OPERATES_PATH="${GITHUB_WORKSPACE}/operates"
|
|
export GITHUB_ENV="${GITHUB_WORKSPACE}/bendienv"
|
|
export CURRENT_PATH="${GITHUB_WORKSPACE##*/}"
|
|
export BENDI_VERSION="1"
|
|
|
|
# 打印函数
|
|
function print_ok() {
|
|
echo -e "\n${OK} ${Blue} $1 ${Font}\n"
|
|
}
|
|
|
|
function print_error() {
|
|
echo -e "\n${ERROR} ${RedBG} $1 ${Font}\n"
|
|
}
|
|
|
|
function ECHO_INFO() {
|
|
echo -e "${Blue}[INFO]${Font} ${Green} $1 ${Font}"
|
|
}
|
|
|
|
function ECHO_WARN() {
|
|
echo -e "${Yellow}[WARN]${Font} ${Yellow} $1 ${Font}"
|
|
}
|
|
|
|
function ECHO_ERROR() {
|
|
echo -e "${Red}[ERROR]${Font} ${Red} $1 ${Font}"
|
|
}
|
|
|
|
# 进度条显示
|
|
function progress_show() {
|
|
local current=$1
|
|
local total=$2
|
|
local width=50
|
|
local percentage=$((current * 100 / total))
|
|
local completed=$((width * current / total))
|
|
local remaining=$((width - completed))
|
|
|
|
printf "\r["
|
|
printf "%${completed}s" | tr ' ' '#'
|
|
printf "%${remaining}s" | tr ' ' '-'
|
|
printf "] %d%%" ${percentage}
|
|
}
|
|
|
|
# 判断命令执行结果
|
|
function judge() {
|
|
if [[ 0 -eq $? ]]; then
|
|
print_ok "$1"
|
|
else
|
|
print_error "$1"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 检查系统环境
|
|
function check_system() {
|
|
source /etc/os-release
|
|
if [[ ! "${UBUNTU_CODENAME}" =~ (bionic|focal|jammy) ]]; then
|
|
print_error "请使用 Ubuntu 18.04/20.04/22.04 系统"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$USER" == "root" ]]; then
|
|
print_error "请勿使用root用户编译,请使用普通用户"
|
|
exit 1
|
|
fi
|
|
|
|
# 检查磁盘空间
|
|
local available_space=$(df -h $PWD | awk 'NR==2 {print $4}' | sed 's/G//')
|
|
if [[ ${available_space%.*} -lt 20 ]]; then
|
|
print_error "可用空间小于20G,编译可能会失败,建议使用大于20G的可用空间"
|
|
read -p "是否继续编译?[y/N]:" continue_build
|
|
case $continue_build in
|
|
[yY])
|
|
ECHO_WARN "继续编译..."
|
|
;;
|
|
*)
|
|
ECHO_INFO "取消编译"
|
|
exit 0
|
|
;;
|
|
esac
|
|
fi
|
|
}
|
|
|
|
# 初始化环境
|
|
function init_env() {
|
|
echo '#!/bin/bash' >${GITHUB_ENV}
|
|
sudo chmod +x ${GITHUB_ENV}
|
|
|
|
if [[ `sudo grep -c "sudo ALL=(ALL:ALL) NOPASSWD:ALL" /etc/sudoers` -eq '0' ]]; then
|
|
sudo sed -i 's?%sudo.*?%sudo ALL=(ALL:ALL) NOPASSWD:ALL?g' /etc/sudoers
|
|
fi
|
|
|
|
# 创建必要的目录
|
|
mkdir -p ${HOME_PATH}
|
|
mkdir -p ${OPERATES_PATH}
|
|
}
|
|
|
|
# 编译主函数
|
|
function compile_firmware() {
|
|
cd ${HOME_PATH}
|
|
|
|
# 显示编译信息
|
|
echo -e "\n"
|
|
echo -e "${Blue}┌──────────────── 编译信息 ────────────────┐${Font}"
|
|
echo -e "${Blue}│ ${Green}CPU 型号:${Font} $(cat /proc/cpuinfo | grep 'model name' | uniq | cut -d: -f2 | xargs)"
|
|
echo -e "${Blue}│ ${Green}CPU 核心:${Font} $(nproc) 线程"
|
|
echo -e "${Blue}│ ${Green}内存大小:${Font} $(free -h | awk '/Mem/ {print $2}')"
|
|
echo -e "${Blue}│ ${Green}可用空间:${Font} $(df -h $PWD | awk 'NR==2 {print $4}')"
|
|
echo -e "${Blue}└─────────────────────────────────────────┘${Font}"
|
|
echo -e "\n"
|
|
|
|
# 清理编译目录
|
|
ECHO_INFO "清理编译目录..."
|
|
rm -rf ./tmp
|
|
rm -rf ./build_dir/target*
|
|
|
|
# 更新 feeds
|
|
ECHO_INFO "更新 feeds..."
|
|
./scripts/feeds update -a
|
|
./scripts/feeds install -a
|
|
|
|
# 下载依赖
|
|
ECHO_INFO "下载依赖文件..."
|
|
make defconfig
|
|
make download -j$(nproc)
|
|
|
|
# 开始编译
|
|
ECHO_INFO "开始编译固件..."
|
|
echo -e "${Yellow}预计需要2-3小时,请耐心等待...${Font}"
|
|
|
|
START_TIME=$(date +%s)
|
|
|
|
if [[ "$(nproc)" -le "12" ]]; then
|
|
make -j$(nproc) V=s 2>&1 | tee build.log
|
|
else
|
|
make -j16 V=s 2>&1 | tee build.log
|
|
fi
|
|
|
|
END_TIME=$(date +%s)
|
|
ELAPSED=$((END_TIME - START_TIME))
|
|
Hours=$((ELAPSED / 3600))
|
|
Minutes=$(((ELAPSED % 3600) / 60))
|
|
Seconds=$((ELAPSED % 60))
|
|
|
|
# 检查编译结果
|
|
if [[ -f bin/targets/*/*/openwrt-*-sysupgrade.bin ]]; then
|
|
print_ok "固件编译完成!"
|
|
echo -e "${Green}编译用时: ${Hours}小时${Minutes}分${Seconds}秒${Font}"
|
|
collect_firmware
|
|
else
|
|
print_error "固件编译失败!"
|
|
echo -e "${Red}请查看build.log文件了解详细错误信息${Font}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 收集固件
|
|
function collect_firmware() {
|
|
cd ${HOME_PATH}
|
|
|
|
# 创建固件目录
|
|
mkdir -p ${GITHUB_WORKSPACE}/firmware
|
|
|
|
# 复制编译好的固件
|
|
ECHO_INFO "正在收集固件..."
|
|
cp -rf bin/targets/*/* ${GITHUB_WORKSPACE}/firmware/
|
|
|
|
# 生成固件信息
|
|
cd ${GITHUB_WORKSPACE}/firmware
|
|
FIRMWARE_INFO="${GITHUB_WORKSPACE}/firmware/固件信息.txt"
|
|
echo "编译日期: $(date "+%Y年%m月%d日 %H:%M")" > "${FIRMWARE_INFO}"
|
|
echo "固件源码: ${SOURCE_CODE}" >> "${FIRMWARE_INFO}"
|
|
echo "固件版本: $(cat ${HOME_PATH}/package/base-files/files/etc/openwrt_version 2>/dev/null)" >> "${FIRMWARE_INFO}"
|
|
echo "固件架构: $(ls bin/targets/)" >> "${FIRMWARE_INFO}"
|
|
|
|
# 显示固件信息
|
|
echo -e "\n"
|
|
echo -e "${Blue}┌──────────────── 固件信息 ────────────────┐${Font}"
|
|
echo -e "${Blue}│ ${Green}固件位置:${Font} ${GITHUB_WORKSPACE}/firmware"
|
|
echo -e "${Blue}│ ${Green}固件大小:${Font} $(du -sh ${GITHUB_WORKSPACE}/firmware | cut -f1)"
|
|
echo -e "${Blue}│ ${Green}编译用时:${Font} ${Hours}小时${Minutes}分${Seconds}秒"
|
|
echo -e "${Blue}└─────────────────────────────────────────┘${Font}"
|
|
echo -e "\n"
|
|
}
|
|
|
|
# 更新源代码
|
|
function update_code() {
|
|
cd ${HOME_PATH}
|
|
|
|
ECHO_INFO "正在更新源代码..."
|
|
git pull
|
|
|
|
if [[ $? -eq 0 ]]; then
|
|
print_ok "源代码更新完成"
|
|
else
|
|
print_error "源代码更新失败"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 选择配置文件
|
|
function select_config() {
|
|
cd ${HOME_PATH}
|
|
|
|
echo -e "\n"
|
|
echo -e "${Blue}┌──────────────── 配置选择 ────────────────┐${Font}"
|
|
echo -e "${Blue}│ ${Yellow}1.${Font} x86_64 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}2.${Font} Rockchip ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}3.${Font} Raspberry Pi ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}4.${Font} 自定义配置 ${Blue}│${Font}"
|
|
echo -e "${Blue}└─────────────────────────────────────────┘${Font}"
|
|
echo -e "\n"
|
|
|
|
read -p "请选择配置文件[1-4]: " config_choose
|
|
|
|
case $config_choose in
|
|
1)
|
|
cp configs/x86_64.config .config
|
|
;;
|
|
2)
|
|
cp configs/rockchip.config .config
|
|
;;
|
|
3)
|
|
cp configs/rpi4.config .config
|
|
;;
|
|
4)
|
|
make menuconfig
|
|
;;
|
|
*)
|
|
print_error "无效的选择"
|
|
select_config
|
|
;;
|
|
esac
|
|
|
|
# 保存配置
|
|
make defconfig
|
|
}
|
|
|
|
# 显示主菜单
|
|
function show_main_menu() {
|
|
clear
|
|
echo -e "\n"
|
|
echo -e "${Blue}┌──────────────────────────────────────────┐${Font}"
|
|
echo -e "${Blue}│ OpenWrt 编译助手 │${Font}"
|
|
echo -e "${Blue}├──────────────────────────────────────────┤${Font}"
|
|
echo -e "${Blue}│ │${Font}"
|
|
echo -e "${Blue}│ ${Yellow}1.${Font} 更新系统软件包 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}2.${Font} 下载/更新 OpenWrt 源码 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}3.${Font} 选择编译配置 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}4.${Font} 开始编译固件 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}5.${Font} 打包 Amlogic/Rockchip 固件 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}6.${Font} 清理编译目录 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}7.${Font} 高级设置 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}0.${Font} 退出脚本 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ │${Font}"
|
|
echo -e "${Blue}└──────────────────────────────────────────┘${Font}"
|
|
echo -e "\n"
|
|
}
|
|
|
|
# 显示高级设置菜单
|
|
function show_advanced_menu() {
|
|
clear
|
|
echo -e "\n"
|
|
echo -e "${Blue}┌──────────────── 高级设置 ────────────────┐${Font}"
|
|
echo -e "${Blue}│ ${Yellow}1.${Font} 修改默认 IP 地址 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}2.${Font} 修改默认主题 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}3.${Font} 添加/删除软件包 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}4.${Font} 设置 OpenClash 配置 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}5.${Font} 自定义 feeds 配置 ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Yellow}0.${Font} 返回主菜单 ${Blue}│${Font}"
|
|
echo -e "${Blue}└─────────────────────────────────────────┘${Font}"
|
|
echo -e "\n"
|
|
}
|
|
|
|
# 处理主菜单选择
|
|
function process_main_menu() {
|
|
local choose
|
|
read -p "请输入选择[0-7]: " choose
|
|
|
|
case $choose in
|
|
1)
|
|
update_system
|
|
;;
|
|
2)
|
|
update_code
|
|
;;
|
|
3)
|
|
select_config
|
|
;;
|
|
4)
|
|
compile_firmware
|
|
;;
|
|
5)
|
|
package_armbian
|
|
;;
|
|
6)
|
|
clean_build
|
|
;;
|
|
7)
|
|
process_advanced_menu
|
|
;;
|
|
0)
|
|
ECHO_INFO "感谢使用,再见!"
|
|
exit 0
|
|
;;
|
|
*)
|
|
print_error "无效的选择"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# 处理高级设置菜单
|
|
function process_advanced_menu() {
|
|
show_advanced_menu
|
|
local choose
|
|
read -p "请输入选择[0-5]: " choose
|
|
|
|
case $choose in
|
|
1)
|
|
modify_ip
|
|
;;
|
|
2)
|
|
modify_theme
|
|
;;
|
|
3)
|
|
modify_packages
|
|
;;
|
|
4)
|
|
setup_openclash
|
|
;;
|
|
5)
|
|
modify_feeds
|
|
;;
|
|
0)
|
|
return
|
|
;;
|
|
*)
|
|
print_error "无效的选择"
|
|
process_advanced_menu
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# 更新系统
|
|
function update_system() {
|
|
ECHO_INFO "正在更新系统..."
|
|
sudo apt update
|
|
sudo apt upgrade -y
|
|
print_ok "系统更新完成"
|
|
}
|
|
|
|
# 清理编译目录
|
|
function clean_build() {
|
|
cd ${HOME_PATH}
|
|
ECHO_INFO "正在清理编译目录..."
|
|
make clean
|
|
rm -rf ./tmp
|
|
print_ok "清理完成"
|
|
}
|
|
|
|
# Amlogic/Rockchip 固件打包
|
|
function package_armbian() {
|
|
clear
|
|
echo -e "\n"
|
|
echo -e "${Blue}┌─────────── Amlogic/Rockchip 打包 ──────────┐${Font}"
|
|
echo -e "${Blue}│ │${Font}"
|
|
echo -e "${Blue}│ ${Yellow}支持的设备:${Font} ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Green}● Amlogic:${Font} S905x3, S905x2, S922x, etc ${Blue}│${Font}"
|
|
echo -e "${Blue}│ ${Green}● Rockchip:${Font} R66S, R68S, H66K, etc ${Blue}│${Font}"
|
|
echo -e "${Blue}│ │${Font}"
|
|
echo -e "${Blue}└──────────────────────────────────────────┘${Font}"
|
|
echo -e "\n"
|
|
|
|
# 检查必要文件
|
|
if [[ ! -f "${HOME_PATH}/bin/targets/armvirt/64/openwrt-armvirt-64-default-rootfs.tar.gz" ]]; then
|
|
print_error "未找到 armvirt-64 rootfs 文件,请先编译固件!"
|
|
return
|
|
fi
|
|
|
|
# 下载打包工具
|
|
if [[ ! -d "amlogic" ]]; then
|
|
ECHO_INFO "下载打包工具..."
|
|
git clone --depth 1 https://github.com/ophub/amlogic-s9xxx-openwrt.git amlogic
|
|
fi
|
|
|
|
# 选择设备
|
|
echo -e "${Yellow}请选择设备类型:${Font}"
|
|
echo -e "1. Amlogic S905x3"
|
|
echo -e "2. Amlogic S905x2"
|
|
echo -e "3. Amlogic S922x"
|
|
echo -e "4. Rockchip R66S/R68S"
|
|
echo -e "5. Rockchip H66K"
|
|
echo -e "0. 返回主菜单"
|
|
|
|
read -p "请输入选择[0-5]: " device_choose
|
|
|
|
case $device_choose in
|
|
1) device="s905x3";;
|
|
2) device="s905x2";;
|
|
3) device="s922x";;
|
|
4) device="r68s";;
|
|
5) device="h66k";;
|
|
0) return;;
|
|
*)
|
|
print_error "无效的选择"
|
|
return
|
|
;;
|
|
esac
|
|
|
|
# 开始打包
|
|
ECHO_INFO "开始打包固件..."
|
|
cd amlogic
|
|
sudo ./make -d $device -k 5.15.100
|
|
|
|
if [[ $? -eq 0 ]]; then
|
|
print_ok "固件打包完成!"
|
|
echo -e "${Green}固件位置:${Font} amlogic/output/images/"
|
|
else
|
|
print_error "固件打包失败!"
|
|
fi
|
|
}
|
|
|
|
# 错误处理函数
|
|
function error_handle() {
|
|
local error_code=$1
|
|
local error_msg=$2
|
|
|
|
echo -e "\n"
|
|
print_error "错误代码: $error_code"
|
|
print_error "错误信息: $error_msg"
|
|
|
|
# 记录错误日志
|
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Error $error_code: $error_msg" >> error.log
|
|
|
|
case $error_code in
|
|
1)
|
|
ECHO_INFO "尝试修复..."
|
|
make clean
|
|
;;
|
|
2)
|
|
ECHO_INFO "尝试更新源..."
|
|
./scripts/feeds update -a
|
|
;;
|
|
*)
|
|
ECHO_INFO "未知错误,请查看日志"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# 添加日志记录
|
|
function log_message() {
|
|
local level=$1
|
|
local message=$2
|
|
|
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" >> build.log
|
|
}
|
|
|
|
# 主程序入口
|
|
function main() {
|
|
# 检查系统环境
|
|
check_system
|
|
|
|
# 初始化环境
|
|
init_env
|
|
|
|
# 主循环
|
|
while true; do
|
|
show_main_menu
|
|
process_main_menu
|
|
echo -e "\n"
|
|
read -p "按回车键继续..."
|
|
done
|
|
}
|
|
|
|
# 捕获错误信号
|
|
trap 'error_handle $? "意外退出"' ERR
|
|
|
|
# 启动主程序
|
|
main "$@" |