логотип PurpleSchool
логотип PurpleSchool

Компиляция в Golang

Автор

Александр Гольцман

Golang — это компилируемый язык, что означает, что исходный код преобразуется в машинный код перед выполнением. Такой подход обеспечивает высокую производительность и независимость от интерпретатора во время работы программы. В этой статье я расскажу, как устроена компиляция в Go, какие флаги можно использовать при компиляции, как кросс-компилировать приложение для разных платформ и как оптимизировать конечный бинарный файл.

Как работает компиляция в Go

Смотрите, в Go компиляция выполняется с помощью утилиты go build, которая преобразует Go-код в исполняемый файл. Процесс включает несколько этапов:

  1. Анализ кода — проверка синтаксиса и зависимостей.
  2. Оптимизация — компилятор оптимизирует код для ускорения выполнения.
  3. Генерация машинного кода — преобразование кода в исполняемый бинарник.
  4. Линковка — объединение всех необходимых зависимостей в один файл.

В результате получается исполняемый файл, который можно запустить без дополнительных зависимостей.

Базовая компиляция

Для компиляции Go-программы достаточно выполнить команду:

go build main.go

Если у вас несколько файлов в одном пакете, можно выполнить go build без указания конкретного файла:

go build

После выполнения команды в текущей директории появится исполняемый файл с именем, соответствующим названию проекта.

Флаги компиляции

Компилятор Go поддерживает различные флаги, которые позволяют управлять процессом сборки.

Оптимизация размера

Если вам нужно уменьшить размер исполняемого файла, используйте флаги:

go build -ldflags "-s -w"
  • s — удаляет символы отладки.
  • w — удаляет информацию о таблице символов.

После такой компиляции бинарный файл будет занимать меньше места.

Генерация статически связанного бинарника

По умолчанию Go использует динамическую линковку, но можно собрать полностью автономный бинарник:

go build -tags netgo -ldflags '-extldflags "-static"'

Это полезно, если вам нужно запустить приложение на сервере без установки дополнительных библиотек.

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

Go позволяет компилировать исполняемые файлы для других операционных систем и архитектур, даже если вы работаете на другой платформе.

Компиляция для Windows

GOOS=windows GOARCH=amd64 go build -o app.exe

Компиляция для Linux

GOOS=linux GOARCH=amd64 go build -o app

Компиляция для macOS

GOOS=darwin GOARCH=amd64 go build -o app

Смотрите, здесь я использую переменные окружения GOOS и GOARCH, которые определяют операционную систему и архитектуру процессора.

Ускорение компиляции

В Go компиляция выполняется быстро по сравнению с другими языками, но для больших проектов можно дополнительно ускорить процесс.

  1. Использование кэша — Go автоматически кеширует результаты компиляции, чтобы не пересобирать неизменившиеся файлы.
  2. Включение многопоточной компиляции — компилятор Go уже использует все доступные ядра процессора, но можно вручную указать число потоков:
GOMAXPROCS=4 go build
  1. Инкрементальная компиляция — если у вас монорепозиторий, можно использовать go install, чтобы собирать только изменённые файлы:
go install ./...

Проверка бинарного файла

После компиляции можно проверить, для какой платформы и архитектуры собран исполняемый файл:

file app

Пример вывода:

app: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

Также можно посмотреть зависимые библиотеки:

ldd app

Если бинарный файл полностью статически скомпилирован, команда ldd выдаст сообщение not a dynamic executable, что подтверждает отсутствие внешних зависимостей.

Заключение

Компиляция в Go — это быстрый и удобный процесс, который позволяет получать автономные исполняемые файлы для разных платформ.

В этой статье я показал, как работает компиляция, какие флаги можно использовать для оптимизации и как выполнять кросс-компиляцию. Если вам нужно уменьшить размер бинарника — используйте -ldflags "-s -w". Если необходимо собрать приложение для другой операционной системы — просто задайте переменные GOOS и GOARCH.

Благодаря такому подходу Go идеально подходит для разработки серверных приложений, CLI-утилит и сервисов, которые можно запускать без сложных зависимостей.

Стрелочка влевоОтладка кода в GolangСтрелочка вправо

Все гайды по Golang

Работа с YAML в GolangПреобразование типов в GolangКонвертация структур в JSON в GolangStrconv в GolangИспользование пакета SQLx для работы с базами данных в GolangРазбираемся с SQL в GolangРазделение строк с помощью функции split в GolangSort в GoПоиск и замена строк в Go - GolangИспользование пакета reflect в GolangРабота с PostgreSQL в GoPointers в GolangПарсинг в GoРабота со списками (list) в GolangПреобразование int в string в GolangРабота с числами с плавающей точкой в GolangРабота с полями в GolangИспользование enum в GolangОбработка JSON в GoЧтение и запись CSV-файлов в GolangРабота с cookie в GolangРегистры в GoКэширование данных в GolangПреобразование byte в string в GolangByte в GoИспользование bufio для работы с потоками данных в GolangДобавление данных и элементов (add) в Go
Логирование в Golang. Zap, Logrus, Loki, GrafanaРабота с Docker-контейнерами в GoИспользование pprof в GolangМеханизмы синхронизации в GolangРабота с пакетом S3 в GolangМониторинг Golang приложений с помощью PrometheusОптимизация проектов на GoПаттерны проектирования в GolangМиграции базы данных в GolangОркестрация контейнеров Go с Kubernetes + DockerGjGo Playground и компилятор GolangИспользование go mod init для создания модулей GolangРабота с переменными окружения (env) в GolangКоманда go build в GolangАвтоматизация Golang проектов — CI/CD с GitLab CI и JenkinsЧтение и использование конфигурации в приложениях на GolangОтладка кода в GolangКомпиляция в GolangКак развернуть Go-приложение на облаке AWSАутентификация в Golang
Сетевые протоколы в GoПеременные в GolangЗначения в GolangДженерик %T и его применение в GolangТипы данных в GolangИспользование tls в GolangИспользование tag в структурах GolangSwitch в GoСтроки в GolangРабота с потоками (stream) в GolangSelect в GoРуны в GoРабота с пакетом params в GolangКонвертация строк в числа в GolangNull, Nil, None, 0 в GoНаименования переменных, функций и структур в GoInt в GolangУстановка GolangЧтение и установка HTTP заголовков в GolangMethods в GolangGoLand — IDE для разработки на Golang от JetBrainsОбработка «not found» в GolangFloat в GolangФлаги командной строки в Go (Golang)Запуск внешних команд в GolangОбработка ошибок в GoИспользование defer в GolangЗначения default в GolangГенерация кода в GoФорматирование кода в GolangЧистая архитектура в GolangКаналы (channels) в GolangПолучение body из HTTP запроса в Golang
Открыть базу знаний