Go package guidelines
Go is well supported on Arch Linux. The go package contains the go tool (for running go fix
, go build
etc) and there is also the gcc-goAUR package and go-hgAUR in AUR.
Contents
General guidelines
Naming
- For applications written in Go, use the name of the application as the package name, in lowercase.
- Be creative if the name is already taken.
- For libraries written in Go, use
go-modulename
, in lowercase. - If the name already starts with
go-
, don't call the packagego-go-modulename
, but justgo-modulename
. - For PKGBUILDS that uses the "go" tool to download the package, only add "-git" to the package name if the _gitroot and _gitname variables are used.
- Similarly for mercurial packages, only add "-hg" to the package name if the _hgroot and _hgname variables are used.
- Extend this pattern for other version control systems.
- The go tool has its own logic for which branch or tag it should use. See
go get --help
.
- Consider adding the name of the author to the package name if there are several applications that are named the same, like dcpu16-kballardAUR.
- In general, the most popular packages should be allowed to use the shortest or "best" name.
Packaging
- Go applications are either just library files, just executables or both. Choose an appropriate way of packaging them. There are several examples below.
- Some Go applications or libraries have not been updated to Go 1 yet.
- Running
go build -fix
may often work, but it may have to be fixed by the developer. Report an issue upstream if this is the case.
- Running
- Several Go projects doesn't have a version number or a license file.
- Use license=('unknown') and report an issue to the developer if a license file is missing.
- Use version "0.1", "1" or the git-revision (or equivivalent for other version control systems) if the version number is missing.
Sample PKGBUILDs
Sample PKGBUILD for an application written in Go
# 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 "$srcdir/$pkgname-$pkgver" source /etc/profile.d/go.sh msg2 "Compiling..." go build } package() { cd "$srcdir/$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:
Sample packages:
Sample PKGBUILD for when only a single go file is available
# 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() { cd "$srcdir" go build -o "$pkgname" } package() { cd "$srcdir" install -Dm755 "$pkgname" "$pkgdir/usr/bin/$pkgname" } # vim:set ts=2 sw=2 et:
Sample packages:
- gorunAUR
Sample PKGBUILDs for Go libraries
go get
first, before packaging.Using go get (recommended)
Here's a way that relies on go get
.
You probably won't need to modify the build() or package() functions at all, only the variables at the top (pkgname etc).
If this doesn't work, test with go get
first.
# Maintainer: NAME <EMAIL> pkgname=go-net-hg pkgver=20120515 pkgrel=1 pkgdesc="Extra network libraries for Go (dict, spdy, websocket)" arch=('x86_64' 'i686') url="http://code.google.com/p/go" license=('BSD') depends=('go') makedepends=('mercurial') options=('!strip' '!emptydirs') _gourl=code.google.com/p/go.net build() { cd "$srcdir" GOPATH="$srcdir" go get -fix -v -x ${_gourl}/... } check() { source /etc/profile.d/go.sh GOPATH="$GOPATH:$srcdir" go test -v -x ${_gourl}/... } package() { source /etc/profile.d/go.sh mkdir -p "$pkgdir/$GOPATH" cp -Rv --preserve=timestamps ${srcdir}/{src,pkg} "$pkgdir/$GOPATH" } # vim:set ts=2 sw=2 et:
Thanks to Rémy Oudompheng for this one.
/...
if this PKGBUILD should fail.Using go get
Here's another way that relies on go get
. It can be nice to have if the go get
method above doesn't work.
You probably won't need to modify the build() or package() functions at all, only the variables at the top (pkgname etc).
If this doesn't work, test with go get
first.
# Maintainer: NAME <EMAIL> pkgname=go-PACKAGENAME 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() { cd "$srcdir" 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 "$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" } package() { cd "$srcdir" source /etc/profile.d/go.sh 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 } # vim:set ts=2 sw=2 et:
Sample packages:
- go-webAUR
Using go get and unionfs-fuse
Here's a way that relies on go get
and unionfs-fuseAUR.
You probably won't need to modify the build() or package() functions at all, only the variables at the top (pkgname etc).
If this doesn't work, test with go get
first.
Thanks to Jens Staal for this one.
# Maintainer: NAME <EMAIL> pkgname=go-PACKAGE NAME pkgver=20120417 pkgrel=1 pkgdesc="PACKAGE DESCRIPTION" arch=('i686' 'x86_64') url="https://SERVER/WEBPAGE" license=('MIT') depends=('some_random_library' 'go') makedepends=('git' 'unionfs-fuse') options=('!strip' '!emptydirs') _gourl=github.com/user/project build() { cd "$srcdir" source /etc/profile.d/go.sh rm -rf build mkdir -p build/go rm -rf temp mkdir -p temp #starting off fresh msg2 "Setting up union mount" unionfs -o cow -o umask=000 $srcdir/temp=RW:$GOROOT=RO $srcdir/build/go cd build/go export GOROOT="$srcdir/build/go" export GOPATH="$srcdir/build" go get -fix "$_gourl" } package() { cd "$srcdir" source /etc/profile.d/go.sh # 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 #msg2 "Unmounting union mount" # fusermount -u $srcdir/build/go # Somehow fusermount -u fails, so we are now left with a mounted directory after build # scary and ugly... # 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 msg2 "Package successfully built." msg "IMPORTANT: Run 'fusermount -u src/build/go' to unmount the go directory!" } # vim:set ts=2 sw=2 et:
Temporary solution for library issue + packaging of binaries: Add the following at the end of package():
# remove libdir in pkgdir rm -rf "$pkgdir/usr/lib" # Package executables if [ -e "$srcdir/build/bin/$pkgname" ]; then install -Dm755 "$srcdir/build/bin/$pkgname" \ "$pkgdir/usr/bin/$pkgname" fi
Sample packages:
For libraries (not executables) released as tarballs
# Maintainer: NAME <EMAIL> pkgname=go-PACKAGE NAME pkgver=1.2.3 pkgrel=1 pkgdesc='Example library for Go package creation guidelines' arch=('i686' 'x86_64') url='http://bitbucket.org/vlasovskikh/go-aur-example' license=('MIT') makedepends=('go' 'libSOMELIBRARY') options=('!strip') source=("https://bitbucket.org/vlasovskikh/go-aur-example/downloads/$pkgname-$pkgver.tar.gz") md5sums=('810311689a73879a96bc9b29ebbfc347') build() { remoteprefix="bitbucket.org/vlasovskikh/$pkgname" libname="SOMELIBRARY" cd "$srcdir" install -d "src/$remoteprefix" cp -aT "$pkgname-$pkgver" "src/$remoteprefix" GOPATH="$srcdir" go install "$remoteprefix/$libname" destdir="$pkgdir/usr/lib/go" install -d "$destdir" "$destdir/src/pkg" cp -aT pkg "$destdir/pkg" cp -aT src "$destdir/src/pkg" } # vim:set ts=2 sw=2 et:
Thanks to Andrey Vlasovskikh for this one.
See also:
For hg packages
# Maintainer: NAME <EMAIL> name=go-PACKAGE NAME pkgname=$name-hg pkgver=1.2.3 pkgrel=1 pkgdesc='Example library for Go package creation guidelines' arch=('i686' 'x86_64') url='http://bitbucket.org/vlasovskikh/go-aur-example' license=('MIT') makedepends=('go' 'libyaml') options=('!strip') _hgroot="https://bitbucket.org/vlasovskikh" _hgrepo="$name" build() { remoteprefix="bitbucket.org/vlasovskikh/$name" libname="yaml" cd "$srcdir" install -d "src/$remoteprefix" cp -aT "$name" "src/$remoteprefix" GOPATH="$srcdir" go install "$remoteprefix/$libname" destdir="$pkgdir/usr/lib/go" install -d "$destdir" "$destdir/src/pkg" cp -aT pkg "$destdir/pkg" cp -aT src "$destdir/src/pkg" } # vim:set ts=2 sw=2 et:
Thanks to Andrey Vlasovskikh for this one. libyaml is just an example of a dependency.
See also:
Sample PKGBUILDs for Go libraries that also includes executables
Using go get (recommended)
# Maintainer: NAME <EMAIL> pkgname=codesearch pkgver=20120515 pkgrel=1 pkgdesc="Code indexing and search written in Go" arch=('x86_64' 'i686') url="http://code.google.com/p/codesearch" license=('BSD') depends=('go') makedepends=('mercurial') options=('!strip' '!emptydirs') _gourl=code.google.com/p/codesearch build() { cd "$srcdir" GOPATH="$srcdir" go get -fix -v -x ${_gourl}/... } check() { source /etc/profile.d/go.sh GOPATH="$GOPATH:$srcdir" go test -v -x ${_gourl}/... } package() { source /etc/profile.d/go.sh 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" } # vim:set ts=2 sw=2 et:
Thanks to Rémy Oudompheng for this one.
Using go get
Here's a way that relies on go get
.
You probably won't need to modify the build() or package() functions at all, only the variables at the top (pkgname etc).
If this doesn't work, test with go get
first.
# 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() { cd "$srcdir" GOROOT=/usr/lib/go #source /etc/profile.d/go.sh 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 "$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() { cd "$srcdir" GOROOT=/usr/lib/go #source /etc/profile.d/go.sh # 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:
Sample packages:
- dcpu16AUR