Difference between revisions of "Go package guidelines"

From ArchWiki
Jump to: navigation, search
(-fix doesn't work for go test)
m (Sample PKGBUILD for when only a single go file is available)
(42 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
[[Category:Package development]]
 
[[Category:Package development]]
{{i18n|Go Package Guidelines}}
 
 
{{Package Guidelines}}
 
{{Package Guidelines}}
  
[[Wikipedia:Go (programming language)|Go]] is well supported on Arch Linux. The {{Pkg|go}} package contains the '''go''' tool (for running {{Ic|go fix}}, {{Ic|go build}} etc) and there is also the {{AUR|gcc-go}} package and {{AUR|go-hg}} in [[AUR]].
+
[[Wikipedia:Go (programming language)|Go]] is well supported on Arch Linux.
  
==General guidelines==
+
The {{Pkg|go}} package contains the '''go''' tool (for running {{Ic|go fix}}, {{Ic|go build}} etc) and there is also the {{AUR|gccgo}} package which provides {{Ic|gccgo}} and {{AUR|go-hg}} in [[AUR]].
  
=== Naming ===
+
= General guidelines =
 +
 
 +
== Naming ==
 
* For applications written in Go, use the name of the application as the package name, in lowercase.
 
* 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.
 
** Be creative if the name is already taken.
 
* For libraries written in Go, use {{Ic|go-''modulename''}}, in lowercase.
 
* For libraries written in Go, use {{Ic|go-''modulename''}}, in lowercase.
* If the name already starts with {{Ic|go-}}, don't call the package {{Ic|go-go-''modulename''}}, but just {{Ic|go-''modulename''}}.
+
* If the name already starts with {{Ic|go-}}, don't call the package {{Ic|go-''go-modulename''}}, but just {{Ic|go-''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.
 
* 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.
 
** Similarly for mercurial packages, only add "-hg" to the package name if the ''_hgroot'' and ''_hgname'' variables are used.
Line 18: Line 19:
 
* Consider adding the name of the author to the package name if there are several applications that are named the same, like {{AUR|dcpu16-kballard}}.
 
* Consider adding the name of the author to the package name if there are several applications that are named the same, like {{AUR|dcpu16-kballard}}.
 
** In general, the most popular packages should be allowed to use the shortest or "best" name.
 
** In general, the most popular packages should be allowed to use the shortest or "best" name.
 +
* Postfixes to the package names (like {{Ic|-hg}}, {{Ic|-git}} or {{Ic|-svn}}) are optional if there are no official releases from the project in question. On one hand, it's common to use them when the package downloads from a VCS. On the other hand, most Go projects don't have any release-tarballs, only the repo which is used for branching/tagging the official release, if it's not ''trunk''. Also, {{Ic|go get}}, which is the "official" way to install Go modules, uses the repositories directly. Use your better judgement.
  
=== Packaging ===
+
== Packaging ==
 
* Go applications are either just library files, just executables or both. Choose an appropriate way of packaging them. There are several examples below.
 
* 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.
 
* Some Go applications or libraries have not been updated to Go 1 yet.
Line 26: Line 28:
 
** Use license=('unknown') and report an issue to the developer if a license file is missing.
 
** 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.
 
** Use version "0.1", "1" or the git-revision (or equivivalent for other version control systems) if the version number is missing.
 +
** Alternatively, use the current date as the version number, in this form {{Ic|YYYYMMDD}}.
  
==Sample PKGBUILDs==
+
= Sample PKGBUILDs =
  
===Sample PKGBUILD for an application written in Go===
+
== Sample PKGBUILD for an application written in Go ==
  
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
Line 49: Line 52:
  
 
   source /etc/profile.d/go.sh
 
   source /etc/profile.d/go.sh
 
  msg2 "Compiling..."
 
 
   go build
 
   go build
 
}
 
}
Line 63: Line 64:
 
# vim:set ts=2 sw=2 et:</nowiki>}}
 
# vim:set ts=2 sw=2 et:</nowiki>}}
  
Sample packages:
+
=== Sample packages ===
 
* {{Pkg|gendesk}}
 
* {{Pkg|gendesk}}
 
* {{AUR|dcpu16}}
 
* {{AUR|dcpu16}}
  
===Sample PKGBUILD for when only a single go file is available===
+
== Sample PKGBUILD for when only a single source file is available ==
  
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
Line 85: Line 86:
 
build() {
 
build() {
 
   cd "$srcdir"
 
   cd "$srcdir"
 +
 +
  source /etc/profile.d/go.sh
 
   go build -o "$pkgname"
 
   go build -o "$pkgname"
 
}
 
}
Line 90: Line 93:
 
package() {
 
package() {
 
   cd "$srcdir"
 
   cd "$srcdir"
 +
 
   install -Dm755 "$pkgname" "$pkgdir/usr/bin/$pkgname"
 
   install -Dm755 "$pkgname" "$pkgdir/usr/bin/$pkgname"
 
}
 
}
Line 95: Line 99:
 
# vim:set ts=2 sw=2 et:</nowiki>}}
 
# vim:set ts=2 sw=2 et:</nowiki>}}
  
