Packaging for Arch Linux
The AUR is insanely convenient for distributing and downloading software on Arch Linux. A while ago I wanted to package and distribute the modified version of beatoraja - lr2oraja.
Why did I make a package?
LR2oraja has modified timing windows to more accurately mimic the timing of the extremely old abandon-ware game Lunatic Rave 2 (LR2).
People still play LR2 & both games play the same
"levels" so comparing scores between them when both have
different timing windows is impossible. With Beatoraja you can simply
download the repo and run the shell script to play but lr2oraja only
provides a patched jar file. I wanted an easy way for my
friends and I to install this game on our linux systems. Since we
commonly ran into issues with java versions and portaudio issues.
Creating a PKGBUILD
Following the Arch Wiki page with the same name, I was able to generate a basic PKGBuild file that did what I wanted. Bellow is the current PKGBUILD (minus the functions) as of the writing of this article.
# Maintainer: Pfych <contact at pfy dot ch>
pkgname=lr2oraja
pkgver=build6711481041
pkgrel=2
pkgdesc="The latest build of beatoraja, but compiled using LR2 judges and gauges."
arch=('x86_64')
depends=('liberica-jre-8-full-bin' 'portaudio')
makedepend=('unzip')
source=(
"https://github.com/wcko87/lr2oraja/releases/download/${pkgver}/LR2oraja.zip"
'https://github.com/pfych/lr2oraja-pkgbuild/releases/download/skin/skin.zip'
'https://github.com/TNG-dev/tachi-beatoraja-ir/releases/download/v3.0.0/bokutachiIR-3.0.0.jar'
'libjportaudio.so'
'beatoraja.sh'
'lr2oraja-icon.png'
)
sha256sums=(
'5f6dceccaeb0e786dd1658c1b481e8db114bc90a8a1056bf65753e8936ed3369' # LR2oraja.zip
'ef23b516537b4f52c306fd61ab9c4197192c06b7202b3b27b63481fec1042a26' # skin.zip
'3754959d5d6f121dbeed3a78dec2b91a26e915ff4ce68fdee4262b89ad150cb9' # bokutachiIR
'a65d1290d3ee7710f9327c040e6369bf7587eb3609835ed782caaf0ac02d84ed' # libjportaudio.so
'a1c1d6ee606d042934ec1ee503a9300d5b225f3c4031be144a3c5bca24f0d042' # beatoraja.sh
'0ec1382690cd847055d1b8e6da36ad6846598b45b25acca5eb5e301a5048da03' # lr2oraja-icon.png
)
license=(
'GPL3'
'GPL3'
'MIT'
'unknown'
'unknown'
)
prepare() {}
build() {}
package() {}
Going from top to bottom:
pkgnameis the name of the package users will type to install the package, and what will appear on the AUR.pkgveris the version of the package that will be displayed on the AUR. This can also be referenced with${pkgver}elsewhere in the file. This is convenient if you pull from git or an external source to get a specific released file.pkgrelis the build-version of the package. You bump this value if you change the contents of the build script or a dependency. If you'repkgveris1.0.0and yourpkgrelis2the final version number will appear on the AUR as1.0.0-2archis an array of architectures the build file supportsdependsis an array of dependencies the package requires to runmakedependis an array of dependencies that are only required during buildsourceis an array of files that are used by the build, if there are any URLs they will be fetched during the installation processsha256sumsis an array ofsha256hashes for each of the files insourceif any of these do not match during the build the package will fail to install.licenseis an array of licenses for each of the files insource
After these definitions you are then able to define functions that run during the packaging process.
Prepare
Define actions in this function that set up required files for the
build step. beatoraja does not function without a skin folder so in my
prepare function I extract the downloaded skin file
fetching during setup.
prepare() {
# Beatoraja will fail to load without a default skin
unzip -o skin.zip
}
Build
Define actions in this function to build your packages files, since we're downloading a zip containing a binary we don't need to run any compilers or any other actions here, so we can just extract the file.
build() {
unzip -o LR2oraja.zip
}
Package
The package function actually moves built files around
and "installs" the package.
Here we create required folders in $pkgdir,
$pkgdir is a global variable that you can use to know
where packages will be installed. You never refer to a path directly.
The other useful global is $srcdir which is the path
where build() and prepare() run.
# Create required directories
cd "$srcdir/"
mkdir -p "$pkgdir/opt/beatoraja/ir"
mkdir -p "$pkgdir/usr/lib"
mkdir -p "$pkgdir/usr/share/applications"
mkdir -p "$pkgdir/usr/share/pixmaps"
We then move all the files we created during build() and
prepare() into those newly created directories & set
permissions.
# Move all required Beatoraja Files
cp libjportaudio.so "$pkgdir/usr/lib"
cp beatoraja.jar "$pkgdir/opt/beatoraja/beatoraja.jar"
cp -r skin "$pkgdir/opt/beatoraja"
cp "bokutachiIR-3.0.0.jar" "$pkgdir/opt/beatoraja/ir"
chmod -R 777 "$pkgdir/opt/beatoraja"
We then create a .desktop entry to make the game easier
to launch, it's a bit tedious but this echo append
method is consistent.
# Create Desktop entry
cp lr2oraja-icon.png "$pkgdir/usr/share/pixmaps"
desktopEntry="$pkgdir/usr/share/applications/lr2oraja.desktop"
touch "$desktopEntry"
echo "[Desktop Entry]" >> "$desktopEntry"
echo "Type=Application" >> "$desktopEntry"
echo "Terminal=true" >> "$desktopEntry"
echo "Exec=/usr/bin/beatoraja" >> "$desktopEntry"
echo "Version=$pkgver" >> "$desktopEntry"
echo "Name=LR2oraja" >> "$desktopEntry"
echo "Categories=Games;" >> "$desktopEntry"
echo "Icon=lr2oraja-icon" >> "$desktopEntry"
Finally, we create a symlink to the games install location at the
users $XDG_CONFIG_HOME, if this isn't set we create
it at ~/.config. The last line here just moves the start
script into the users bin folder. We create this symlink since most
users expect program configuration files to exist in their systems
config folder, Since LR2oraja is not linux native all the config files
exist in its installation directory - This symlink just connects
~/.config/beatoraja to that install location.
if [ -z "$XDG_CONFIG_HOME" ]; then
XDG_CONFIG_HOME="$HOME/.config"
fi
# Create config symlink
ln -sfn "$pkgdir/opt/beatoraja" "$XDG_CONFIG_HOME/beatoraja"
# Install LR2oraja
install -D beatoraja.sh "$pkgdir/usr/bin/beatoraja"
Distributing
Once you've set up and configured your PKGBUILD file
you need to generate a .SRCINFO file. This can be done
with a single command:
makepkg --printsrcinfo > .SRCINFO
You can then test your package installation by running:
makepkg
pacman -U myPackageName.pkg.tar.zst
Once you know your package is working you can initialise a git repo & push to the AUR. Here are a few gotchas that caught me as well as some tips:
- Your entire repo & it's history must be smaller than around 1-2mb. Your repo should contain as little as possible - preferably only text files!
- Every commit in the repo must result in a successful build. No "WIP" commits.
- Always remember to bump your
pkgrelwhen making small changes to your build files - If you are working with a frequently changing code base or repo,
ensure you configure your
sourceurls andpkgversionin a way where you can avoid having to make major changes to the build file any time a change is made to the original codebase. The LR2orajaPKGBUILDrefers only to the static release files on GitHub - where the package version number is the version number used in the releases URL. This allows me to just change the version number to fetch the latest version.
Here's the official guidelines and steps for submitting a package to the AUR.
If everything worked and your package is now appearing on the AUR you can install it using your favourite AUR helper!
yay -Syu lr2oraja
If you want to view the final PKGBUILD for LR2oraja you can do so here.