How to Build for linux/amd64 and linux/arm64 from macOS

Use Go's cross-compilation flags `GOOS` and `GOARCH` to build binaries for Linux targets directly from macOS without needing a Linux machine.

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.