Sample packages:
+
=== Sample packages ===
 
* {{AUR|gorun}}
 
* {{AUR|gorun}}
  
===Sample PKGBUILDs for Go libraries===
+
== Sample PKGBUILDs for Go libraries ==
  
{{Note| Not all libraries are upgraded to work with Go 1 yet! If in doubt, try installing with {{Ic|go get}} first, before packaging.}}
+
{{Note| Not all libraries are upgraded to work with Go1 yet! If in doubt, try installing with {{Ic|go get}} first, before packaging.}}
  
==== Using ''go get'' '''(recommended)''' ====
+
=== Using ''go get'' '''(recommended)''' ===
  
 
Here's a way that relies on {{Ic|go get}}.
 
Here's a way that relies on {{Ic|go get}}.
Line 108: Line 112:
 
You probably won't need to modify the build() or package() functions at all, only the variables at the top (pkgname etc).
 
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 {{Ic|go get}} first.
+
If this doesn't work, test with {{Ic|go get}} first. Change ''mercurial'' to ''git'', if that's what your package uses.
 +
 
 +
{{Note| Remove {{Ic|/...}} if the PKGBUILD fails!}}
  
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
  
pkgname=go-net-hg
+
pkgname=go-net
 
pkgver=20120515
 
pkgver=20120515
 
pkgrel=1
 
pkgrel=1
Line 138: Line 144:
 
   mkdir -p "$pkgdir/$GOPATH"
 
   mkdir -p "$pkgdir/$GOPATH"
 
   cp -Rv --preserve=timestamps ${srcdir}/{src,pkg} "$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
 
}
 
}
  
Line 144: Line 158:
 
Thanks to Rémy Oudompheng‎ for this one.
 
Thanks to Rémy Oudompheng‎ for this one.
  
====Using ''go get''====
+
Add "|| return 0" after the {{Ic|go test}} line if you wish to force the test to succeed. It's recommended to report the issue upstream to the relevant developers instead.
 +
 
 +
==== Sample packages ====
 +
* {{AUR|go-web}}
 +
 
 +
==== Troubleshooting ====
 +
* If you get the error that there are two packages found, both package {{Ic|main}} and another package, try removing the corresponding .go file for the {{Ic|main}} package in the {{Ic|build()}} function. Alternatively, move it elsewhere when building and then copy it to {{Ic|/usr/share/doc/$pkgname/examples}} in the {{Ic|package()}} function.
 +
 
 +
=== Using ''go get''===
  
 
Here's another way that relies on {{Ic|go get}}. It can be nice to have if the {{Ic|go get}} method above doesn't work.
 
Here's another way that relies on {{Ic|go get}}. It can be nice to have if the {{Ic|go get}} method above doesn't work.
Line 231: Line 253:
  
 
   # Package license (if available)
 
   # Package license (if available)
   for f in LICENSE COPYING; do
+
   for f in LICENSE COPYING LICENSE.* COPYING.*; do
 
     if [ -e "$srcdir/build/src/$_gourl/$f" ]; then
 
     if [ -e "$srcdir/build/src/$_gourl/$f" ]; then
 
       install -Dm644 "$srcdir/build/src/$_gourl/$f" \
 
       install -Dm644 "$srcdir/build/src/$_gourl/$f" \
Line 241: Line 263:
 
# vim:set ts=2 sw=2 et:</nowiki>}}
 
# vim:set ts=2 sw=2 et:</nowiki>}}
  
Sample packages:
+
=== For libraries (not executables) released as tarballs ===
* {{AUR|go-web}}
+
 
+
====Using ''go get'' and ''unionfs-fuse'' ====
+
 
+
Here's a way that relies on {{Ic|go get}} and {{AUR| unionfs-fuse}}.
+
 
+
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 {{Ic|go get}} first.
+
 
+
{{Note| Improvements are more than welcome, especially for how to umount the unionfs after building.}}
+
 
+
{{Warning| This PKGBUILD may try to install .a files for libraries that are already installed, causing file conflicts, or not package libraries that are already installed.}}
+
 
+
{{Note| This method is not recommended!}}
+
 
