Compilação Estática Com Golang
Criando executáveis monolíticos
Veja o vídeo desse arquivo aqui.
Golang já faz um bom trabalho compilando estaticamente praticamente tudo, mas dependendo do seu código é necessário incluir mais alguns parâmetros para garantir que seu executável seja totalmente livre de dependências.
A primeira coisa é compilar o seu projeto e então inspecionar o binário para ver se ele tem alguma dependência.
Para fazer isso no macOS usamos o utilitário otool
(object file displaying tool) passando o parâmetro -L
(mostra as shared libraries usadas) como no exemplo:
otool -L nomedobinario
No Linux o comando equivalente é o ldd
:
ldd nomedobinario
O comando file
também pode dar pistas das bibliotecas compartilhadas que estão sendo usadas.
CGO_ENABLED=0
Se seu comigo não mostrar nenhuma dependência você não precisa fazer nada, mas em alguns casos é necessário desabilitar o cgo, para isso basta incluir a variável de ambiente CGO_ENABLED=0
.
CGO_ENABLED=0 go build
Em versões mais antigas do go se você se você precisasse de suporte a net era necessário incluir o parâmetro -tags netgo
, embora esse parâmetros não gere erros ele não é mais necessário.
Se você estiver usando bibliotecas externas você vai precisar inserir alguns parâmetros para o linker via -ldflags
como no exemplo:
CGO_ENABLED=0 go build -ldflags '-extldflags "-static"'
E se você quiser ter certeza que tudo foi realmente recompilado você pode incluir o parâmetro -a
que faz com que todos os packages usados sejam recompilados mesmo que eles já estejam atualizados.
Bonus
Já que estamos falando de parâmetros de compilação podemos incluir mais dois parâmetros para o linker que vão ajudar a diminuir o tamanho do executável final -ldflags "-s -w"
.
O parâmetro -s
remove informações de debug do executável e o -w
impede a geração do DWARF (Debugging With Attributed Record Formats). Claro que sem isso não da para fazer debug então pode não ser tão interessante.
Para ver esses e outros parâmetros do linker execute o seguinte comando:
go tool link --help
O comando final ficou assim:
CGO_ENABLED=0 go build -a -ldflags '-extldflags "-static" -s -w'