270 lines
7.5 KiB
Bash
Executable File
270 lines
7.5 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# 跨平台编译脚本
|
|
# 支持编译多个操作系统和架构的版本
|
|
|
|
set -e
|
|
|
|
# 颜色输出
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# 项目信息
|
|
PROJECT_NAME="agent"
|
|
BUILD_DIR="bin"
|
|
VERSION="${VERSION:-$(date +%Y%m%d-%H%M%S)}"
|
|
MAIN_PACKAGE="./cmd/agent"
|
|
|
|
# 支持的平台列表
|
|
# 格式: OS/ARCH
|
|
PLATFORMS=(
|
|
"linux/amd64"
|
|
"linux/arm64"
|
|
"darwin/amd64"
|
|
"darwin/arm64"
|
|
"windows/amd64"
|
|
"windows/arm64"
|
|
)
|
|
|
|
# 显示使用说明
|
|
usage() {
|
|
echo -e "${BLUE}使用方法:${NC}"
|
|
echo " $0 [选项]"
|
|
echo ""
|
|
echo -e "${BLUE}选项:${NC}"
|
|
echo " -h, --help 显示帮助信息"
|
|
echo " -p, --platform PLATFORM 只编译指定平台 (例如: linux/amd64)"
|
|
echo " -l, --list 列出所有支持的平台"
|
|
echo " -c, --clean 编译前清理输出目录"
|
|
echo " -j, --jobs N 并行编译数量 (默认: 4)"
|
|
echo " -v, --version VERSION 设置版本号 (默认: 时间戳)"
|
|
echo " -s, --simple-only 只生成不带版本号的文件(默认生成两个)"
|
|
echo ""
|
|
echo -e "${BLUE}示例:${NC}"
|
|
echo " $0 # 编译所有平台"
|
|
echo " $0 -p linux/amd64 # 只编译 Linux AMD64"
|
|
echo " $0 -j 2 # 使用2个并行任务"
|
|
echo " $0 -c # 清理后编译"
|
|
}
|
|
|
|
# 列出所有平台
|
|
list_platforms() {
|
|
echo -e "${BLUE}支持的平台:${NC}"
|
|
for platform in "${PLATFORMS[@]}"; do
|
|
echo " - $platform"
|
|
done
|
|
}
|
|
|
|
# 清理输出目录
|
|
clean_build() {
|
|
if [ -d "$BUILD_DIR" ]; then
|
|
echo -e "${YELLOW}清理输出目录...${NC}"
|
|
rm -rf "$BUILD_DIR"
|
|
fi
|
|
mkdir -p "$BUILD_DIR"
|
|
}
|
|
|
|
# 编译单个平台
|
|
build_platform() {
|
|
local os_arch=$1
|
|
local simple_only=$2 # 是否只生成不带版本号的文件
|
|
local os=$(echo $os_arch | cut -d'/' -f1)
|
|
local arch=$(echo $os_arch | cut -d'/' -f2)
|
|
|
|
local output_path
|
|
if [ "$simple_only" = "true" ]; then
|
|
# 只生成不带版本号的文件
|
|
output_path="${BUILD_DIR}/${PROJECT_NAME}-${os}-${arch}"
|
|
if [ "$os" = "windows" ]; then
|
|
output_path="${output_path}.exe"
|
|
fi
|
|
else
|
|
# 生成带版本号的文件
|
|
output_path="${BUILD_DIR}/${PROJECT_NAME}-${os}-${arch}-${VERSION}"
|
|
if [ "$os" = "windows" ]; then
|
|
output_path="${output_path}.exe"
|
|
fi
|
|
fi
|
|
|
|
echo -e "${BLUE}[编译]${NC} ${os}/${arch} -> ${output_path}"
|
|
|
|
if GOOS=$os GOARCH=$arch go build -ldflags "-s -w -X main.version=${VERSION}" \
|
|
-o "$output_path" "$MAIN_PACKAGE" 2>&1; then
|
|
echo -e "${GREEN}[成功]${NC} ${os}/${arch}"
|
|
|
|
# 如果不是只生成简单版本,则创建不带版本号的副本(方便使用)
|
|
if [ "$simple_only" != "true" ]; then
|
|
local simple_name="${BUILD_DIR}/${PROJECT_NAME}-${os}-${arch}"
|
|
if [ "$os" = "windows" ]; then
|
|
simple_name="${simple_name}.exe"
|
|
fi
|
|
cp "$output_path" "$simple_name" 2>/dev/null || true
|
|
fi
|
|
return 0
|
|
else
|
|
echo -e "${RED}[失败]${NC} ${os}/${arch}"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# 主函数
|
|
main() {
|
|
local selected_platforms=()
|
|
local clean=false
|
|
local jobs=4
|
|
local list_only=false
|
|
local simple_only=false
|
|
|
|
# 解析参数
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
-p|--platform)
|
|
selected_platforms+=("$2")
|
|
shift 2
|
|
;;
|
|
-l|--list)
|
|
list_only=true
|
|
shift
|
|
;;
|
|
-c|--clean)
|
|
clean=true
|
|
shift
|
|
;;
|
|
-j|--jobs)
|
|
jobs="$2"
|
|
shift 2
|
|
;;
|
|
-v|--version)
|
|
VERSION="$2"
|
|
shift 2
|
|
;;
|
|
-s|--simple-only)
|
|
simple_only=true
|
|
shift
|
|
;;
|
|
*)
|
|
echo -e "${RED}未知参数: $1${NC}"
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# 如果只是列出平台,则退出
|
|
if [ "$list_only" = true ]; then
|
|
list_platforms
|
|
exit 0
|
|
fi
|
|
|
|
# 确定要编译的平台
|
|
if [ ${#selected_platforms[@]} -eq 0 ]; then
|
|
selected_platforms=("${PLATFORMS[@]}")
|
|
else
|
|
# 验证平台是否支持
|
|
for platform in "${selected_platforms[@]}"; do
|
|
local found=false
|
|
for p in "${PLATFORMS[@]}"; do
|
|
if [ "$p" = "$platform" ]; then
|
|
found=true
|
|
break
|
|
fi
|
|
done
|
|
if [ "$found" = false ]; then
|
|
echo -e "${RED}错误: 不支持的平台 '$platform'${NC}"
|
|
echo ""
|
|
list_platforms
|
|
exit 1
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# 清理(如果需要)
|
|
if [ "$clean" = true ]; then
|
|
clean_build
|
|
else
|
|
mkdir -p "$BUILD_DIR"
|
|
fi
|
|
|
|
echo -e "${GREEN}========================================${NC}"
|
|
echo -e "${GREEN}开始跨平台编译${NC}"
|
|
echo -e "${GREEN}========================================${NC}"
|
|
echo -e "项目名称: ${BLUE}${PROJECT_NAME}${NC}"
|
|
echo -e "版本号: ${BLUE}${VERSION}${NC}"
|
|
echo -e "输出目录: ${BLUE}${BUILD_DIR}${NC}"
|
|
echo -e "并行任务数: ${BLUE}${jobs}${NC}"
|
|
echo -e "平台数量: ${BLUE}${#selected_platforms[@]}${NC}"
|
|
echo ""
|
|
|
|
# 导出函数和变量供后台任务使用
|
|
export -f build_platform
|
|
export PROJECT_NAME BUILD_DIR VERSION MAIN_PACKAGE RED GREEN YELLOW BLUE NC
|
|
|
|
# 使用后台任务进行并行编译
|
|
local success_count=0
|
|
local fail_count=0
|
|
local temp_file=$(mktemp)
|
|
|
|
# 导出变量供后台任务使用
|
|
export simple_only
|
|
|
|
# 启动编译任务
|
|
for platform in "${selected_platforms[@]}"; do
|
|
(
|
|
if build_platform "$platform" "$simple_only"; then
|
|
echo "SUCCESS $platform" >> "$temp_file"
|
|
else
|
|
echo "FAIL $platform" >> "$temp_file"
|
|
fi
|
|
) &
|
|
|
|
# 控制并行数量
|
|
while [ $(jobs -r | wc -l | tr -d ' ') -ge "$jobs" ]; do
|
|
sleep 0.1
|
|
done
|
|
done
|
|
|
|
# 等待所有后台任务完成
|
|
wait
|
|
|
|
# 统计结果
|
|
if [ -f "$temp_file" ]; then
|
|
while IFS= read -r line; do
|
|
if [[ $line == SUCCESS* ]]; then
|
|
((success_count++))
|
|
elif [[ $line == FAIL* ]]; then
|
|
((fail_count++))
|
|
fi
|
|
done < "$temp_file"
|
|
rm -f "$temp_file"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${GREEN}========================================${NC}"
|
|
echo -e "${GREEN}编译完成${NC}"
|
|
echo -e "${GREEN}========================================${NC}"
|
|
echo -e "成功: ${GREEN}${success_count}${NC}"
|
|
echo -e "失败: ${RED}${fail_count}${NC}"
|
|
echo ""
|
|
|
|
if [ $fail_count -eq 0 ]; then
|
|
echo -e "${GREEN}所有平台编译成功!${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}编译输出文件:${NC}"
|
|
ls -lh "$BUILD_DIR" | grep "$PROJECT_NAME" | awk '{print " " $9 " (" $5 ")"}'
|
|
else
|
|
echo -e "${RED}部分平台编译失败,请检查错误信息${NC}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 运行主函数
|
|
main "$@"
|
|
|