+
{{Note|This way is deprecated and won't work after the latest update of Go.}}
+
 
+
Thanks to Jens Staal for this one.
+
 
+
{{bc|<nowiki>
+
# 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:</nowiki>}}
+
 
+
Temporary solution for library issue + packaging of binaries:
+
Add the following at the end of package():
+
{{bc|<nowiki>
+
# 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
+
</nowiki>}}
+
 
+
Sample packages:
+
* {{AUR|go-tecla}}
+
* {{AUR|oh}}
+
* {{AUR|mdtwm}}
+
* {{AUR|gich}}
+
  
====For libraries (not executables) released as tarballs====
+
{{Note|This way is deprecated and won't work properly after the latest update of Go.}}
  
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
Line 393: Line 302:
 
* https://bitbucket.org/vlasovskikh/go-aur-example
 
* https://bitbucket.org/vlasovskikh/go-aur-example
  
====For hg packages====
+
== Sample PKGBUILDs for Go libraries that also includes executables ==
  
{{bc|<nowiki># Maintainer: NAME <EMAIL>
+
=== Using ''go get'' '''(recommended)''' ===
  
name=go-PACKAGE NAME
+
Here's a way that relies on go get.
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() {
+
You probably won't need to modify the build() or package() functions at all, only the variables at the top (pkgname etc).
  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:
+
</nowiki>}}
+
 
+
Thanks to Andrey Vlasovskikh for this one. ''libyaml'' is just an example of a dependency.
+
 
+
See also:
+
* https://bitbucket.org/vlasovskikh/go-aur-example
+
  
===Sample PKGBUILDs for Go libraries that also includes executables===
+
If this doesn't work, test with go get first.
  
====Using ''go get'' '''(recommended)''' ====
+
{{Note| Remove {{Ic|/...}} if the PKGBUILD fails!}}
  
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
Line 456: Line 335:
 
check() {
 
check() {
 
   source /etc/profile.d/go.sh
 
   source /etc/profile.d/go.sh
   GOPATH="$GOPATH:$srcdir" go test -fix -v -x ${_gourl}/...
+
   GOPATH="$GOPATH:$srcdir" go test -v -x ${_gourl}/...
 
}
 
}
  
Line 466: Line 345:
 
   mkdir -p "$pkgdir/$GOPATH"
 
   mkdir -p "$pkgdir/$GOPATH"
 
   cp -Rv --preserve=timestamps ${srcdir}/{src,pkg} "$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
 
}
 
}
  
Line 472: Line 359:
 
Thanks to Rémy Oudompheng‎ for this one.
 
Thanks to Rémy Oudompheng‎ for this one.
  
====Using ''go get''====
+
=== Using ''go get'' ===
  
Here's a way that relies on {{Ic|go get}}.
+
Here's another way that relies on {{Ic|go get}}.
  
 
You probably won't need to modify the build() or package() functions at all, only the variables at the top (pkgname etc).
 
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 {{Ic|go get}} first.
 
If this doesn't work, test with {{Ic|go get}} first.
 
{{Note|Improvements are more than welcome.}}
 
 
{{Note|This way is deprecated and won't work after the latest update of Go.}}
 
  
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
 
{{bc|<nowiki># Maintainer: NAME <EMAIL>
Line 500: Line 383:
 
   cd "$srcdir"
 
   cd "$srcdir"
  
   GOROOT=/usr/lib/go #source /etc/profile.d/go.sh
+
   export GOROOT=/usr/lib/go
  
 
   rm -rf build
 
   rm -rf build
Line 547: Line 430:
 
   cd "$srcdir"
 
   cd "$srcdir"
  
   GOROOT=/usr/lib/go #source /etc/profile.d/go.sh
+
   source /etc/profile.d/go.sh
 +
  export GOROOT="$GOPATH"
  
 
   # Package go package files
 
   # Package go package files
Line 588: Line 472:
  
 
# vim:set ts=2 sw=2 et:</nowiki>}}
 
# vim:set ts=2 sw=2 et:</nowiki>}}
 
Sample packages:
 
* {{AUR|dcpu16}}
 

Revision as of 08:03, 20 September 2012

Template: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 gccgoAUR package which provides gccgo and go-hgAUR in AUR.

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 package go-go-modulename, but just go-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.
  • Postfixes to the package names (like -hg, -git or -svn) are optional if there are no official releases from the project in question. On one hand, it's common to use them when the package downloads from a VCS. On the other hand, most Go projects don't have any release-tarballs, only the repo which is used for branching/tagging the official release, if it's not trunk. Also, go get, which is the "official" way to install Go modules, uses the repositories directly. Use your better judgement.

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.
  • 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.
    • Alternatively, use the current date as the version number, in this form YYYYMMDD.

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
  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 source 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"

  source /etc/profile.d/go.sh
  go build -o "$pkgname"
}

package() {
  cd "$srcdir"

  install -Dm755 "$pkgname" "$pkgdir/usr/bin/$pkgname"
}

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

Sample packages

Sample PKGBUILDs for Go libraries

Note: Not all libraries are upgraded to work with Go1 yet! If in doubt, try installing with 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. Change mercurial to git, if that's what your package uses.

Note: Remove /... if the PKGBUILD fails!
# Maintainer: NAME <EMAIL>

pkgname=go-net
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"

  # 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:

Thanks to Rémy Oudompheng‎ for this one.

Add "|| return 0" after the go test line if you wish to force the test to succeed. It's recommended to report the issue upstream to the relevant developers instead.

Sample packages

Troubleshooting

  • If you get the error that there are two packages found, both package main and another package, try removing the corresponding .go file for the main package in the build() function. Alternatively, move it elsewhere when building and then copy it to /usr/share/doc/$pkgname/examples in the package() function.

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 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:

For libraries (not executables) released as tarballs

Note: This way is deprecated and won't work properly after the latest update of Go.
# 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:

Sample PKGBUILDs for Go libraries that also includes executables

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.

Note: Remove /... if the PKGBUILD fails!
# 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"

  # 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:

Thanks to Rémy Oudompheng‎ for this one.

Using go get

Here's another 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"

  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"

  # 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"

  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

  # 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: