hostSync/build.sh

128 lines
3.9 KiB
Bash

#!/usr/bin/env bash
# ./build.sh [name] [version]
# 手动编译脚本,与 GoReleaser 配置保持一致
BIN_NAME=$1
if [ -z "$BIN_NAME" ]; then
BIN_NAME="hostsync" # 项目默认名称
fi
VERSION=$2
if [ -z "$VERSION" ]; then
VERSION=$(git describe --tags --abbrev=0 2>/dev/null)
# only use tags that start with 'v' and match semantic versioning
# then use the number part as version
# e.g. v1.2.3 => 1.2.3
if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
VERSION=""
else
VERSION="${VERSION#v}" # 去掉 'v' 前缀
fi
fi
# use short commit hash if no tag
if [ -z "$VERSION" ]; then
VERSION="$(git rev-parse --short HEAD)"
fi
echo "Building $BIN_NAME $VERSION"
OUTPUT_DIR="dist-$VERSION"
# output dir
rm -rf "$OUTPUT_DIR" >/dev/null 2>&1
mkdir -p "$OUTPUT_DIR" >/dev/null 2>&1
# check if upx is available
UPX_AVAILABLE=false
if command -v upx >/dev/null 2>&1; then
UPX_AVAILABLE=true
echo "UPX detected, will compress binaries after build"
else
echo "UPX not found, binaries will not be compressed"
fi
# 与 GoReleaser 配置完全一致的平台组合
declare -A targets=(
# Darwin (macOS) - 忽略 386 和 arm
["darwin-amd64"]=""
["darwin-arm64"]=""
# Linux - 支持所有架构,包括 ARM 版本
["linux-386"]=""
["linux-amd64"]=""
["linux-arm-v6"]="" # goarm=6
["linux-arm-v7"]="" # goarm=7
["linux-arm64"]=""
# Windows - 忽略 arm (32位)
["windows-386"]=".exe"
["windows-amd64"]=".exe"
["windows-arm64"]=".exe"
)
# build
k=1
total=${#targets[@]}
for target_key in "${!targets[@]}"; do
time=$(date "+%Y-%m-%d %H:%M:%S")
# 解析目标平台信息
if [[ "$target_key" == *"-arm-"* ]]; then
# 处理 ARM 版本,如 linux-arm-v6, linux-arm-v7
IFS='-' read -r GOOS GOARCH GOARM_VER <<<"$target_key"
GOARM=${GOARM_VER#v} # 移除 'v' 前缀
NAME_SUFFIX="armv$GOARM"
else
# 普通平台,如 linux-amd64, windows-386
IFS='-' read -r GOOS GOARCH <<<"$target_key"
GOARM=""
NAME_SUFFIX="$GOARCH"
fi
EXT="${targets[$target_key]}"
# 构建符合 GoReleaser 规范的文件名
OUTPUT="$OUTPUT_DIR/${BIN_NAME}-${VERSION}-${GOOS}-${NAME_SUFFIX}${EXT}"
# padding with spaces half of the terminal width
COLUMNS=$(tput cols 2>/dev/null || echo 80)
PADWIDTH=$((COLUMNS / 2))
OUTPUT_MSG=$(printf "%-${PADWIDTH}s" "Building $OUTPUT ...")
prg=$(echo "scale=2; ($k * 100) / $total" | bc 2>/dev/null || echo "$k")
printf "\r[%3.0f%%] %s%s" "$prg" "$OUTPUT_MSG" "$time"
# 设置环境变量并构建
COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
LDFLAGS="-s -w -X main.version=$VERSION -X main.commit=$COMMIT -X main.date=$DATE -X main.builtBy=manual"
env GOOS=$GOOS GOARCH=$GOARCH GOARM=$GOARM go build -ldflags="$LDFLAGS" -trimpath -o "$OUTPUT" >/dev/null 2>&1
# compress with upx if available
if [ "$UPX_AVAILABLE" = true ]; then
OUTPUT_MSG=$(printf "%-${PADWIDTH}s" "Compressing $OUTPUT ...")
time=$(date "+%Y-%m-%d %H:%M:%S")
printf "\r[%3.0f%%] %s%s" "$prg" "$OUTPUT_MSG" "$time"
upx --best --lzma -q "$OUTPUT" >/dev/null 2>&1 || echo -e "\nWarning: Failed to compress $OUTPUT"
fi
k=$((k + 1))
done
printf "\r%-${PADWIDTH}s%s\n" "[100%] All done." "$(date "+%Y-%m-%d %H:%M:%S")"
# reset env
unset BIN_NAME VERSION OUTPUT_DIR targets time GOOS GOARCH GOARM EXT UPX_AVAILABLE
unset COMMIT DATE LDFLAGS OUTPUT_MSG PADWIDTH COLUMNS prg k total target_key GOARM_VER NAME_SUFFIX
# 生成校验和文件,文件名与 GoReleaser 一致
echo ""
echo "📋 Generating checksums..."
CHECKSUM_FILE="$OUTPUT_DIR/SHA256SUMS"
cd "$OUTPUT_DIR" && sha256sum * | grep -v SHA256SUMS >"$(basename "$CHECKSUM_FILE")" && cd ..
echo "✅ Build completed. Files generated in $OUTPUT_DIR"
echo "📁 Total files: $(ls -1 "$OUTPUT_DIR" | wc -l) (including checksum)"