Go package guidelines (Português)

From ArchWiki
Jump to: navigation, search
Status de tradução: Esse artigo é uma tradução de Go package guidelines. Data da última tradução: 2018-11-23. Você pode ajudar a sincronizar a tradução, se houver alterações na versão em inglês.
Diretrizes de criação de pacotes

CLRCrossEclipseFree PascalGNOMEGoHaskellJavaKDEKernelLispMinGWNode.jsNonfreeOCamlPerlPHPPythonRRubyVCSWebWine

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 go-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.

Nota: O nome do pacote deve estar totalmente em minúsculo.

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"

  # 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. Todos os pacotes devem ser compilados preferencialmente com o go-pie, 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 do LDFLAGS.

Para reproducible builds, é importante que os binários sejam removidos do caminho de compilação usando os sinalizadores -trimpath.

# LDFLAGS na variável de ambiente GOFLAGS.
export GOFLAGS="-gcflags=all=-trimpath=${PWD} -asmflags=all=-trimpath=${PWD} -ldflags=-extldflags=-zrelro -ldflags=-extldflags=-znow"

# LDFLAGS definido no go build.
go build \
    -gcflags "all=-trimpath=${PWD}" \
    -asmflags "all=-trimpath=${PWD}" \
    -ldflags "-extldflags ${LDFLAGS}" \
    .
Nota: Por uma questão de brevidade, esses sinalizadores são omitidos nos exemplos abaixo.

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.

Nota: Essas compilações precisam de $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.

Nota: Essas compilações devem ter $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:

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 \
    -gcflags "all=-trimpath=$PWD" \
    -asmflags "all=-trimpath=$PWD" \
    -ldflags "-extldflags $LDFLAGS" \
    -o "$pkgname" .
}

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 \
    -gcflags "all=-trimpath=$GOPATH" \
    -asmflags "all=-trimpath=$GOPATH" \
    -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"
}

Exemplos de pacotes