Содержание

Сборка Go-приложений в бинарник

go run vs go build

Во время разработки вы запускаете программу через go run main.go. Это удобно: Go компилирует код "на лету" и сразу запускает. Но для распространения программы это не подходит — у пользователя может не быть Go.

go build компилирует исходный код в нативный бинарник — один исполняемый файл, который:

  • Не требует установленного Go
  • Не требует исходного кода
  • Не требует интернета или зависимостей
  • Запускается на любой совместимой системе

Это одна из причин популярности Go для CLI-инструментов и серверов: Docker, Kubernetes, Terraform, Hugo — все написаны на Go и распространяются как один бинарник.

Базовая сборка

Простейший вариант

go build

Создаст бинарник с именем текущей директории (или модуля из go.mod).

Указать имя выходного файла

go build -o myapp

Создаст файл myapp (на Windows автоматически добавится .exe).

Собрать конкретный файл

go build -o myapp main.go

Проверить без создания файла

go build -n

Покажет, что будет выполнено, но ничего не создаст. Полезно для отладки процесса сборки.

Что происходит при сборке

  1. Парсинг — Go читает исходные файлы и строит AST (абстрактное синтаксическое дерево)
  2. Проверка типов — статический анализ, поиск ошибок
  3. Компиляция — преобразование в машинный код для целевой платформы
  4. Линковка — объединение кода вашей программы, стандартной библиотеки и зависимостей в один файл

Результат — статически слинкованный бинарник. Все зависимости "вшиты" внутрь. Никаких .dll или .so файлов рядом не нужно.

# Посмотреть размер бинарника ls -lh myapp # Посмотреть, от чего зависит (на Linux) ldd myapp # Вывод: "not a dynamic executable" — зависимостей нет

Кросс-компиляция

Go умеет собирать бинарники для других операционных систем и архитектур. Работаете на macOS, а нужен бинарник для Linux-сервера? Две переменные окружения:

# Для Linux (64-bit) GOOS=linux GOARCH=amd64 go build -o myapp-linux # Для Windows (64-bit) GOOS=windows GOARCH=amd64 go build -o myapp.exe # Для macOS на Apple Silicon GOOS=darwin GOARCH=arm64 go build -o myapp-mac-arm # Для Raspberry Pi (ARM) GOOS=linux GOARCH=arm64 go build -o myapp-raspi

Основные значения

GOOS (операционная система):

ЗначениеОС
linuxLinux
darwinmacOS
windowsWindows
freebsdFreeBSD

GOARCH (архитектура процессора):

ЗначениеАрхитектура
amd64Intel/AMD 64-bit (большинство серверов и ПК)
arm64ARM 64-bit (Apple Silicon, ARM серверы, Raspberry Pi 4)
386Intel/AMD 32-bit (устаревшее)
armARM 32-bit (старые Raspberry Pi)
# Посмотреть все поддерживаемые комбинации go tool dist list

Оптимизация размера бинарника

По умолчанию бинарник содержит отладочную информацию. Для продакшена можно её убрать:

go build -ldflags="-s -w" -o myapp
ФлагЧто убираетЭкономия
-sТаблицу символов~20-25%
-wDWARF отладочную информацию~5-10%

Пример: бинарник 10 MB → 7 MB.

Внедрение данных при сборке

Через -ldflags можно задать значения переменных прямо при компиляции. Это полезно для версии, даты сборки, коммита.

Пример: версия приложения

package main import "fmt" // Значение задаётся при сборке var version = "dev" func main() { fmt.Printf("myapp version %s\n", version) }

Сборка с версией:

go build -ldflags="-X main.version=1.0.0" -o myapp

Теперь ./myapp выведет myapp version 1.0.0.

Автоматизация через git

# Взять версию из git-тега VERSION=$(git describe --tags --always) go build -ldflags="-X main.version=$VERSION" -o myapp # Добавить дату сборки BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ) go build -ldflags="-X main.version=$VERSION -X main.buildTime=$BUILD_TIME" -o myapp

Комбинирование флагов

# Версия + оптимизация размера go build -ldflags="-s -w -X main.version=1.0.0" -o myapp

Сборка для продакшена

Типичная команда для production-сборки:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ go build -ldflags="-s -w -X main.version=$(git describe --tags)" \ -o myapp

Что здесь:

  • CGO_ENABLED=0 — отключает CGO, гарантирует полностью статический бинарник
  • GOOS=linux GOARCH=amd64 — целевая платформа
  • -ldflags="-s -w" — убираем отладочную информацию
  • -X main.version=... — внедряем версию

Makefile для сборки

Для повторяемой сборки удобно использовать Makefile:

VERSION := $(shell git describe --tags --always) BUILD_TIME := $(shell date -u +%Y-%m-%dT%H:%M:%SZ) LDFLAGS := -s -w -X main.version=$(VERSION) -X main.buildTime=$(BUILD_TIME) .PHONY: build build-linux build-windows clean build: go build -ldflags="$(LDFLAGS)" -o myapp build-linux: GOOS=linux GOARCH=amd64 go build -ldflags="$(LDFLAGS)" -o myapp-linux build-windows: GOOS=windows GOARCH=amd64 go build -ldflags="$(LDFLAGS)" -o myapp.exe build-all: build build-linux build-windows clean: rm -f myapp myapp-linux myapp.exe

Использование:

make build # Собрать для текущей ОС make build-linux # Собрать для Linux make build-all # Собрать для всех платформ make clean # Удалить бинарники

Шпаргалка

# Базовая сборка go build go build -o myapp # Кросс-компиляция GOOS=linux GOARCH=amd64 go build -o myapp-linux GOOS=windows GOARCH=amd64 go build -o myapp.exe GOOS=darwin GOARCH=arm64 go build -o myapp-mac # Оптимизация размера go build -ldflags="-s -w" -o myapp # Внедрение версии go build -ldflags="-X main.version=1.0.0" -o myapp # Production-сборка CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=1.0.0" -o myapp

Полезные ресурсы

Следующий шаг после статьи

Закрепите тему во вводном проекте без регистрации, а затем переходите к курсам.

Продолжить изучение

Выбери следующую статью по маршруту или углубись в смежную тему.

Похожие статьи