# Building GemReader This document provides detailed instructions on how to build the GemReader application for different platforms, with a focus on creating executable files (especially .exe files for Windows). ## Prerequisites Before building GemReader, ensure you have the following installed: - Go 1.24 or higher - Git (for cloning the repository) - A terminal/command prompt - For Windows: A modern version of Windows that supports Go compilation ## Building for Windows (.exe) ### Basic Build To build the application for Windows and create an .exe file, run the following command: ```bash go build -o gemreader.exe cmd/gemreader/main.go ``` This will create a `gemreader.exe` file in your current directory. ### Cross-compilation from Other Platforms If you're building from a non-Windows platform (Linux or macOS) and want to create a Windows executable, use these commands: ```bash GOOS=windows GOARCH=amd64 go build -o gemreader.exe cmd/gemreader/main.go ``` ### Advanced Build Options #### Building with release flags (optimized) For a more optimized build with smaller file size: ```bash go build -ldflags "-s -w" -o gemreader.exe cmd/gemreader/main.go ``` - `-s`: Omit the symbol table and debug information - `-w`: Omit the DWARF symbol table #### Building with version information To embed version information in the executable: ```bash go build -ldflags "-X main.Version=1.0.0 -s -w" -o gemreader.exe cmd/gemreader/main.go ``` ## Building for Other Platforms This section covers building the application on Windows for other operating systems using Go's cross-compilation feature. ### From Windows to Linux To build for Linux from a Windows machine, you have several options: **Option 1: Using PowerShell (Recommended)** ```powershell # For 64-bit Linux $env:GOOS="linux"; $env:GOARCH="amd64"; go build -o gemreader-linux cmd/gemreader/main.go # For 32-bit Linux $env:GOOS="linux"; $env:GOARCH="386"; go build -o gemreader-linux-386 cmd/gemreader/main.go # For ARM64 Linux $env:GOOS="linux"; $env:GOARCH="arm64"; go build -o gemreader-linux-arm64 cmd/gemreader/main.go ``` **Option 2: Using Command Prompt (CMD)** In Command Prompt, you need to set the environment variables persistently for the session: ```batch go env -w GOOS=linux go env -w GOARCH=amd64 go build -o gemreader-linux cmd/gemreader/main.go # Reset to default after building go env -w GOOS=windows go env -w GOARCH=amd64 ``` **Option 3: Temporary environment variables in PowerShell (One-liner)** ```powershell $env:GOOS="linux"; $env:GOARCH="amd64"; go build -o gemreader-linux cmd/gemreader/main.go; $env:GOOS="windows"; $env:GOARCH="amd64" ``` ### From Windows to macOS To build for macOS from a Windows machine: **Using PowerShell:** ```powershell # For Intel-based Macs $env:GOOS="darwin"; $env:GOARCH="amd64"; go build -o gemreader-mac cmd/gemreader/main.go # For Apple Silicon Macs (M1/M2/M3) $env:GOOS="darwin"; $env:GOARCH="arm64"; go build -o gemreader-mac-arm64 cmd/gemreader/main.go ``` **Using Command Prompt:** ```batch go env -w GOOS=darwin go env -w GOARCH=amd64 go build -o gemreader-mac cmd/gemreader/main.go # Reset to default after building go env -w GOOS=windows go env -w GOARCH=amd64 ``` ### Using PowerShell If you're using PowerShell instead of Command Prompt, the syntax is slightly different: ```powershell # For Linux ARM64 $env:GOOS="linux"; $env:GOARCH="arm64"; go build -o gemreader-linux-arm64 cmd/gemreader/main.go # For macOS $env:GOOS="darwin"; $env:GOARCH="arm64"; go build -o gemreader-mac-arm64 cmd/gemreader/main.go ``` ### Common GOOS and GOARCH Values | GOOS | GOARCH | Platform | | ------- | ------ | ---------------------------- | | windows | amd64 | 64-bit Windows | | windows | 386 | 32-bit Windows | | windows | arm64 | 64-bit Windows on ARM | | linux | amd64 | 64-bit Linux | | linux | 386 | 32-bit Linux | | linux | arm64 | 64-bit Linux on ARM | | darwin | amd64 | 64-bit macOS (Intel) | | darwin | arm64 | 64-bit macOS (Apple Silicon) | ### Building for Multiple Platforms You can create a batch script to build for multiple platforms at once. Here's an example `build-all.bat`: ```batch @echo off echo Building GemReader for multiple platforms... REM Create dist directory if it doesn't exist if not exist dist mkdir dist echo Building for Windows (64-bit)... go env -w GOOS=windows go env -w GOARCH=amd64 go build -ldflags "-s -w" -o dist/gemreader-windows-amd64.exe cmd/gemreader/main.go echo Building for Linux (64-bit)... go env -w GOOS=linux go env -w GOARCH=amd64 go build -ldflags "-s -w" -o dist/gemreader-linux-amd64 cmd/gemreader/main.go echo Building for macOS (Intel)... go env -w GOOS=darwin go env -w GOARCH=amd64 go build -ldflags "-s -w" -o dist/gemreader-darwin-amd64 cmd/gemreader/main.go echo Building for macOS (Apple Silicon)... go env -w GOOS=darwin go env -w GOARCH=arm64 go build -ldflags "-s -w" -o dist/gemreader-darwin-arm64 cmd/gemreader/main.go echo Resetting GOOS and GOARCH to default... go env -w GOOS=windows go env -w GOARCH=amd64 echo Build process completed! pause ``` Alternatively, you can create a PowerShell script `build-all.ps1` for more reliable cross-platform building: ```powershell Write-Host "Building GemReader for multiple platforms..." # Create dist directory if it doesn't exist if (!(Test-Path dist)) { New-Item -ItemType Directory -Path dist } # Build for Windows Write-Host "Building for Windows (64-bit)..." $env:GOOS="windows" $env:GOARCH="amd64" go build -ldflags "-s -w" -o dist/gemreader-windows-amd64.exe cmd/gemreader/main.go # Build for Linux Write-Host "Building for Linux (64-bit)..." $env:GOOS="linux" $env:GOARCH="amd64" go build -ldflags "-s -w" -o dist/gemreader-linux-amd64 cmd/gemreader/main.go # Build for macOS Intel Write-Host "Building for macOS (Intel)..." $env:GOOS="darwin" $env:GOARCH="amd64" go build -ldflags "-s -w" -o dist/gemreader-darwin-amd64 cmd/gemreader/main.go # Build for macOS Apple Silicon Write-Host "Building for macOS (Apple Silicon)..." $env:GOOS="darwin" $env:GOARCH="arm64" go build -ldflags "-s -w" -o dist/gemreader-darwin-arm64 cmd/gemreader/main.go Write-Host "Build process completed!" ``` ## Using Build Scripts For more complex builds, you can create a build script. Here's an example `build.bat` for Windows: ```batch @echo off echo Building GemReader for Windows... REM Build the application go build -ldflags "-s -w" -o gemreader.exe cmd/gemreader/main.go if %ERRORLEVEL% == 0 ( echo Build successful! gemreader.exe has been created. ) else ( echo Build failed! exit /b %ERRORLEVEL% ) ``` And a `build.sh` script for Unix-like systems: ```bash #!/bin/bash echo "Building GemReader..." # Build the application go build -ldflags "-s -w" -o gemreader cmd/gemreader/main.go if [ $? -eq 0 ]; then echo "Build successful! gemreader has been created." else echo "Build failed!" exit 1 fi ``` ## Build Targets with Go Releaser (Alternative Approach) If the project uses GoReleaser or similar tools, you can use: ```bash # Install GoReleaser if not already installed go install github.com/goreleaser/goreleaser@latest # Build all targets defined in .goreleaser.yml goreleaser build --single-target --snapshot ``` ## Troubleshooting Build Issues ### Common Issues #### Missing Dependencies If you encounter dependency issues, run: ```bash go mod tidy ``` This will ensure all dependencies are downloaded and the go.mod file is updated. #### CGO Issues If your build fails due to CGO issues (uncommon for this project), you can disable CGO: ```bash CGO_ENABLED=0 go build -o gemreader.exe cmd/gemreader/main.go ``` #### Large Executable Size If the resulting executable is too large, consider these options: 1. Use the `-ldflags "-s -w"` options as mentioned above 2. Use UPX to compress the executable (third-party tool): ```bash upx --best gemreader.exe ``` ### Checking Build Information To verify your build information, you can use: ```bash go version -m gemreader.exe ``` This will show build information about the executable. ## Production Builds For production releases, consider using these flags to create a minimal executable: ```bash go build \ -ldflags="-s -w -X main.Version=1.0.0" \ -o gemreader.exe \ cmd/gemreader/main.go ``` ## Verifying the Build After building, you can test your executable by running: ```bash # On Windows .\gemreader.exe sample.md # Or with a different markdown file .\gemreader.exe path\to\your\markdown\file.md ``` ## Build Artifacts The build process will create: - `gemreader.exe` (or platform-specific executable) - The executable is self-contained and doesn't require additional files to run - Configuration files like `config.toml` and `sample.md` can be distributed separately if needed ## Creating an Installer (Optional) For distribution purposes, you may want to create an installer for Windows using tools like: - NSIS (Nullsoft Scriptable Install System) - Inno Setup - GoReleaser with nfpm for cross-platform packaging This is outside the scope of this document but worth considering for production releases.