Use Go's cross-compilation flags GOOS and GOARCH to build binaries for Linux targets directly from macOS without needing a Linux machine. You can either run two separate build commands or use a single command with GOOS and GOARCH set to build for both architectures sequentially.
Here are two practical approaches. The first uses a simple shell loop to generate both binaries in one go, which is ideal for quick local builds:
#!/bin/bash
for arch in amd64 arm64; do
GOOS=linux GOARCH=$arch go build -o myapp-linux-$arch ./main.go
done
This script iterates through the target architectures, setting the environment variables for each iteration. It produces two distinct binaries: myapp-linux-amd64 and myapp-linux-arm64.
For more complex projects where you need to manage build tags, versioning, or output directories, using a make file or a dedicated build tool like gox or gomplate is cleaner. Here is a Makefile snippet that handles the build and organizes the output into a dist folder:
.PHONY: build-linux
build-linux:
@mkdir -p dist
@echo "Building linux/amd64..."
GOOS=linux GOARCH=amd64 go build -o dist/myapp-amd64 .
@echo "Building linux/arm64..."
GOOS=linux GOARCH=arm64 go build -o dist/myapp-arm64 .
@echo "Done. Binaries are in ./dist/"
When running these commands on macOS, ensure your Go version is reasonably up to date (1.18+ is recommended) to avoid issues with newer Linux kernel features or glibc versions. If your application relies on CGO, you must install the corresponding Linux cross-compilation toolchain (e.g., gcc for the target architecture) and set CC and CXX environment variables, as the default macOS toolchain cannot compile C code for Linux. For pure Go applications, no extra dependencies are required.
After building, you can verify the architecture of the resulting binaries using the file command on macOS:
file dist/myapp-amd64 dist/myapp-arm64
You should see output indicating ELF 64-bit LSB executable, x86-64 for the amd64 binary and ELF 64-bit LSB executable, ARM aarch64 for the arm64 binary. This confirms the cross-compilation was successful and the binaries are ready for deployment on Linux servers.