Go package guidelines (Português)
32-bit – CLR – CMake – Cross – DKMS – Eclipse – Electron – Fonte – Free Pascal – GNOME – Go – Haskell – Java – KDE – Kernel – Lisp – Meson – MinGW – Node.js – Nonfree – OCaml – Perl – PHP – Python – R – Ruby – Rust – VCS – Web – Wine
Esse documento cobra padrões e diretrizes sobre a escrita de PKGBUILDs para Go.
Diretrizes gerais
Nomenclatura de pacote
Para módulos de biblioteca Go, use golang-nomemódulo
. Use também o prefixo se o pacote fornecer um programa fortemente acoplado ao ecossistema Go. Para outras aplicações, use apenas o nome do programa.
Instruções para gerenciadores de dependência alternativos
Isso não é necessário para o Go 1.11 e posterior, a menos que um gerenciador de dependências alternativo seja exigido pelo projeto Go que você está empacotando.
Ao preparar as fontes antes de construir, pode ser necessário o seguinte:
- Crie um diretório
$srcdir/gopath
para $GOPATH e copie o código-fonte para esse diretório. - Deve-se notar que esta etapa pode não ser necessária se o projeto fornecer um
Makefile
para o projeto que o configura.
prepare(){ mkdir -p gopath/src/github.com/pkgbuild-example ln -rTsf $pkgname-$pkgver gopath/src/github.com/pkgbuild-example/$pkgname export GOPATH="$srcdir"/gopath # as dependências podem ser obtidas aqui, se necessário cd gopath/src/github.com/pkgbuild-example/$pkgname dep ensure }
Compilação
Existem nos repositórios dois pacotes go com os quais que você pode compilar; go e go-pie[link quebrado: replaced by go]. Todos os pacotes devem ser compilados preferencialmente com o go-pie[link quebrado: replaced by go], pois isso nos permite entregar binários seguros. No entanto, como upstream pode ter bugs, compilar com o go deve ser o último recurso.
Sinalizadores e opções de compilação
A maioria dos Makefiles escritos para aplicativos go não respeitam o LDFLAGS
fornecido pelos sistemas de compilação, isso faz com que os binários do Go não sejam compilados com o RELRO. Isso precisa ser corrigido no Makefile, ou o Makefile deve ser omitido. Se houver um Makefile envolvido, você tem 3 opções para suportar o RELRO:
- Aplicar um patch no Makefile
- Ignorar o Makefile completamente e usar
go build
- Exportar
GOFLAGS
- Isso é menos desejável, pois estaremos descartando sinalizadores doLDFLAGS
.
Para reproducible builds, é importante que os binários sejam removidos do caminho de compilação usando os sinalizadores -trimpath
.
export CGO_LDFLAGS="${LDFLAGS}" export GOFLAGS="-trimpath" # ou, alternativamente, use LDFLAGS definido no go build. go build \ -trimpath \ -ldflags "-extldflags ${LDFLAGS}" \ .
Projetos Go modernos (para Go >=1.11)
Go 1.11 introduz go modules. Isso omite a necessidade de configuração GOPATH
e nós podemos compilar diretamente no diretório.
Projetos como esses têm um arquivo go.mod
e um go.sum
.
$PWD
retirado do binário.build(){ cd $pkgname-$pkgver go build . }
Projetos Go antigos (para Go <1.11)
Ao compilarmos pacotes com $GOPATH, existem alguns problemas que você pode encontrar. Normalmente o projeto entrega um Makefile
que pode ser usado e deve ser usado. Existem casos em que você ainda precisa configurar um $GOPATH
no PKGBUILD. O trecho a seguir configura um GOPATH
dentro de $srcdir/gopath
que pode ser usado para compilar pacotes. Um novo diretório é usado, já que alguns gerenciador de dependências fazem coisas estranhas se descobrirem o projeto na raiz do $GOPATH
.
$GOPATH
removidos do binário.prepare(){ mkdir -p gopath/src/github.com/pkgbuild-example ln -rTsf $pkgname-$pkgver gopath/src/github.com/pkgbuild-example/$pkgname # as dependências podem ser obtidas aqui se necessário cd gopath/src/github.com/pkgbuild-example/$pkgname dep ensure } build(){ export GOPATH="$srcdir"/gopath cd gopath/src/github.com/pkgbuild-example/$pkgname go install -v . }
Note install
e build
, e que podem ser feitas compilações recursivas se você tiver um subdiretório cmd/
com múltiplos binários: go install -v github.com/pkgbuild-example/cmd/...
Notas sobre dependências e gerenciadores de dependências
Os pacotes Go atualmente usam a pasta vendor/
para lidar com dependências em projetos. Geralmente, eles são gerenciados por um dos vários projetos do gerenciador de dependências. Se um for usado para o pacote, este passo deve ser executado na função prepare() do PKGBUILD.
Dependências são normalmente gerenciadas pelo comando go mod
, que vem com o Go 1.11 ou posterior.
Existem também gerenciadores de dependência alternativos:
- depAUR
- godep[link quebrado: package not found]
- glide
Exemplos de PKGBUILDs
PKGBUILD básico
pkgname=foo pkgver=0.0.1 pkgrel=1 pkgdesc='Go PKGBUILD Example' arch=('x86_64') url='https://example.org/$pkgname' license=('GPL') makedepends=('go-pie') source=("$url/$pkgname-$pkgver.tar.gz") sha256sums=('1337deadbeef') build() { cd $pkgname-$pkgver go build \ -mod=vendor \ -trimpath \ -ldflags "-extldflags $LDFLAGS" \ -o $pkgname . } check() { cd $pkgname-$pkgver go test -mod=vendor ./... } package() { cd $pkgname-$pkgver install -Dm755 $pkgname "$pkgdir"/usr/bin/$pkgname }
PKGBUILD com GOPATH e dep
pkgname=foo pkgver=0.0.1 pkgrel=1 pkgdesc='Go PKGBUILD Example' arch=('x86_64') url='https://example.org/$pkgname' license=('GPL') makedepends=('go-pie' 'dep') source=("$url/$pkgname-$pkgver.tar.gz") sha256sums=('1337deadbeef') prepare(){ mkdir -p gopath/src/example.org/foo ln -rTsf $pkgname-$pkgver gopath/src/example.org/foo cd gopath/src/example.org/foo dep ensure } build() { export GOPATH="$srcdir"/gopath cd gopath/src/example.org/foo go install \ -trimpath \ -ldflags "-extldflags $LDFLAGS" \ -v ./... } check() { export GOPATH="$srcdir"/gopath cd gopath/src/example.org/foo go test ./... } package() { install -Dm755 gopath/bin/$pkgname "$pkgdir"/usr/bin/$pkgname }