TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸

Building executables for macOS, Linux and Windows with Go

March 28, 2021

Kurzer Guide zum Cross-Compiling mit Go. Ziel: ein Binary fuer macOS, Linux und Windows aus dem gleichen Code.

Voraussetzungen

  • Go installiert (go version)
  • Projekt hat go.mod
  • Build aus dem Projekt-Root

Grundprinzip

Go nutzt die Umgebungsvariablen:

  • GOOS = Ziel-OS (z. B. linux, windows, darwin)
  • GOARCH = Architektur (z. B. amd64, arm64)
  • CGO_ENABLED = 0 oder 1 (C-Interop)

Einfacher Build (aktuelles System)

code
go build -o bin/myapp ./cmd/myapp

Cross-Compile Beispiele

macOS (Intel):

code
GOOS=darwin GOARCH=amd64 go build -o bin/myapp-darwin-amd64 ./cmd/myapp

macOS (Apple Silicon):

code
GOOS=darwin GOARCH=arm64 go build -o bin/myapp-darwin-arm64 ./cmd/myapp

Linux (amd64):

code
GOOS=linux GOARCH=amd64 go build -o bin/myapp-linux-amd64 ./cmd/myapp

Windows (amd64):

code
GOOS=windows GOARCH=amd64 go build -o bin/myapp-windows-amd64.exe ./cmd/myapp

Alle Ziele in einem Script

code
#!/usr/bin/env bash
set -e

APP=myapp
PKG=./cmd/myapp
OUT=bin

mkdir -p "$OUT"

build() {
  local os=$1
  local arch=$2
  local ext=$3
  GOOS="$os" GOARCH="$arch" CGO_ENABLED=0 go build -o "$OUT/${APP}-${os}-${arch}${ext}" "$PKG"
}

build darwin amd64 ""
build darwin arm64 ""
build linux amd64 ""
build windows amd64 ".exe"

CGO Hinweis

Wenn dein Projekt C-Bibliotheken nutzt (z. B. SQLite via CGO), reicht CGO_ENABLED=0 nicht. Dann brauchst du einen Cross-Compiler fuer das jeweilige Ziel.

Build-Tags und Optimierungen

Kleinere Binaries

code
go build -ldflags="-s -w" -o bin/myapp ./cmd/myapp

Version ins Binary schreiben

code
go build -ldflags "-X main.version=1.2.3 -X main.commit=$(git rev-parse --short HEAD)" \
  -o bin/myapp ./cmd/myapp

In Go:

code
var version = "dev"
var commit = "none"

GOOS/GOARCH Liste

code
go tool dist list

Haeufig:

  • linux/amd64, linux/arm64
  • darwin/amd64, darwin/arm64
  • windows/amd64

Troubleshooting

  • "exec format error" -> Binary passt nicht zum System (GOOS/GOARCH falsch)
  • CGO errors -> Cross-Compiler fehlt oder CGO deaktivieren
  • "package not in module" -> falscher Build-Pfad, aus Projekt-Root bauen