Go package guidelines (Português)

From ArchWiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Status de tradução: Esse artigo é uma tradução de Go package guidelines. Data da última tradução: 2020-03-27. Você pode ajudar a sincronizar a tradução, se houver alterações na versão em inglês.
Diretrizes de pacotes do Arch

32-bitCLRCMakeCrossDKMSEclipseElectronFonteFree PascalGNOMEGoHaskellJavaKDEKernelLispMesonMinGWNode.jsNonfreeOCamlPerlPHPPythonRRubyRustVCSWebWine

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.

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
  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 do LDFLAGS.

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}" \
    .
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 \
    -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
}

Exemplos de pacotes