128 lines
3.9 KiB
Bash
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)"
|