Что нужно построить? (идти строить против идти устанавливать)

108

Программисты-новички на Go часто не знают или не понимают, что делает основная команда сборки go.

Что именно go buildи go installкоманды строить и где они ставят результат / вывод?

icza
источник
go build vs go install
Беньямин Джафари

Ответы:

127

Что goделает команда, зависит от того, запускаем ли мы ее для «обычного» пакета или для специального "main"пакета.

Для пакетов

  • go build  строит ваш пакет, а затем отбрасывает результаты .
  • go installbuilds затем устанавливает пакет в ваш $GOPATH/pkgкаталог.

Для команд (пакет main)

  • go build  строит команду и оставляет результат в текущем рабочем каталоге .
  • go installсоздает команду во временном каталоге, а затем перемещает в него $GOPATH/bin.

На что перейти go build?

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

Если пакеты (пути импорта) не указаны, сборка применяется к текущему каталогу.

Путь импорта может содержать один или несколько "..."подстановочных знаков (в этом случае это шаблон ). ...может соответствовать любой строке, например, net/...соответствует netпакету и пакетам, находящимся в любой из его подпапок. Команда

go build ./...

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

Для получения дополнительных сведений об указании пакетов запустите go help packages.

Что касается модулей

Предварительная поддержка модулей Go была представлена ​​в Go 1.11, а модули стали стандартными, начиная с Go 1.13. Когда goинструмент запускается из папки, содержащей go.modфайл (или одного из родительских элементов текущей папки), goинструмент работает в режиме с учетом модуля (устаревший режим называется режимом GOPATH ).

В режиме с поддержкой модулей GOPATH больше не определяет значение импорта во время сборки, но по-прежнему сохраняет загруженные зависимости (в GOPATH / pkg / mod) и установленные команды (в GOPATH / bin, если GOBIN не установлен).

При сборке модулей то, что создается, указывается в списке сборки . Список сборки изначально содержит только основной модуль (модуль, содержащий каталог, в котором выполняется goкоманда), а зависимости основного модуля добавляются в список сборки рекурсивно (также добавляются зависимости зависимостей).

Для получения дополнительной информации запустите go help modules.


В основном вы можете использовать go buildв качестве проверки, что пакеты могут быть собраны (вместе с их зависимостями), а go installтакже (навсегда) устанавливают результаты в соответствующие папки вашего $GOPATH.

go build молча завершится, если все в порядке, и выдаст вам сообщения об ошибках, если пакеты не могут быть собраны / скомпилированы.

Всякий раз, когда goинструмент устанавливает пакет или двоичный файл, он также устанавливает любые зависимости, которые у него есть, поэтому запуск go installтакже автоматически установит пакеты, от которых зависит ваша программа (общедоступные, "go gettable" пакеты).

Для начала прочтите официальную страницу How to Write Go Code .

Подробнее об goинструменте: Command go

Вы также можете получить дополнительную помощь, выполнив следующую команду:

go help build

Также стоит отметить, что начиная с Go 1.5 go installтакже удаляются исполняемые файлы, созданные go build( источник ):

Если «go install» (без аргументов, то есть текущий каталог) завершается успешно, удалите исполняемый файл, записанный «go build», если он есть. Это позволяет избежать устаревших двоичных файлов ...

Чтобы завершить список, go runкомпилирует ваше приложение во временную папку и запускает этот исполняемый двоичный файл. Когда приложение закрывается, оно правильно очищает временные файлы.

Вопрос вдохновлен вопросом Дэйва Чейни « Что нужно построить?»

icza
источник
1
кажется странным, что go install не обновляет исполняемый файл, если он идентичен ранее установленному ... какие-нибудь идеи здесь?
Скотт
14

Для пакета:

go build: строит ваш пакет, а затем отбрасывает результаты

Этого не будет после Go 1.10 (1 квартал 2018 г.), спасибо CL 68116 и CL 75473 . См. Эту ветку , на которую я ссылаюсь здесь.

Что именно строят команды go buildиgo install

Всякий раз, когда инструмент go устанавливает пакет или двоичный файл, он также устанавливает любые зависимости, которые у него есть, поэтому запуск go install также автоматически установит пакеты, от которых зависит ваша программа (общедоступные, "go gettable" пакеты).

На самом деле ... go installизменится также с Go 1.10, в дополнение к новому кешу:

Команда " go install" больше не устанавливает зависимости названных пакетов ( CL 75850 ).

Если вы запустите " go install foo", будет установлено только одноfoo .

Раньше все было по-разному. Если зависимости были устаревшими, " go install" также устанавливала любые зависимости.
Неявная установка зависимостей во время " go install" вызвала много путаницы и головной боли для пользователей, но ранее было необходимо включить инкрементные сборки.
Уже нет.
Мы думаем, что новая " install what I said" семантика будет гораздо более понятной, тем более что из отчетов об ошибках ясно, что многие пользователи их уже ожидали.
Чтобы принудительно установить зависимости во время " go install", используйте новый " go install -i" по аналогии с " go build -i" и " go test -i".

Тот факт, что " go install" использовался для установки любых перестроенных зависимостей, чаще всего вызывал путаницу в связи с -a, что означает " force rebuild of all dependencies".
Теперь " go install -a myprog" приведет к полной перестройке всех зависимостей myprog, а также myprogсамого себя, но только myprogустановится. (Все перестроенные зависимости, конечно, все равно будут сохранены в кеше сборки.)
Обеспечение более понятной работы этого случая особенно важно в сочетании с новым анализом устаревания на основе содержимого, поскольку он видит веские причины для перестраивания зависимостей чаще, чем раньше. , что увеличило бы количество путаницы "почему мои зависимости были установлены".
Например, если вы запустите " go install -gcflags=-N myprog", это установитmyprogпостроен без оптимизации компилятора, но больше не переустанавливает пакеты, myprogиспользуемые из стандартной библиотеки, без оптимизации компилятора.

VonC
источник
Имеет ли go build, делать getс? У меня ошибка сборки cannot find package "github.com/spf13/cobra" in any of:…. Я не знаю, как сказать, чтобы получить это. Мне нужно явно получать?
ctrl-alt-delor
@ ctrl-alt-delor С какой версией Go? В вашем проекте есть go.modфайл?
VonC
go version go1.11.4 linux/amd64. Насчет go.mod не знаю. Я перестраиваю https://github.com/cbroglie/mustache/blob/master/cmd/mustache/main.go, это странно, поскольку я только что собрал весь пакет и использую этот пример в качестве основы, и я создал более базовую версию, которая работала (но не использую эту библиотеку). Я не вижу, как он не был установлен с пакетом усов.
ctrl-alt-delor
@ ctrl-alt-delor, так что cobr продается github.com/cbroglie/mustache/tree/master/cmd/mustache/vendor/… . Правильно ли настроен ваш GOPATH?
VonC
Я обнаружил то, что вы уже нашли. Пакет находится в подкаталоге поставщика: поэтому он не был установлен. Однако я не знаю, почему он не устанавливает его сейчас при сборке. Или как использовать каталог поставщика (если я скопирую его в свой каталог).
ctrl-alt-delor