diff --git a/.github/workflows/beta_release.yml b/.github/workflows/beta_release.yml index be072419..9b804cea 100644 --- a/.github/workflows/beta_release.yml +++ b/.github/workflows/beta_release.yml @@ -61,7 +61,7 @@ jobs: strategy: matrix: include: - - target: "!(*musl*|*windows-arm64*|*android*|*freebsd*)" # xgo and loongarch + - target: "!(*musl*|*windows-arm64*|*windows7-*|*android*|*freebsd*)" # xgo and loongarch hash: "md5" - target: "linux-!(arm*)-musl*" #musl-not-arm hash: "md5-linux-musl" @@ -69,6 +69,8 @@ jobs: hash: "md5-linux-musl-arm" - target: "windows-arm64" #win-arm64 hash: "md5-windows-arm64" + - target: "windows7-*" #win7 + hash: "md5-windows7" - target: "android-*" #android hash: "md5-android" - target: "freebsd-*" #freebsd diff --git a/build.sh b/build.sh index 93e7ea33..3c62a078 100644 --- a/build.sh +++ b/build.sh @@ -95,6 +95,45 @@ BuildWinArm64() { go build -o "$1" -ldflags="$ldflags" -tags=jsoniter . } +BuildWin7() { + # Setup Win7 Go compiler (patched version that supports Windows 7) + go_version=$(go version | grep -o 'go[0-9]\+\.[0-9]\+\.[0-9]\+' | sed 's/go//') + echo "Detected Go version: $go_version" + + curl -fsSL --retry 3 -o go-win7.zip -H "Authorization: Bearer $GITHUB_TOKEN" \ + "https://github.com/XTLS/go-win7/releases/download/patched-${go_version}/go-for-win7-linux-amd64.zip" + + rm -rf go-win7 + unzip go-win7.zip -d go-win7 + rm go-win7.zip + + # Set permissions for all wrapper files + chmod +x ./wrapper/zcc-win7 + chmod +x ./wrapper/zcxx-win7 + chmod +x ./wrapper/zcc-win7-386 + chmod +x ./wrapper/zcxx-win7-386 + + # Build for both 386 and amd64 architectures + for arch in "386" "amd64"; do + echo "building for windows7-${arch}" + export GOOS=windows + export GOARCH=${arch} + export CGO_ENABLED=1 + + # Use architecture-specific wrapper files + if [ "$arch" = "386" ]; then + export CC=$(pwd)/wrapper/zcc-win7-386 + export CXX=$(pwd)/wrapper/zcxx-win7-386 + else + export CC=$(pwd)/wrapper/zcc-win7 + export CXX=$(pwd)/wrapper/zcxx-win7 + fi + + # Use the patched Go compiler for Win7 compatibility + $(pwd)/go-win7/bin/go build -o "${1}-${arch}.exe" -ldflags="$ldflags" -tags=jsoniter . + done +} + BuildDev() { rm -rf .git/ mkdir -p "dist" @@ -186,12 +225,171 @@ BuildRelease() { rm -rf .git/ mkdir -p "build" BuildWinArm64 ./build/"$appName"-windows-arm64.exe + BuildWin7 ./build/"$appName"-windows7 xgo -out "$appName" -ldflags="$ldflags" -tags=jsoniter . # why? Because some target platforms seem to have issues with upx compression # upx -9 ./"$appName"-linux-amd64 # cp ./"$appName"-windows-amd64.exe ./"$appName"-windows-amd64-upx.exe # upx -9 ./"$appName"-windows-amd64-upx.exe mv "$appName"-* build + + # Build LoongArch with glibc (both old world abi1.0 and new world abi2.0) + # Separate from musl builds to avoid cache conflicts + BuildLoongGLIBC ./build/$appName-linux-loong64-abi1.0 abi1.0 + BuildLoongGLIBC ./build/$appName-linux-loong64 abi2.0 +} + +BuildLoongGLIBC() { + local target_abi="$2" + local output_file="$1" + local oldWorldGoVersion="1.24.3" + + if [ "$target_abi" = "abi1.0" ]; then + echo building for linux-loong64-abi1.0 + else + echo building for linux-loong64-abi2.0 + target_abi="abi2.0" # Default to abi2.0 if not specified + fi + + # Note: No longer need global cache cleanup since ABI1.0 uses isolated cache directory + echo "Using optimized cache strategy: ABI1.0 has isolated cache, ABI2.0 uses standard cache" + + if [ "$target_abi" = "abi1.0" ]; then + # Setup abi1.0 toolchain and patched Go compiler similar to cgo-action implementation + echo "Setting up Loongson old-world ABI1.0 toolchain and patched Go compiler..." + + # Download and setup patched Go compiler for old-world + if ! curl -fsSL --retry 3 -H "Authorization: Bearer $GITHUB_TOKEN" \ + "https://github.com/loong64/loong64-abi1.0-toolchains/releases/download/20250722/go${oldWorldGoVersion}.linux-amd64.tar.gz" \ + -o go-loong64-abi1.0.tar.gz; then + echo "Error: Failed to download patched Go compiler for old-world ABI1.0" + if [ -n "$GITHUB_TOKEN" ]; then + echo "Error output from curl:" + curl -fsSL --retry 3 -H "Authorization: Bearer $GITHUB_TOKEN" \ + "https://github.com/loong64/loong64-abi1.0-toolchains/releases/download/20250722/go${oldWorldGoVersion}.linux-amd64.tar.gz" \ + -o go-loong64-abi1.0.tar.gz || true + fi + return 1 + fi + + rm -rf go-loong64-abi1.0 + mkdir go-loong64-abi1.0 + if ! tar -xzf go-loong64-abi1.0.tar.gz -C go-loong64-abi1.0 --strip-components=1; then + echo "Error: Failed to extract patched Go compiler" + return 1 + fi + rm go-loong64-abi1.0.tar.gz + + # Download and setup GCC toolchain for old-world + if ! curl -fsSL --retry 3 -H "Authorization: Bearer $GITHUB_TOKEN" \ + "https://github.com/loong64/loong64-abi1.0-toolchains/releases/download/20250722/loongson-gnu-toolchain-8.3.novec-x86_64-loongarch64-linux-gnu-rc1.1.tar.xz" \ + -o gcc8-loong64-abi1.0.tar.xz; then + echo "Error: Failed to download GCC toolchain for old-world ABI1.0" + if [ -n "$GITHUB_TOKEN" ]; then + echo "Error output from curl:" + curl -fsSL --retry 3 -H "Authorization: Bearer $GITHUB_TOKEN" \ + "https://github.com/loong64/loong64-abi1.0-toolchains/releases/download/20250722/loongson-gnu-toolchain-8.3.novec-x86_64-loongarch64-linux-gnu-rc1.1.tar.xz" \ + -o gcc8-loong64-abi1.0.tar.xz || true + fi + return 1 + fi + + rm -rf gcc8-loong64-abi1.0 + mkdir gcc8-loong64-abi1.0 + if ! tar -Jxf gcc8-loong64-abi1.0.tar.xz -C gcc8-loong64-abi1.0 --strip-components=1; then + echo "Error: Failed to extract GCC toolchain" + return 1 + fi + rm gcc8-loong64-abi1.0.tar.xz + + # Setup separate cache directory for ABI1.0 to avoid cache pollution + abi1_cache_dir="$(pwd)/go-loong64-abi1.0-cache" + mkdir -p "$abi1_cache_dir" + echo "Using separate cache directory for ABI1.0: $abi1_cache_dir" + + # Use patched Go compiler for old-world build (critical for ABI1.0 compatibility) + echo "Building with patched Go compiler for old-world ABI1.0..." + echo "Using isolated cache directory: $abi1_cache_dir" + + # Use env command to set environment variables locally without affecting global environment + if ! env GOOS=linux GOARCH=loong64 \ + CC="$(pwd)/gcc8-loong64-abi1.0/bin/loongarch64-linux-gnu-gcc" \ + CXX="$(pwd)/gcc8-loong64-abi1.0/bin/loongarch64-linux-gnu-g++" \ + CGO_ENABLED=1 \ + GOCACHE="$abi1_cache_dir" \ + $(pwd)/go-loong64-abi1.0/bin/go build -a -o "$output_file" -ldflags="$ldflags" -tags=jsoniter .; then + echo "Error: Build failed with patched Go compiler" + echo "Attempting retry with cache cleanup..." + env GOCACHE="$abi1_cache_dir" $(pwd)/go-loong64-abi1.0/bin/go clean -cache + if ! env GOOS=linux GOARCH=loong64 \ + CC="$(pwd)/gcc8-loong64-abi1.0/bin/loongarch64-linux-gnu-gcc" \ + CXX="$(pwd)/gcc8-loong64-abi1.0/bin/loongarch64-linux-gnu-g++" \ + CGO_ENABLED=1 \ + GOCACHE="$abi1_cache_dir" \ + $(pwd)/go-loong64-abi1.0/bin/go build -a -o "$output_file" -ldflags="$ldflags" -tags=jsoniter .; then + echo "Error: Build failed again after cache cleanup" + echo "Build environment details:" + echo "GOOS=linux" + echo "GOARCH=loong64" + echo "CC=$(pwd)/gcc8-loong64-abi1.0/bin/loongarch64-linux-gnu-gcc" + echo "CXX=$(pwd)/gcc8-loong64-abi1.0/bin/loongarch64-linux-gnu-g++" + echo "CGO_ENABLED=1" + echo "GOCACHE=$abi1_cache_dir" + echo "Go version: $($(pwd)/go-loong64-abi1.0/bin/go version)" + echo "GCC version: $($(pwd)/gcc8-loong64-abi1.0/bin/loongarch64-linux-gnu-gcc --version | head -1)" + return 1 + fi + fi + else + # Setup abi2.0 toolchain for new world glibc build + echo "Setting up new-world ABI2.0 toolchain..." + if ! curl -fsSL --retry 3 -H "Authorization: Bearer $GITHUB_TOKEN" \ + "https://github.com/loong64/cross-tools/releases/download/20250507/x86_64-cross-tools-loongarch64-unknown-linux-gnu-legacy.tar.xz" \ + -o gcc12-loong64-abi2.0.tar.xz; then + echo "Error: Failed to download GCC toolchain for new-world ABI2.0" + if [ -n "$GITHUB_TOKEN" ]; then + echo "Error output from curl:" + curl -fsSL --retry 3 -H "Authorization: Bearer $GITHUB_TOKEN" \ + "https://github.com/loong64/cross-tools/releases/download/20250507/x86_64-cross-tools-loongarch64-unknown-linux-gnu-legacy.tar.xz" \ + -o gcc12-loong64-abi2.0.tar.xz || true + fi + return 1 + fi + + rm -rf gcc12-loong64-abi2.0 + mkdir gcc12-loong64-abi2.0 + if ! tar -Jxf gcc12-loong64-abi2.0.tar.xz -C gcc12-loong64-abi2.0 --strip-components=1; then + echo "Error: Failed to extract GCC toolchain" + return 1 + fi + rm gcc12-loong64-abi2.0.tar.xz + + export GOOS=linux + export GOARCH=loong64 + export CC=$(pwd)/gcc12-loong64-abi2.0/bin/loongarch64-unknown-linux-gnu-gcc + export CXX=$(pwd)/gcc12-loong64-abi2.0/bin/loongarch64-unknown-linux-gnu-g++ + export CGO_ENABLED=1 + + # Use standard Go compiler for new-world build + echo "Building with standard Go compiler for new-world ABI2.0..." + if ! go build -a -o "$output_file" -ldflags="$ldflags" -tags=jsoniter .; then + echo "Error: Build failed with standard Go compiler" + echo "Attempting retry with cache cleanup..." + go clean -cache + if ! go build -a -o "$output_file" -ldflags="$ldflags" -tags=jsoniter .; then + echo "Error: Build failed again after cache cleanup" + echo "Build environment details:" + echo "GOOS=$GOOS" + echo "GOARCH=$GOARCH" + echo "CC=$CC" + echo "CXX=$CXX" + echo "CGO_ENABLED=$CGO_ENABLED" + echo "Go version: $(go version)" + echo "GCC version: $($CC --version | head -1)" + return 1 + fi + fi + fi } BuildReleaseLinuxMusl() { @@ -249,6 +447,7 @@ BuildReleaseLinuxMuslArm() { done } + BuildReleaseAndroid() { rm -rf .git/ mkdir -p "build" @@ -344,7 +543,7 @@ MakeRelease() { tar -czvf compress/"$i$liteSuffix".tar.gz "$appName" rm -f "$appName" done - for i in $(find . -type f -name "$appName-windows-*"); do + for i in $(find . -type f \( -name "$appName-windows-*" -o -name "$appName-windows7-*" \)); do cp "$i" "$appName".exe zip compress/$(echo $i | sed 's/\.[^.]*$//')$liteSuffix.zip "$appName".exe rm -f "$appName".exe @@ -484,4 +683,5 @@ else echo -e " $0 release" echo -e " $0 release lite" echo -e " $0 release docker lite" + echo -e " $0 release linux_musl" fi diff --git a/wrapper/zcc-win7 b/wrapper/zcc-win7 new file mode 100644 index 00000000..59418776 --- /dev/null +++ b/wrapper/zcc-win7 @@ -0,0 +1,2 @@ +#!/bin/sh +zig cc -target x86_64-windows-gnu $@ \ No newline at end of file diff --git a/wrapper/zcc-win7-386 b/wrapper/zcc-win7-386 new file mode 100644 index 00000000..14b68a1d --- /dev/null +++ b/wrapper/zcc-win7-386 @@ -0,0 +1,2 @@ +#!/bin/sh +zig cc -target x86-windows-gnu $@ \ No newline at end of file diff --git a/wrapper/zcxx-win7 b/wrapper/zcxx-win7 new file mode 100644 index 00000000..81cef561 --- /dev/null +++ b/wrapper/zcxx-win7 @@ -0,0 +1,2 @@ +#!/bin/sh +zig c++ -target x86_64-windows-gnu $@ \ No newline at end of file diff --git a/wrapper/zcxx-win7-386 b/wrapper/zcxx-win7-386 new file mode 100644 index 00000000..ed65f1ab --- /dev/null +++ b/wrapper/zcxx-win7-386 @@ -0,0 +1,2 @@ +#!/bin/sh +zig c++ -target x86-windows-gnu $@ \ No newline at end of file