# Build script for ekDNSHelper # Builds the executables using the go1.20 toolchain # # USAGE: # .\build.ps1 # Standard build for current platform (Windows amd64) # .\build.ps1 -Release # Build for all platforms (no debug symbols) # .\build.ps1 -Clean # Clean build (removes old files first) # .\build.ps1 -CrossCompile # Build for all platforms # .\build.ps1 -Package # Create release packages (ZIP / tar.gz) # .\build.ps1 -Release -Package # Full release: optimized build + packages # # OUTPUT: # - Default build: build\ekdns.exe # - Cross-compiled: build\ekdns--[.exe] # - Release packages: releases\ekdns---.zip / .tar.gz param( [string]$OutputDir = "build", [string]$OutputName = "ekdns", [switch]$Release, [switch]$Clean, [switch]$CrossCompile, [switch]$Package ) $ErrorActionPreference = "Stop" # Go binary — use go1.20 toolchain $GoCmd = "go1.20" # Get version information from git or use defaults $gitHash = "unknown" $gitTag = "dev" $prevErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = "Continue" try { $gitHashResult = git rev-parse --short HEAD 2>&1 if ($LASTEXITCODE -eq 0 -and $gitHashResult -and $gitHashResult -notmatch "fatal|error") { $gitHash = $gitHashResult.Trim() } $gitTagResult = git describe --tags --always --dirty 2>&1 if ($LASTEXITCODE -eq 0 -and $gitTagResult -and $gitTagResult -notmatch "fatal|error") { $gitTag = $gitTagResult.Trim() } } catch { # Git not available or not a git repository — use defaults } $ErrorActionPreference = $prevErrorActionPreference $buildTime = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ" Write-Host "============================================" -ForegroundColor Cyan Write-Host " ekDNSHelper Build" -ForegroundColor Cyan Write-Host "============================================" -ForegroundColor Cyan Write-Host "" Write-Host " Version: $gitTag" -ForegroundColor Gray Write-Host " Commit: $gitHash" -ForegroundColor Gray Write-Host " Time: $buildTime" -ForegroundColor Gray Write-Host "" # Clean output directory if requested if ($Clean) { Write-Host "Cleaning output directory..." -ForegroundColor Yellow if (Test-Path $OutputDir) { Remove-Item -Path $OutputDir -Recurse -Force } Write-Host "Cleaning Go caches..." -ForegroundColor Yellow & $GoCmd clean -cache -testcache 2>$null } # Ensure output directory exists if (-not (Test-Path $OutputDir)) { New-Item -ItemType Directory -Path $OutputDir | Out-Null Write-Host "Created output directory: $OutputDir" -ForegroundColor Green } # Build flags — always inject version and copyright year; release builds also strip debug symbols. $buildYear = (Get-Date).Year $injectedFlags = "-X main.version=$gitTag -X main.copyrightYear=$buildYear" if ($Release) { $ldflags = "-s -w $injectedFlags" Write-Host "Building RELEASE version (optimized, no debug symbols)..." -ForegroundColor Green } else { $ldflags = $injectedFlags Write-Host "Building DEBUG version (with debug symbols)..." -ForegroundColor Yellow } # Disable CGO for static binaries $env:CGO_ENABLED = "0" $platforms = @( @{ GOOS = "windows"; GOARCH = "386"; Suffix = ".exe" }, @{ GOOS = "windows"; GOARCH = "amd64"; Suffix = ".exe" }, @{ GOOS = "linux"; GOARCH = "amd64"; Suffix = "" }, @{ GOOS = "linux"; GOARCH = "arm64"; Suffix = "" }, @{ GOOS = "darwin"; GOARCH = "amd64"; Suffix = "" }, @{ GOOS = "darwin"; GOARCH = "arm64"; Suffix = "" } ) function Build-Binary { param( [string]$GOOS, [string]$GOARCH, [string]$OutputPath ) $env:GOOS = $GOOS $env:GOARCH = $GOARCH if ($ldflags) { & $GoCmd build -ldflags $ldflags -o $OutputPath . } else { & $GoCmd build -o $OutputPath . } return $LASTEXITCODE } try { if ($CrossCompile -or $Release) { Write-Host "Cross-compiling for all platforms..." -ForegroundColor Cyan Write-Host "" foreach ($platform in $platforms) { $outputFile = "$OutputName-$($platform.GOOS)-$($platform.GOARCH)$($platform.Suffix)" $outputPath = Join-Path $OutputDir $outputFile Write-Host " Building $outputFile..." -ForegroundColor Gray $result = Build-Binary -GOOS $platform.GOOS -GOARCH $platform.GOARCH -OutputPath $outputPath if ($result -eq 0) { $fileSizeMB = [math]::Round((Get-Item $outputPath).Length / 1MB, 2) Write-Host " [OK] $fileSizeMB MB" -ForegroundColor Green } else { Write-Host " [FAILED]" -ForegroundColor Red exit $result } } Write-Host "" Write-Host "Cross-compilation complete!" -ForegroundColor Green } else { $outputPath = Join-Path $OutputDir "$OutputName.exe" Write-Host "Compiling for Windows (amd64)..." -ForegroundColor Cyan $result = Build-Binary -GOOS "windows" -GOARCH "amd64" -OutputPath $outputPath if ($result -eq 0) { $fileSizeMB = [math]::Round((Get-Item $outputPath).Length / 1MB, 2) Write-Host "Build successful!" -ForegroundColor Green Write-Host " Output: $outputPath" -ForegroundColor Gray Write-Host " Size: $fileSizeMB MB" -ForegroundColor Gray } else { Write-Host "Build failed with exit code: $result" -ForegroundColor Red exit $result } } } catch { Write-Host "Build error: $_" -ForegroundColor Red exit 1 } Write-Host "" Write-Host "Build complete!" -ForegroundColor Green Write-Host "" Write-Host "Usage:" -ForegroundColor Cyan Write-Host " .\$OutputDir\$OutputName.exe --help" -ForegroundColor White Write-Host " .\$OutputDir\$OutputName.exe add " -ForegroundColor White # Create release packages if requested if ($Package) { Write-Host "" Write-Host "============================================" -ForegroundColor Cyan Write-Host " Creating Release Packages" -ForegroundColor Cyan Write-Host "============================================" -ForegroundColor Cyan Write-Host "" $releasesDir = "releases" if (-not (Test-Path $releasesDir)) { New-Item -ItemType Directory -Path $releasesDir | Out-Null Write-Host "Created releases directory: $releasesDir" -ForegroundColor Green } foreach ($platform in $platforms) { $platformName = "$($platform.GOOS)-$($platform.GOARCH)" $packageName = "$OutputName-$gitTag-$platformName" $packageDir = Join-Path $releasesDir $packageName $isWindowsPlatform = $platform.GOOS -eq "windows" if ($isWindowsPlatform) { $archivePath = "$packageDir.zip" $exeName = "$OutputName.exe" } else { $archivePath = "$packageDir.tar.gz" $exeName = $OutputName } Write-Host "Creating package for $platformName..." -ForegroundColor Cyan if (Test-Path $packageDir) { Remove-Item -Path $packageDir -Recurse -Force } if (Test-Path $archivePath) { try { Remove-Item -Path $archivePath -Force -ErrorAction Stop } catch { Write-Host " Warning: Could not remove old package (file may be in use)" -ForegroundColor Yellow continue } } New-Item -ItemType Directory -Path $packageDir | Out-Null # Copy the binary $binaryFile = "$OutputName-$platformName$($platform.Suffix)" $binaryPath = Join-Path $OutputDir $binaryFile if (-not (Test-Path $binaryPath)) { Write-Host " Error: Binary not found at $binaryPath. Run build first." -ForegroundColor Red continue } Copy-Item -Path $binaryPath -Destination (Join-Path $packageDir $exeName) # Copy README if present if (Test-Path "README.md") { Copy-Item -Path "README.md" -Destination (Join-Path $packageDir "README.md") } # VERSION.txt @" ekDNSHelper Version Information =============================== Version: $gitTag Git Commit: $gitHash Build Time: $buildTime Platform: $platformName Run '$exeName --help' for usage information. "@ | Out-File -FilePath (Join-Path $packageDir "VERSION.txt") -Encoding UTF8 # CHECKSUMS.txt $exeHash = (Get-FileHash -Path (Join-Path $packageDir $exeName) -Algorithm SHA256).Hash @" ekDNSHelper Release Checksums Version: $gitTag Build: $gitHash Platform: $platformName SHA256 Checksums: ----------------- $exeName $exeHash To verify (PowerShell): `$hash = (Get-FileHash -Path $exeName -Algorithm SHA256).Hash if (`$hash -eq "$exeHash") { Write-Host "Verified!" -ForegroundColor Green } To verify (Linux/macOS): echo "$exeHash $exeName" | sha256sum -c - "@ | Out-File -FilePath (Join-Path $packageDir "CHECKSUMS.txt") -Encoding UTF8 # Create archive try { if ($isWindowsPlatform) { Compress-Archive -Path "$packageDir\*" -DestinationPath $archivePath -CompressionLevel Optimal -Force } else { Push-Location $releasesDir try { tar -czf "$packageName.tar.gz" -C . $packageName 2>$null if ($LASTEXITCODE -ne 0) { Write-Host " Warning: tar not available, using ZIP format" -ForegroundColor Yellow $archivePath = "$packageDir.zip" Compress-Archive -Path "$packageDir\*" -DestinationPath $archivePath -CompressionLevel Optimal -Force } } finally { Pop-Location } } $archiveSizeMB = [math]::Round((Get-Item $archivePath).Length / 1MB, 2) Remove-Item -Path $packageDir -Recurse -Force Write-Host " [OK] $archivePath ($archiveSizeMB MB)" -ForegroundColor Green } catch { Write-Host " Error creating package: $_" -ForegroundColor Red if (Test-Path $packageDir) { Remove-Item -Path $packageDir -Recurse -Force } } } Write-Host "" Write-Host "Release packaging complete!" -ForegroundColor Green Write-Host "" Write-Host "Package contents:" -ForegroundColor Cyan Write-Host " - ekdns executable" -ForegroundColor Gray Write-Host " - README.md (if present)" -ForegroundColor Gray Write-Host " - VERSION.txt" -ForegroundColor Gray Write-Host " - CHECKSUMS.txt (integrity verification)" -ForegroundColor Gray }