#!/bin/bash set -e # Change to repo root cd "$(dirname "$0")/../" # Default values TARGET_OS="" TARGET_ARCH="" OUTPUT_NAME="memos" OUTPUT_DIR="./build" BUILD_TAGS="" EMBED_FRONTEND=true # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in --arch) TARGET_ARCH="$2" shift 2 ;; --os) TARGET_OS="$2" shift 2 ;; --output) OUTPUT_DIR="$2" shift 2 ;; --name) OUTPUT_NAME="$2" shift 2 ;; --tags) BUILD_TAGS="$2" shift 2 ;; --no-frontend) EMBED_FRONTEND=false shift 1 ;; --help|-h) echo "Usage: $0 [OPTIONS]" echo "Build Memos with embedded frontend" echo "" echo "Options:" echo " --arch ARCH Target architecture (arm, arm64, amd64, etc.)" echo " --os OS Target OS (linux, darwin, windows, etc.)" echo " --output DIR Output directory (default: ./build)" echo " --name NAME Output binary name (default: memos)" echo " --tags TAGS Build tags to use" echo " --no-frontend Build without embedding frontend" echo " --help Show this help message" echo "" echo "Examples:" echo " $0 # Build for current platform with embedded frontend" echo " $0 --arch arm64 --os linux # Cross-compile for ARM64 Linux" echo " $0 --no-frontend # Build backend only" exit 0 ;; *) echo "Unknown option: $1" exit 1 ;; esac done # Set output path if [ -n "$TARGET_OS" ] && [ -n "$TARGET_ARCH" ]; then OUTPUT_PATH="$OUTPUT_DIR/${OUTPUT_NAME}-${TARGET_OS}-${TARGET_ARCH}" if [ "$TARGET_OS" = "windows" ]; then OUTPUT_PATH="${OUTPUT_PATH}.exe" fi else OUTPUT_PATH="$OUTPUT_DIR/$OUTPUT_NAME" if [ "$(uname -s)" = "Windows_NT" ] || [ "${OSTYPE:-}" = "msys" ]; then OUTPUT_PATH="${OUTPUT_PATH}.exe" fi fi echo "Building Memos..." if [ "$EMBED_FRONTEND" = true ]; then echo "With embedded frontend" else echo "Backend only (no frontend)" fi if [ -n "$TARGET_OS" ] && [ -n "$TARGET_ARCH" ]; then echo "Target: $TARGET_OS/$TARGET_ARCH" fi echo "Output: $OUTPUT_PATH" # Ensure build directories exist mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR/.gocache" mkdir -p "$OUTPUT_DIR/.gomodcache" # Set Go environment variables export GOCACHE="$(pwd)/$OUTPUT_DIR/.gocache" export GOMODCACHE="$(pwd)/$OUTPUT_DIR/.gomodcache" BUILD_ENV="" if [ -n "$TARGET_OS" ]; then BUILD_ENV="$BUILD_ENV GOOS=$TARGET_OS" fi if [ -n "$TARGET_ARCH" ]; then BUILD_ENV="$BUILD_ENV GOARCH=$TARGET_ARCH" fi BUILD_ENV="$BUILD_ENV CGO_ENABLED=0" # Build flags BUILD_FLAGS="-o $OUTPUT_PATH" if [ -n "$BUILD_TAGS" ]; then BUILD_FLAGS="$BUILD_FLAGS -tags $BUILD_TAGS" fi BUILD_FLAGS="$BUILD_FLAGS -ldflags '-s -w'" echo "Build environment: $BUILD_ENV" echo "Build flags: $BUILD_FLAGS" # Build frontend if requested if [ "$EMBED_FRONTEND" = true ]; then echo "Building frontend..." # Check if pnpm is available if ! command -v pnpm >/dev/null 2>&1; then echo "Error: pnpm not found. Please install pnpm first." echo "Install with: npm install -g pnpm" exit 1 fi # Build frontend cd web pnpm build cd .. echo "Copying frontend assets..." # Remove old embedded files rm -rf server/router/frontend/dist # Copy new build to embedded location cp -r web/dist server/router/frontend/dist echo "Frontend embedded successfully" fi # Build the Go executable echo "Building Go backend..." eval "$BUILD_ENV go build $BUILD_FLAGS ./cmd/memos" # Verify the build if [ -f "$OUTPUT_PATH" ]; then echo "Build successful!" echo "Binary size: $(du -h "$OUTPUT_PATH" | cut -f1)" if [ -n "$TARGET_OS" ] && [ -n "$TARGET_ARCH" ]; then echo "File type: $(file "$OUTPUT_PATH")" fi # Show checksum if command -v sha256sum >/dev/null 2>&1; then echo "SHA256: $(sha256sum "$OUTPUT_PATH" | cut -d' ' -f1)" fi echo "" echo "To run:" echo " $OUTPUT_PATH --port 8081" else echo "Build failed: Output file not found" exit 1 fi