O que vai construir construir? (vá construir x vá instalar)

106

Os novos programadores de Go geralmente não sabem ou ficam confusos com o que o comando fundamental go build faz.

O que exatamente os comandos go builde go installconstroem e onde eles colocam o resultado / saída?

icza
fonte

Respostas:

125

O que o gocomando faz depende se o executamos para um pacote "normal" ou para o "main"pacote especial .

Para pacotes

  • go build  constrói seu pacote e então descarta os resultados .
  • go installcompila e instala o pacote em seu $GOPATH/pkgdiretório.

Para comandos (pacote main)

  • go build  constrói o comando e deixa o resultado no diretório de trabalho atual .
  • go installcria o comando em um diretório temporário e o move para $GOPATH/bin.

Para o que passar go build?

Você pode passar pacotes para os go buildpacotes que deseja construir. Você também pode passar uma lista de .goarquivos de um único diretório, que é então tratada como a lista de arquivos de origem especificando um único pacote.

Se nenhum pacote (caminhos de importação) for fornecido, a construção será aplicada ao diretório atual.

Um caminho de importação pode conter um ou mais "..."curingas (nesse caso, é um padrão ). ...pode corresponder a qualquer string, por exemplo, net/...corresponde ao netpacote e aos pacotes que estão em qualquer uma de suas subpastas. O comando

go build ./...

freqüentemente usado para construir o pacote na pasta atual e todos os pacotes retornando para baixo. Este comando emitido em uma raiz de projeto constrói o projeto completo.

Para mais informações sobre como especificar pacotes, execute go help packages.

Em relação aos módulos

O suporte preliminar para módulos Go foi introduzido no Go 1.11 e os módulos se tornaram padrão a partir do Go 1.13. Quando a goferramenta é executada a partir de uma pasta que contém um go.modarquivo (ou um dos pais da pasta atual), a goferramenta é executada no modo com reconhecimento de módulo (o modo legado é denominado modo GOPATH ).

No modo de reconhecimento de módulo, GOPATH não define mais o significado das importações durante uma construção, mas ainda armazena dependências baixadas (em GOPATH / pkg / mod) e comandos instalados (em GOPATH / bin, a menos que GOBIN seja definido).

Ao construir módulos, o que é construído é especificado pela lista de construção . A lista de construção contém inicialmente apenas o módulo principal (o módulo que contém o diretório onde o gocomando é executado), e as dependências do módulo principal são adicionadas à lista de construção, recursivamente (as dependências das dependências também são adicionadas).

Para mais informações, execute go help modules.


Basicamente, você pode usar go buildcomo uma verificação se os pacotes podem ser compilados (junto com suas dependências) enquanto go installtambém (permanentemente) instala os resultados nas pastas apropriadas do seu $GOPATH.

go build será encerrado silenciosamente se tudo estiver OK e fornecerá mensagens de erro se os pacotes não puderem ser compilados / compilados.

Sempre que a goferramenta instala um pacote ou binário, ela também instala todas as dependências que possui, portanto, a execução go installtambém instalará os pacotes dos quais seu programa depende (disponíveis publicamente, pacotes "go gettable"), automaticamente.

Para começar, leia a página oficial How to Write Go Code .

Mais informações sobre a goferramenta: Command go

Você também pode obter mais ajuda executando o seguinte comando:

go help build

Também é importante notar que a partir do Go 1.5 go installtambém remove os executáveis ​​criados por go build( fonte ):

Se 'go install' (sem argumentos, significando o diretório atual) for bem-sucedido, remova o executável escrito por 'go build', se presente. Isso evita deixar um binário obsoleto para trás ...

Para completar a lista, go runcompila seu aplicativo em uma pasta temporária e inicia o binário executável. Quando o aplicativo é encerrado, ele limpa corretamente os arquivos temporários.

Pergunta inspirada no livro de Dave Cheney What does go build build?

icza
fonte
1
parece estranho que go install não atualize o executável se for idêntico ao instalado anteriormente ... alguma ideia aqui?
Scott Stensland
14

Para pacote:

go build: cria seu pacote e depois descarta os resultados

Isso não será verdade depois do Go 1.10 (primeiro trimestre de 2018), graças a CL 68116 e CL 75473 . Veja este tópico , que faço referência aqui.

O que exatamente os comandos go builde go installconstroem

Sempre que a ferramenta go instala um pacote ou binário, ela também instala todas as dependências que possui, portanto, a execução de go install também instalará os pacotes dos quais seu programa depende (disponíveis publicamente, pacotes "go gettable"), automaticamente.

Na verdade ... go installmudará também com Go 1.10, além do novo cache:

O go installcomando " " não instala mais dependências dos pacotes nomeados ( CL 75850 ).

Se você executar " go install foo", a única coisa instalada seráfoo .

Antes, isso variava. Se as dependências estiverem desatualizadas, " go install" também instalou quaisquer dependências.
A instalação implícita de dependências durante " go install" causou muita confusão e dores de cabeça para os usuários, mas anteriormente era necessário habilitar compilações incrementais.
Não mais.
Achamos que a nova install what I saidsemântica " " será muito mais compreensível, especialmente porque fica claro a partir dos relatórios de bug que muitos usuários já os esperavam.
Para forçar a instalação de dependências durante " go install", use o novo " go install -i" , por analogia com " go build -i" e " go test -i".

O fato de que " go install" costumava instalar quaisquer dependências reconstruídas causava confusão na maioria das vezes em conjunto com -a, que significa " force rebuild of all dependencies".
Agora, " go install -a myprog" forçará uma reconstrução completa de todas as dependências do myprog, assim como de myprogsi mesmo, mas apenas myprogserá instalado. (Todas as dependências reconstruídas ainda serão salvas no cache de compilação, é claro.)
Fazer este caso funcionar de forma mais compreensível é especialmente importante em conjunto com a nova análise de desatualização baseada em conteúdo, porque ela vê boas razões para reconstruir dependências com mais frequência do que antes , o que aumentaria a confusão "por que minhas dependências foram instaladas".
Por exemplo, se você executar " go install -gcflags=-N myprog", isso instalará ummyprogconstruído sem otimizações do compilador, mas também não reinstala mais os pacotes myprogusados ​​da biblioteca padrão sem otimizações do compilador.

VonC
fonte
Faz go build, faz get? Eu tenho um erro de compilação cannot find package "github.com/spf13/cobra" in any of:…. Não sei como dizer para conseguir. Eu preciso obter explicitamente?
ctrl-alt-delor
@ ctrl-alt-delor Com qual versão do Go? O seu projeto contém um go.modarquivo?
VonC de
go version go1.11.4 linux/amd64. Não sei sobre go.mod. Estou reconstruindo https://github.com/cbroglie/mustache/blob/master/cmd/mustache/main.go, é estranho porque acabei de construir o pacote inteiro e estou usando este exemplo como base, e criei uma versão mais básica que funcionou (mas não usando esta biblioteca). Não consigo ver como não foi instalado com o pacote bigode.
ctrl-alt-delor de
@ ctrl-alt-delor então cobr é vendido github.com/cbroglie/mustache/tree/master/cmd/mustache/vendor/… . Seu GOPATH está configurado corretamente?
VonC de
Eu descobri o que você já encontrou. O pacote está em um subdiretório do fornecedor: é por isso que ele não foi instalado. No entanto, não sei por que não o instala agora na construção. Ou como usar o diretório do fornecedor (se eu copiá-lo para o meu diretório).
ctrl-alt-delor