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:
pkgname
is the name of the package users will type to install the package, and what will appear on the AUR.pkgver
is 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.pkgrel
is the build-version of the package. You bump this value if you change the contents of the build script or a dependency. If you’repkgver
is1.0.0
and yourpkgrel
is2
the final version number will appear on the AUR as1.0.0-2
arch
is an array of architectures the build file supportsdepends
is an array of dependencies the package requires to runmakedepend
is an array of dependencies that are only required during buildsource
is an array of files that are used by the build, if there are any URLs they will be fetched during the installation processsha256sums
is an array ofsha256
hashes for each of the files insource
if any of these do not match during the build the package will fail to install.license
is 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
pkgrel
when making small changes to your build files - If you are working with a frequently changing code base or repo, ensure you configure your
source
urls andpkgversion
in 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 LR2orajaPKGBUILD
refers 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.