Go package guidelines (简体中文)

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.
Arch 软件包准则

32-bitCLRCMakeCrossDKMSEclipseElectronFontFree PascalGNOMEGoHaskellJavaKDEKernelLispMesonMinGWNode.jsNonfreeOCamlPerlPHPPythonRRubyRustVCSWebWine

翻译状态:本文是 Go package guidelines翻译。上次翻译日期:2018-05-03。如果英文版本有所更改,则您可以帮助同步翻译。

Arch Linux 对 Go 的支持非常完善。

软件包 go 中包含了 go 工具 (用于运行 go fix, go build 等)。 另外还有个提供 gccgogcc-go 软件包。

通用准则

命名

  • 对于使用 Go 语言编写的软件库,请使用小写字母的 go-库名 作为软件包名。
    • 如果软件库名本身就是以 go- 开头的,请不要使用 go-go-模块名 这样的名字,而改用 go-模块名
  • 对于使用"go"工具下载的软件包,只有当它不是从tar包或者tagged提交(而是从trunk/HEAD)下载源码时,软件包名才添加"-git"后缀。
    • 类似的,对于mercurial 版本控制系统,只有当软件包未从release-revision下载源码时,才添加"-hg"后缀。
    • 其他版本控制系统,请一并参考该准则。
    • "go"工具下载那个分支或者Tag通常有他自己的一套逻辑。请参考 go get --help.
  • 如果有多个同名的软件包,可考虑将作者的名字添加到软件包名之中,例如:dcpu16-kballardAUR[损坏的链接:package not found]
    • 当然,通常情况下,最流行的软件包会使用最短或者"最佳"的软件包名。
  • 如果软件开发者本身并没有正式的官方发布,那么这种后缀名 (例如 -hg, -git-svn) 只是可选的。 一方面,这种软件包通常都是直接通过源码版本库下载使用的。另一方面, 大多数 Go 语言项目从不发布任何tarball,而只发布源码版本库。并将版本库的master分支、HEAD提交以外的分支、Tag作为官方发布的方式。另一方面,Go语言官方的模块安装方式 go get 也往往直接使用源码版本库。所以请根据情况作出最佳选择。

打包

  • Go 语言项目通常只包含软件库、可执行文件或者两者俱有。请以合适的方式打包他们。后续有几个例子以供参考。
  • 有些 Go 语言项目并不支持最新版本的Go编译。这种情况下
    • 直接执行 go build -fix 一般就可以搞定了。如果仍有问题,请上报给上游开发者,并且他们修复。
  • 有些Go语言项目并没有版本号或者授权协议文件。这种情况下:
    • 使用 license=('unknown') 并向上游开发者提交授权协议缺失的报告。
    • 如果没有版本号,请使用 "0.1", "1" 或者Git库的revision ( 其他版本控制系统类似)。
    • 作为备选,可以用当前日期作为版本号,格式形如 YYYYMMDD

PKGBUILD 范例

Go 语言开发的独立程序 PKGBUILD

# Maintainer: NAME <EMAIL>

pkgname=PACKAGE NAME
pkgver=1.2.3
pkgrel=1
pkgdesc="PACKAGE DESCRIPTION"
arch=('x86_64' 'i686')
url="http://SERVER/$pkgname/"
license=('MIT')
makedepends=('go')
options=('!strip' '!emptydirs')
source=("http://SERVER/$pkgname/$pkgname-$pkgver.tar.gz")
sha256sums=('00112233445566778899aabbccddeeff')

build() {
  cd "$pkgname-$pkgver"

  go build
}

package() {
  cd "$pkgname-$pkgver"

  install -Dm755 "$pkgname-$pkgver" "$pkgdir/usr/bin/$pkgname"
  install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
}

# vim:set ts=2 sw=2 et:

参考示例包

仅包含单个Go文件的程序 PKGBUILD

# Maintainer: NAME <EMAIL>

pkgname=PACKAGE NAME
pkgver=1.2.3
pkgrel=1
pkgdesc="PACKAGE DESCRIPTION"
arch=('x86_64' 'i686')
url="http://SERVER/$pkgname/"
license=('GPL3')
makedepends=('go')
options=('!strip' '!emptydirs')
source=("http://SERVER/$pkgname/$pkgname.go")
sha256sums=('00112233445566778899aabbccddeeff')

build() {
  go build -o "$pkgname"
}

package() {
  install -Dm755 "$pkgname" "$pkgdir/usr/bin/$pkgname"
}

# vim:set ts=2 sw=2 et:

参考示例包

包含可执行文件的Go语言库 PKGBUILD

使用 go get

这是推荐的使用"go get"的方式,请优先选用这种方式,后文介绍的那种仅供参考。

这种方式将依赖于"go get"。

通常情况下你无需修改 build() 或 package() 函数,只需要修改前面定义的变量 (pkgname 等)即可。

如果打包失败,请先确保手动执行"go get"能成功。

提示: 如果打包失败,尝试去掉 /...再试试!
# Maintainer: NAME <EMAIL>

pkgname=codesearch
pkgver=20120515
pkgrel=1
pkgdesc="Code indexing and search written in Go"
arch=('x86_64' 'i686')
url="https://github.com/google/codesearch"
license=('BSD')
depends=('go')
makedepends=('mercurial')
options=('!strip' '!emptydirs')
_gourl=github.com/google/codesearch

build() {
  GOPATH="$srcdir" go get -fix -v -x ${_gourl}/...
}

check() {
  GOPATH="$GOPATH:$srcdir" go test -v -x ${_gourl}/...
}

package() {
  mkdir -p "$pkgdir/usr/bin"
  install -p -m755 "$srcdir/bin/"* "$pkgdir/usr/bin"

  mkdir -p "$pkgdir/$GOPATH"
  cp -Rv --preserve=timestamps "$srcdir/"{src,pkg} "$pkgdir/$GOPATH"

  # Package license (if available)
  for f in LICENSE COPYING LICENSE.* COPYING.*; do
    if [ -e "$srcdir/src/$_gourl/$f" ]; then
      install -Dm644 "$srcdir/src/$_gourl/$f" \
        "$pkgdir/usr/share/licenses/$pkgname/$f"
    fi
  done
}

# vim:set ts=2 sw=2 et:

感谢 Rémy Oudompheng‎ 提供该范例。

使用 go get

另外一种依靠 go get的方式如下。

一般不需要修改 build() 或 package() 函数,只需要修改前面的变量 (pkgname 等)即可。

如果打包有问题,请先确保手动执行 go get 没问题。

# Maintainer: NAME <EMAIL>

pkgname=PACKAGE NAME
pkgver=1.2.3
pkgrel=1
pkgdesc="PACKAGE DESCRIPTION"
arch=('x86_64' 'i686')
url="http://SERVER/$pkgname/"
license=('MIT')
makedepends=('go' 'git')
options=('!strip' '!emptydirs')
_gourl=SERVER.NET/PATH/MODULENAME

build() {
  export GOROOT=/usr/lib/go

  rm -rf build
  mkdir -p build/go
  cd build/go

  for f in "$GOROOT/"*; do
    ln -s "$f"
  done

  rm pkg
  mkdir pkg
  cd pkg

  for f in "$GOROOT/pkg/"*; do
    ln -s "$f"
  done

  platform=`for f in "$GOROOT/pkg/"*; do echo \`basename $f\`; done|grep linux`

  rm -f "$platform"
  mkdir "$platform"
  cd "$platform"

  for f in "$GOROOT/pkg/$platform/"*.h; do
    ln -s "$f"
  done

  export GOROOT="$srcdir/build/go"
  export GOPATH="$srcdir/build"

  go get -fix "$_gourl"

  # Prepare executable
  if [ -d "$srcdir/build/src" ]; then
    cd "$srcdir/build/src/$_gourl"
    go build -o "$srcdir/build/$pkgname"
  else
    echo 'Old sources for a previous version of this package are already present!'
    echo 'Build in a chroot or uninstall the previous version.'
    return 1
  fi
}

package() {
  export GOROOT="$GOPATH"

  # Package go package files
  for f in "$srcdir/build/go/pkg/"* "$srcdir/build/pkg/"*; do
    # If it's a directory
    if [ -d "$f" ]; then
      cd "$f"
      mkdir -p "$pkgdir/$GOROOT/pkg/`basename $f`"
      for z in *; do
        # Check if the directory name matches
        if [ "$z" == `echo $_gourl | cut -d/ -f1` ]; then
          cp -r $z "$pkgdir/$GOROOT/pkg/`basename $f`"
        fi
      done
      cd ..
    fi
  done

  # Package source files
  if [ -d "$srcdir/build/src" ]; then
    mkdir -p "$pkgdir/$GOROOT/src/pkg"
    cp -r "$srcdir/build/src/"* "$pkgdir/$GOROOT/src/pkg/"
    find "$pkgdir" -depth -type d -name .git -exec rm -r {} \;
  fi

  # Package license (if available)
  for f in LICENSE COPYING; do
    if [ -e "$srcdir/build/src/$_gourl/$f" ]; then
      install -Dm644 "$srcdir/build/src/$_gourl/$f" \
        "$pkgdir/usr/share/licenses/$pkgname/$f"
    fi
  done

  # Package executables
  if [ -e "$srcdir/build/$pkgname" ]; then
    install -Dm755 "$srcdir/build/$pkgname" \
      "$pkgdir/usr/bin/$pkgname"
  fi
}

# vim:set ts=2 sw=2 et: