add go build script

This commit is contained in:
Moustapha Kodjo Amadou 2025-07-14 14:54:33 +01:00
parent a656a158c4
commit 48ca0eb5d3

362
go/build_go.sh Executable file
View file

@ -0,0 +1,362 @@
#!/bin/bash
# Go build script for Mangayomi
# It supports Linux, macOS, Windows, Android, and iOS builds.
# to build, run:
# ./build_go.sh [linux|macos|windows|android|ios] [--all]
set -e # Stop on error
# Colors for messages
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Colored message functions
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check prerequisites
check_prerequisites() {
log_info "Checking prerequisites..."
# Check Go
if ! command -v go &> /dev/null; then
log_error "Go is not installed. Please install Go 1.22 or newer."
exit 1
fi
GO_VERSION=$(go version | grep -o 'go[0-9]\+\.[0-9]\+' | sed 's/go//')
log_info "Detected Go version: $GO_VERSION"
# Check if we're in the go directory
if [ ! -f "go.mod" ]; then
log_error "go.mod not found. Run this script from the 'go' directory of the Mangayomi project."
exit 1
fi
}
# Build for Linux
build_linux() {
log_info "Building for Linux..."
mkdir -p ../linux/bundle/lib
go build -buildmode=c-shared -ldflags="-s -w" -trimpath -o ../linux/bundle/lib/libmtorrentserver.so ./binding/desktop
log_success "Linux build completed: ../linux/bundle/lib/libmtorrentserver.so"
}
# Build for macOS
build_macos() {
log_info "Building for macOS..."
if [[ "$OSTYPE" != "darwin"* ]]; then
log_warning "macOS build requested but you're not on macOS. Build might fail."
fi
mkdir -p ../macos/Frameworks
# Build ARM64
log_info "Building macOS ARM64..."
CGO_ENABLED=1 GOARCH=arm64 go build -buildmode=c-shared -ldflags="-s -w" -trimpath -o libmtorrentserver_arm64.dylib ./binding/desktop
# Build AMD64
log_info "Building macOS AMD64..."
CGO_ENABLED=1 GOARCH=amd64 go build -buildmode=c-shared -ldflags="-s -w" -trimpath -o libmtorrentserver_amd64.dylib ./binding/desktop
# Create universal binary
if command -v lipo &> /dev/null; then
log_info "Creating universal binary..."
lipo -create -output ../macos/Frameworks/libmtorrentserver.dylib libmtorrentserver_arm64.dylib libmtorrentserver_amd64.dylib
# Clean up intermediate binaries
log_info "Cleaning up intermediate binaries..."
rm -f libmtorrentserver_arm64.dylib libmtorrentserver_amd64.dylib
rm -f libmtorrentserver_arm64.h libmtorrentserver_amd64.h
log_success "macOS build completed: ../macos/Frameworks/libmtorrentserver.dylib (universal)"
else
log_warning "lipo not available. Separate binaries are available."
fi
}
# Build for Windows
build_windows() {
log_info "Building for Windows..."
mkdir -p ../windows
# Configure environment for Windows
export CGO_ENABLED=1
export CC=gcc
export GOARCH=amd64
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
# Native Windows
go build -buildmode=c-shared -ldflags="-s -w -extldflags=-static" -trimpath -o ../windows/libmtorrentserver.dll ./binding/desktop
else
# Cross-compilation from Unix
if command -v x86_64-w64-mingw32-gcc &> /dev/null; then
export CC=x86_64-w64-mingw32-gcc
export GOOS=windows
go build -buildmode=c-shared -ldflags="-s -w -extldflags=-static" -trimpath -o ../windows/libmtorrentserver.dll ./binding/desktop
else
log_error "Windows cross-compiler not found. Install mingw-w64."
return 1
fi
fi
log_success "Windows build completed: ../windows/libmtorrentserver.dll"
}
# Build for Android
build_android() {
log_info "Building for Android..."
# Check gomobile
if ! command -v gomobile &> /dev/null; then
log_info "Installing gomobile..."
go install golang.org/x/mobile/cmd/gomobile@latest
go install golang.org/x/mobile/cmd/gobind@latest
# Add GOPATH/bin to PATH if necessary
export PATH=$PATH:$(go env GOPATH)/bin
# Initialize gomobile
log_info "Initializing gomobile..."
gomobile init -v
fi
# Check Android NDK
if [ -z "$ANDROID_NDK_HOME" ] && [ -z "$ANDROID_NDK_ROOT" ]; then
log_warning "ANDROID_NDK_HOME or ANDROID_NDK_ROOT not defined. Android build might fail."
log_warning "Install Android Studio and NDK, then set the environment variable."
log_warning "Example: export ANDROID_NDK_HOME=/path/to/android/sdk/ndk/25.2.9519653"
fi
# Check Java JDK
if ! javac -version &> /dev/null; then
log_warning "javac (Java Development Kit) not working. Android build might fail."
log_warning "Install Oracle JDK or OpenJDK and configure JAVA_HOME."
log_warning "On macOS: brew install openjdk@11"
log_warning "Then: export JAVA_HOME=\$(brew --prefix openjdk@11)"
fi
go get -u golang.org/x/mobile
log_info "Building Android AAR..."
mkdir -p ../android/app/libs
# Try Android build with enhanced error handling
# Uses -checklinkname=0 and -tags to allow anet v0.0.5 usage (solution inspired by Gopeed)
if ! gomobile bind -v -tags mobile -target=android/arm,android/arm64,android/amd64,android/386 -androidapi 21 -ldflags="-s -w -checklinkname=0" -trimpath -o ../android/app/libs/libmtorrentserver.aar ./binding/mobile; then
log_error "Android build failed."
log_error "Common error: 'invalid reference to net.zoneCache'"
log_error ""
log_error "Possible solutions:"
log_error "1. Install and configure Android NDK correctly:"
log_error " - Download Android Studio"
log_error " - Install Android NDK via SDK Manager"
log_error " - Set ANDROID_NDK_HOME"
log_error ""
log_error "2. Update Go to latest version:"
log_error " - current go version: $(go version)"
log_error " - Recommended: Go 1.21 or newer"
log_error ""
log_error "3. Known issue with github.com/wlynxg/anet:"
log_error " - This package uses internal Go APIs"
log_error " - Applied solution: replace directive in go.mod"
log_error ""
log_error "4. Check Java JDK installation:"
log_error " - Install JDK: brew install openjdk@11"
log_error " - Set JAVA_HOME: export JAVA_HOME=\$(brew --prefix openjdk@11)"
log_error ""
log_error "5. Alternative - Desktop build only:"
log_error " ./build_go.sh linux macos windows"
return 1
fi
rm -f ../android/app/libs/libmtorrentserver-sources.jar
log_success "Android build completed: ../android/app/libs/libmtorrentserver.aar"
}
# Build for iOS
build_ios() {
log_info "Building for iOS..."
if [[ "$OSTYPE" != "darwin"* ]]; then
log_error "iOS build is only possible on macOS."
return 1
fi
# Check Xcode
if ! command -v xcodebuild &> /dev/null; then
log_error "Xcode is not installed."
return 1
fi
# Check gomobile
if ! command -v gomobile &> /dev/null; then
log_info "Installing gomobile..."
go install golang.org/x/mobile/cmd/gomobile@latest
go install golang.org/x/mobile/cmd/gobind@latest
# Add GOPATH/bin to PATH if necessary
export PATH=$PATH:$(go env GOPATH)/bin
# Initialize gomobile
log_info "Initializing gomobile..."
gomobile init -v
fi
go get -u golang.org/x/mobile
log_info "Building iOS XCFramework..."
mkdir -p ../ios/Frameworks
# Uses same optimizations as Android for anet v0.0.5 compatibility
gomobile bind -v -tags mobile -target=ios,iossimulator -ldflags="-s -w -checklinkname=0" -trimpath -o ../ios/Frameworks/libmtorrentserver.xcframework ./binding/mobile
log_success "iOS build completed: ../ios/Frameworks/libmtorrentserver.xcframework"
}
# Show help
show_help() {
echo "Usage: $0 [OPTIONS] [TARGETS]"
echo ""
echo "OPTIONS:"
echo " -h, --help Show this help"
echo " -a, --all Build for all supported platforms"
echo ""
echo "TARGETS:"
echo " linux Build for Linux"
echo " macos Build for macOS"
echo " windows Build for Windows"
echo " android Build for Android"
echo " ios Build for iOS"
echo ""
echo "Examples:"
echo " $0 linux macos # Build for Linux and macOS"
}
# Variables
BUILD_ALL=false
TARGETS=()
# Parser les arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-a|--all)
BUILD_ALL=true
shift
;;
linux|macos|windows|android|ios)
TARGETS+=("$1")
shift
;;
*)
log_error "Unknown option: $1"
show_help
exit 1
;;
esac
done
# Main
main() {
log_info "Starting Go build for Mangayomi"
check_prerequisites
if [ "$BUILD_ALL" = true ]; then
TARGETS=("linux" "macos" "windows" "android" "ios")
fi
if [ ${#TARGETS[@]} -eq 0 ]; then
log_warning "No target specified. Building for current platform..."
case "$OSTYPE" in
linux*) TARGETS=("linux") ;;
darwin*) TARGETS=("macos") ;;
msys*|win32*) TARGETS=("windows") ;;
*)
log_error "Unsupported platform: $OSTYPE"
show_help
exit 1
;;
esac
fi
# Build for each target
for target in "${TARGETS[@]}"; do
log_info "--- Building for: $target ---"
case $target in
linux)
if build_linux; then
log_success "✅ Build $target successful"
else
log_error "❌ Build $target failed"
fi
;;
macos)
if build_macos; then
log_success "✅ Build $target successful"
else
log_error "❌ Build $target failed"
fi
;;
windows)
if build_windows; then
log_success "✅ Build $target successful"
else
log_error "❌ Build $target failed"
fi
;;
android)
if build_android; then
log_success "✅ Build $target successful"
else
log_error "❌ Build $target failed"
log_warning "Android build may fail due to compatibility issues"
log_warning "Other platforms should work normally"
fi
;;
ios)
if build_ios; then
log_success "✅ Build $target successful"
else
log_error "❌ Build $target failed"
fi
;;
*)
log_error "Unknown target: $target"
;;
esac
echo "" # Empty line for readability
done
}
# Execute main script
main "$@"