Сборка исполняемых файлов (бинарников) из кода на Go — одна из ключевых сильных сторон языка. Процесс под Linux, родной платформе для многих разработчиков Go, отличается простотой, гибкостью и мощью. В этом руководстве мы разберем не только базовые команды, но и погрузимся в тонкости кросс-компиляции, статической линковки, управления зависимостями и оптимизации размера итогового файла.
Базовый процесс сборки
После установки Go (например, через пакетный менеджер вашего дистрибутива или с официального сайта) сборка сводится к одной команде в терминале, выполненной из директории с вашим проектом.
go build
Эта команда просканирует текущую директорию, найдет пакет main, скомпилирует его и все зависимости, и создаст исполняемый файл с именем, соответствующим названию директории. Вы можете явно указать исходный файл или пакет:
go build main.go
# или
go build ./cmd/myapp
По умолчанию go build создает бинарник, оптимизированный для текущей операционной системы и архитектуры процессора (например, linux/amd64). Файл будет самодостаточным и не потребует установленной среды Go для запуска.
Управление выходным файлом и платформой
Имя и расположение
Используйте флаг -o (output), чтобы задать имя и путь для результирующего бинарника.
go build -o ./bin/my-awesome-app
Кросс-компиляция: сборка под другие ОС и архитектуры
Go из коробки поддерживает кросс-компиляцию. Для этого нужно задать переменные среды GOOS (целевая операционная система) и GOARCH (целевая архитектура).
# Для сборки под Windows 64-bit
GOOS=windows GOARCH=amd64 go build -o app.exe
# Для сборки под Linux на ARM (например, Raspberry Pi)
GOOS=linux GOARCH=arm go build -o app-arm
Популярные значения: GOOS – linux, windows, darwin (macOS); GOARCH – amd64, 386, arm, arm64.
Для кросс-компиляции под некоторые платформы (например, windows/arm64) может потребоваться установка дополнительных инструментов или версия Go 1.16+. Все поддерживаемые комбинации можно посмотреть командой go tool dist list.
Продвинутые флаги и оптимизация
Статическая линковка
По умолчанию Go пытается статически слинковать все зависимости, но может динамически линковаться с некоторыми системными библиотеками (например, libc). Для создания полностью статического бинарника, который будет работать на любом совместимом Linux (даже без стандартных библиотек), используйте:
CGO_ENABLED=0 go build -o static-app
Флаг CGO_ENABLED=0 отключает использование CGo, что гарантирует полностью статическую сборку.
Управление версиями и внедрение метаданных
Вы можете внедрять информацию о версии, времени сборки или коммите Git с помощью флагов -ldflags (линкер флаги).
go build -ldflags "-X main.Version=1.0.0 -X main.BuildTime=$(date +'%Y-%m-%d_%T')" -o app
В коде программы должны быть объявлены соответствующие строковые переменные: var Version, BuildTime string.
Уменьшение размера бинарника
Для production-сборки используйте флаги, отключающие отладочную информацию и оптимизирующие бинарник:
go build -ldflags="-s -w" -o compact-app
Опции -s и -w отключают таблицу символов и информацию DWARF, что может значительно уменьшить размер файла.
Работа с зависимостями (модули Go)
Современные проекты используют систему модулей. Убедитесь, что в вашем проекте инициализирован go.mod файл:
go mod init myproject
Перед сборкой рекомендуется скачать все зависимости:
go mod tidy
Команда go build автоматически учитывает зависимости, описанные в go.mod.
Автоматизация: Makefile
Для сложных проектов удобно использовать Makefile для стандартизации сборки.
# Пример простого Makefile
APP_NAME=myapp
VERSION=1.0
build:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -X main.Version=$(VERSION)" -o bin/$(APP_NAME)
build-all:
./scripts/build-all-platforms.sh
clean:
rm -rf bin/
FAQ: Часто задаваемые вопросы
Мой бинарник не запускается на другом Linux-сервере. В чем проблема?
Скорее всего, проблема в динамических библиотеках. Соберите полностью статический бинарник с CGO_ENABLED=0 или убедитесь, что на целевом сервере установлены все необходимые библиотеки (например, glibc той же или более старой версии).
Как собрать бинарник с поддержкой CGo?
Убедитесь, что у вас установлен компилятор C (например, gcc). Затем просто выполняйте go build без CGO_ENABLED=0. Зависимости от C-библиотек будут подтянуты из системы.
Можно ли ускорить процесс сборки?
Go и так компилирует код очень быстро. Для повторных сборок кэш компилятора ($GOCACHE) ускоряет процесс. Также можно использовать флаг -i для установки скомпилированных пакетов в кэш, но для финальной сборки он не рекомендуется.
Чем отличается `go build` от `go install`?
go build создает бинарник в текущей или указанной директории. go install компилирует и устанавливает бинарник в директорию, указанную в $GOPATH/bin (или $GOBIN), делая его доступным для запуска из любого места в системе.