How to Build Go Executables for Multiple Operating Systems

Apr 7, 2023

Go makes it easy to build executables for various platforms / operating systems / processor architectures. Simply set the GOOS and GOARCH environment variables and run go build as usual:

GOOS="linux" GOARCH="amd64" go build -o yourProduct .

For another project, I created a bash script that builds binaries for a predefined list of binaries the entire script looks like this:

#!/bin/bash

set -e

rm -rf build

# Define the target operating systems and architectures and extension
TARGETS=(
    "linux/386/"
    "linux/amd64/"
    "linux/arm64/"
    "darwin/amd64/"
    "darwin/arm64/"
    "windows/386/.exe"
    "windows/amd64/.exe"
)

product_name="yourProduct"
start_dir="${PWD}"

for target in "${TARGETS[@]}"; do
    # Split the target operating system and architecture into separate variables
    IFS='/' read -r os arch extension <<< "${target}"

    # Define the output directory
    output_dir="build/${os}_${arch}"
    output_name="${product_name}${extension}"

    # Create the output directory if it doesn't exist
    mkdir -p "${output_dir}"

    # Build the program for the target operating system and architecture
    GOOS="${os}" GOARCH="${arch}" go build -ldflags="-s -w" -trimpath -o "${output_dir}/${output_name}" .

    # Zip the executable file
    cd "${output_dir}"
    zip "build.zip" "${output_name}"
    mv "build.zip" "../${product_name}_${os}_${arch}.zip"

    cd "${start_dir}"

    # Print a message indicating that the build was successful
    echo "Build for ${os}/${arch} successful."
done

The platforms can be defined in the TARGETS variable. You can find all valid combinations in the Go “Installing Go from source” documentation. The script creates the builds for each platform in corresponding folders and then creates a ZIP with the executable. The resulting build folder looks like this:

── build
   ├─ linux_386
   │  └─ yourProduct
   ├─ linux_amd64
   │  └─ yourProduct
   ├─ linux_arm64
   │  └─ yourProduct
   ├─ darwin_amd64
   │  └─ yourProduct
   ├─ darwin_arm64
   │  └─ yourProduct
   ├─ windows_386
   │  └─ yourProduct.exe
   ├─ windows_amd64
   │  └─ yourProduct.exe
   ├─ yourProduct_linux_386.zip
   ├─ yourProduct_linux_amd64.zip
   ├─ yourProduct_linux_arm64.zip
   ├─ yourProduct_darwin_amd64.zip
   ├─ yourProduct_darwin_arm64.zip
   ├─ yourProduct_windows_386.zip
   └─ yourProduct_windows_amd64.zip

If you need something similar, you can get the script on GitHub: serve/build.sh. I published it under BSD 3-Clause License.

Enjoy!

You might also like