Что на самом деле делает `go build`? Разбираемся с `go build` vs `go install`
Краткий ответ: `go build` собирает здесь и сейчас, `go install` — собирает и убирает в системную папку
Вы всё верно подметили. Разница между этими командами — в том, куда попадает результат сборки. Давайте разложим по полочкам.
Что делает `go build`?
Команда go build компилирует пакет (или пакеты) и все его зависимости. Если вы собираете main-пакет (тот, который содержит package main и функцию main()), то результатом будет исполняемый бинарный файл. Если вы собираете обычный пакет (библиотеку) — результата в виде файла вы не увидите, компилятор только проверит, что код собирается без ошибок.
По умолчанию бинарник для main-пакета создаётся в текущей рабочей директории (той, откуда вы вызвали команду). Имя файла совпадает с именем папки, в которой лежит main-пакет.
# Пример: у вас проект "myapp" с main.go
cd myapp
go build
# Результат: ./myapp (или myapp.exe на Windows)
Что делает `go install`?
Команда go install делает то же самое, что и go build, но с одним важным отличием: она устанавливает результат в стандартное место:
- Для main-пакетов бинарник помещается в
$GOPATH/bin(или$GOBIN, если эта переменная задана). - Для обычных пакетов (библиотек) скомпилированные объектные файлы (.a) помещаются в
$GOPATH/pkg.
После go install вы не увидите бинарника в папке проекта — он «переехал» в системную директорию. Это сделано для того, чтобы ваши программы были доступны из любого места в командной строке (если $GOPATH/bin добавлен в PATH).
go install
# Результат: $GOPATH/bin/myapp (myapp.exe на Windows)
# В текущей папке бинарника нет!
А что насчёт зависимостей?
Ни go build, ни go install не устанавливают внешние зависимости. Они только компилируют уже скачанные пакеты. Если у вас в коде есть import "example.com/somepackage", то:
go buildнайдёт этот пакет в$GOPATH/pkg/mod(или в vendor) и скомпилирует его вместе с вашим кодом.- Если пакета нет, команда завершится с ошибкой.
Для загрузки зависимостей существует отдельная команда go mod download или go mod tidy. А go install (начиная с Go 1.16) может устанавливать конкретные версии утилит, например: go install golang.org/x/tools/cmd/goimports@latest. Но это уже другая история.
Когда что использовать?
go build— когда вы разрабатываете и хотите быстро проверить, что проект собирается, или получить бинарник «прямо здесь» для тестирования.go install— когда вы хотите установить готовую программу в систему, чтобы вызывать её из любого места (например, утилиты командной строки вродеgolangci-lint).go build -o output.exe— когда нужно явно указать имя и путь для бинарника.
Итог
Представьте, что go build — это «собрать на столе», а go install — «собрать и положить на полку в инструментальный ящик». Обе команды делают одно и то же с точки зрения компиляции, но различаются местом размещения результата.
Дополнение: флаг `-i` и исторический контекст
В более старых версиях Go (до 1.16) у команды go build был флаг -i, который заставлял её устанавливать зависимости в $GOPATH/pkg. Многие путались, думая, что go build -i — это то же самое, что go install. На самом деле нет: go build -i всё равно оставлял бинарник в текущей папке, но дополнительно кешировал скомпилированные зависимости.
Начиная с Go 1.16, флаг -i был объявлен устаревшим, а в Go 1.18 его убрали полностью. Теперь поведение чёткое:
go build— только компиляция в текущую директорию (для main-пакетов).go install— компиляция + установка в$GOPATH/bin(для main) или$GOPATH/pkg(для библиотек).
Также стоит помнить про go run — это команда, которая компилирует и сразу запускает программу, не оставляя бинарника на диске. Идеально для быстрых экспериментов.
Если вы используете модули (Go Modules), то папка $GOPATH/pkg/mod содержит кеш всех скачанных зависимостей, и ни go build, ни go install его не трогают — они только читают оттуда готовые исходники.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги
Монорепозиторий с Swift: организация кода для iOS и macOS
HTTP клиент на Swift: делаем запросы правильно