Difference between revisions of "Go package guidelines"

From ArchWiki
Jump to: navigation, search
(Added a note about /...)
(Added a note about /...)
Line 473: Line 473:
  
 
Thanks to Rémy Oudompheng‎ for this one.
 
Thanks to Rémy Oudompheng‎ for this one.
 +
 +
{{Note| Try removing {{Ic|/...}} if this PKGBUILD should fail.}}
  
 
====Using ''go get''====
 
====Using ''go get''====

Revision as of 17:18, 16 May 2012

This template has only maintenance purposes. For linking to local translations please use interlanguage links, see Help:i18n#Interlanguage links.


Local languages: Català – Dansk – English – Español – Esperanto – Hrvatski – Indonesia – Italiano – Lietuviškai – Magyar – Nederlands – Norsk Bokmål – Polski – Português – Slovenský – Česky – Ελληνικά – Български – Русский – Српски – Українська – עברית – العربية – ไทย – 日本語 – 正體中文 – 简体中文 – 한국어


External languages (all articles in these languages should be moved to the external wiki): Deutsch – Français – Română – Suomi – Svenska – Tiếng Việt – Türkçe – فارسی

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 gcc-goAUR package 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.

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.

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:

Sample PKGBUILDs for Go libraries

Note: Not all libraries are upgraded to work with Go 1 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.

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

Note: Try removing /... 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:

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.

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.

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

Note: Try removing /... if this PKGBUILD should fail.

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.

Note: Improvements are more than welcome.
Note: This way is deprecated and won't work after the latest update of 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' '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: