In depth guide on how to create/update AUR packages.
base-devel: A group of packages containing essential build tools likemakeandgcc.git: The version control system used to interact with the AUR.pacman-contrib: Provides helpful utilities, most notablyupdpkgsums.
These packages can be installed with pacman:
sudo pacman -S --needed base-devel git pacman-contribIn order to interact with AUR, you would need to setup ssh. This means that you need to generate a new SSH key and add it to the AUR website.
If you don't already have an ssh key for AUR, create one. It's better to use ed25519 as it is considered to be more secure:
ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/keys/ed25519/some_key_nameThe command above would generate 2 files:
~/.ssh/keys/ed25519/some_key_name(private key)~/.ssh/keys/ed25519/some_key_name.pub(public key)
There are 2 paths you can take:
-
Using bare
ssh-agent: You would need to associate that private key with AUR, this can be done by adding following lines into the~/.ssh/configfile:# ~/.ssh/config Host aur.archlinux.org IdentityFile ~/.ssh/keys/ed25519/some_key_name User some_aur_username
-
Using
ssh-agentwith KeePassXC:You would need to enable SSH Agent integration on of these ways:
- Enable SSH Agent integration in KeePassXC settings.
- Add the following line to your
~/.config/keepassxc/keepassxc.conffile:[SSHAgent] Enabled=true
Then you would need to create a new entry in KeePassXC with the following fields:
- Entry > Username: some_aur_username
- Entry > Password: keyphrase you used when creating the SSH key
- Entry > URL: https://aur.archlinux.org
- SSH Agent > Add key to agent ...: true
- SSH Agent > Remove key from agent ...: true
- SSH Agent > External file: ~/.ssh/keys/ed25519/some_key_name
Then you can manually add agent to the SSH Agent by pressing the "Add to agent" button in the SSH Agent section.
- Copy your public key to the clipboard
xclip -sel clip < ~/.ssh/keys/ed25519/some_key_name.pub
- Go to the AUR website: aur.archlinux.org
- Log in, go to My Account, and paste your public key into the "SSH Public Keys" text box. It should look like that:
ssh-ed25519 AAAAAAAaaAAAaAaAAAaaAaaaAAAaAaAa/AaaaAAaaAaAaAaaAAaAaaaAAaAAAAaAaAAA
You have 2 ways of creating a new package repository:
-
Clone repository from aur:
cd ~/aur_directory/ git clone ssh://some_aur_username@aur.archlinux.org/some_package_name.git cd some_package_name git switch -c master
-
Use local repository and add remote:
cd ~/aur_directory/some_package_name git switch -c master git remote add label ssh://some_aur_username@aur.archlinux.org/some_package_name.git
This step is optional, but I would recommend it to keep your package repository clean.
Just create .gitignore file with following contents:
# Ignore everything by default
*
# Un-ignore the files required for version control and packaging
## Core AUR package metadata.
!.gitignore
!PKGBUILD
!.SRCINFO
## License files for compliance.
!LICENSE
!/LICENSES/*
## Helper scripts and assets that are common for package source.
!*.install
!*.changelog
!*.patch
!*.desktop
!*.sh
!*.toml
## PGP signatures for source file verification.
!*.asc
!/keys/gpg/*.ascThis should cover most of the cases.
The PKGBUILD file is the most important file in your package repository. It contains all the necessary information about your package, such as its name, version, dependencies, and build instructions.
In order to create a PKGBUILD file, you can just copy template:
tail -n +6 /usr/share/pacman/PKGBUILD.proto > PKGBUILDNow you should fill following required metadata fields:
| Variable | Description | Example |
|---|---|---|
pkgname |
The name of the package (should match the name of the package). | pkgname=firefox pkgname=('firefox' 'firefox-i18n-en-us') |
pkgver |
The upstream version of the software. Can be automatically updated with a pkgver() function. |
pkgver=94.0.1 |
pkgrel |
Your package release number (should start with 1). Increment it with each new package update. | pkgrel=1 |
arch |
The architecture(s) it can be built for. According to the AUR guidelines should always be compatible with 'x86_64' |
arch=('x86_64') arch=('any') |
Also you can fill in optional metadata fields:
| Variable | Description | Example |
|---|---|---|
epoch |
Used to force a package upgrade when the version numbering scheme changes. Must be non-negative integer. | epoch=1 |
pkgdesc |
A brief, one-line description of the package. | pkgdesc="A popular open-source web browser" |
url |
The official website of the software. | url="https://www.mozilla.org/firefox/" |
license |
The license(s) under which the software is distributed. | license=('GPL3') license=('GPL2' 'LGPL3') |
groups |
An array of package groups this package belongs to. | groups=('network' 'web-browser') |
In order to specify relations with other packages, use this fields:
| Variable | Description | Example |
|---|---|---|
depends |
Packages required for the software to run. | depends=('gtk3' 'libx11' 'alsa-lib') |
makedepends |
Packages needed only to build the software, not to run it. | makedepends=('rust' 'cargo' 'clang') |
checkdepends |
Packages required to run the test suite during the build process. | checkdepends=('pytest' 'dbus-test-runner') |
optdepends |
Optional packages that provide additional functionality. | depends=('gtk3' 'libx11' 'alsa-lib') |
depends |
Packages required for the software to run. | optdepends=('hunspell: for spell checking') |
provides |
A list of other package names or virtual provisions that this package fulfills. | provides=('web-browser') provides=("${_pkgname}=${pkgver}") |
conflicts |
A list of packages that cannot be installed at the same time as this one. | conflicts=('firefox-esr') |
replaces |
A list of packages that this package is intended to replace. | replaces=('firefox-beta') |
Also you would need to specify how sources should be obtained and built.
| Variable | Description | Example |
|---|---|---|
source |
An array of files required to build the package. This can include URLs, local files, and version control systems. | source=("$pkgname-$pkgver.tar.bz2::https://ftp.mozilla.org/pub/firefox/releases/$pkgver/source/firefox-$pkgver.source.tar.xz") source=("$pkgname::git+https://github.com/mozilla/gecko-dev.git") |
noextract |
An array of files from the source array that should not be extracted. |
noextract=("$pkgname-$pkgver.tar.bz2") |
options |
An array to override default makepkg behavior. |
options=('!strip' 'docs' '!libtool' 'staticlibs') |
In order to verify the integrity of the source files, you can use following variables:
| Variable | Description | Example |
|---|---|---|
validpgpkeys |
An array of PGP key fingerprints to verify the integrity of the source files. | validpgpkeys=('1234567890ABCDEF1234567890ABCDEF12345678') |
cksums |
Arrays of checksums to verify the integrity of the source files. | |
md5sums |
||
sha1sums |
There are 2 ways to automatically generate checksums: | |
sha224sums |
1. updpkgsums |
|
sha256sums |
2. makepkg -g >> PKGBUILD |
sha256sums=('abcdef123456...') sha256sums=('SKIP') |
sha384sums |
||
sha512sums |
SKIP can be used to skip integrity checks. |
These variables handle files and scripts related to the package's installation.
| Variable | Description | Example |
|---|---|---|
install |
Specifies an installation script that is run when the package is installed, upgraded, or removed. | install=$pkgname.install |
changelog |
Specifies a changelog file to be included in the package. | changelog=$pkgname.changelog |
backup |
Files that should be backed up when the package is upgraded or removed. Used for configuration files in /etc. |
backup=('etc/firefox/profile/prefs.js') |
In order to build and package the software, the following functions may be used:
-
package(): This is a required function that installs the compiled files into the$pkgdirdirectory, which will become the root directory of the final package.package() { cd "$srcdir/$pkgname-$pkgver" make DESTDIR="$pkgdir/" install }
-
build(): This function contains the commands to compile the software. It runs inside the$srcdir.build() { cd "$srcdir/$pkgname-$pkgver" ./configure --prefix=/usr make }
-
check(): This optional function is for running the software's test suite.check() { cd "$srcdir/$pkgname-$pkgver" make check }
-
prepare(): This optional function is used to prepare the sources for building, such as applying patches. It runs after the sources are extracted.prepare() { cd "$srcdir/$pkgname-$pkgver" patch -p1 -i "$srcdir/some-patch.diff" }
For building multiple packages from a single PKGBUILD, you can define a pkgbase and use an array for pkgname. Then, create a separate package_*() function for each sub-package.
pkgbase=firefox
pkgname=('firefox' 'firefox-i18n-en-us')
# ... global variables ...
package_firefox() {
# ... packaging commands for the main firefox package
}
package_firefox-i18n-en-us() {
# ... packaging commands for the English language pack
}For more information about PKGBUILD format, you can read official man page or official wiki page.
Before you publish your package, you probably want to check whether it is works correctly.
In order to do this, you can run the following command:
makepkg -siThis will try to create the package and then install it locally.
After creating PKGBUILD, you must regenerate the .SRCINFO file, which contains package metadata used by the AUR website and package managers.
You can do this by running the following command:
makepkg --printsrcinfo > .SRCINFODO NOT FORGET TO REGENERATE THE
.SRCINFOFILE AFTER MAKING CHANGES TO THEPKGBUILDFILE.
Once you have tested your package and generated the .SRCINFO file, you can publish it to the AUR.
You can do this by committing your files to your local Git repository and pushing them to the AUR's remote server.
First of all, you should check status of the repository, verify all of the changes, and make sure you're on master branch:
git statusThen, you can stage your files:
git add PKGBUILD .SRCINFO .gitignore ...Next step is to commit your changes:
git commit -m "init(package): initial commit"Finally, you can push your changes to the AUR's remote server:
git push -u origin masterSometimes package would not be updated on the AUR website for some time. You can try fetching, for some reason, this will cause it update.
git fetchAs an AUR maintainer, your job continues after the initial publication. You are responsible for keeping the package up-to-date and responding to user feedback.
When the upstream software is updated, you should update your package to reflect the changes.
-
Navigate and Sync: Change into your local package repository and ensure it's up-to-date with the AUR remote.
cd ~/aur_directory/some_package_name git pull
-
Edit
PKGBUILD: Open thePKGBUILDfile and update thepkgvervariable to the new version number. It is standard practice to reset thepkgrelvariable back to1for any upstream version change. -
Update Checksums: The source file has changed, so the old checksums are now invalid. Use
updpkgsumsto automatically download the new source and update the hashes.updpkgsums
-
Regenerate
.SRCINFO: Since you've updated thepkgver, you must regenerate the.SRCINFOfile. This is a critical step.makepkg --printsrcinfo > .SRCINFO -
Test Again: Always build and test the new version locally before pushing it to ensure the update did not break anything.
makepkg -si
-
Commit and Push: Once you've confirmed everything works, commit the changes with a clear message and push them to the AUR.
git add PKGBUILD .SRCINFO git commit -m "upgpkg: package_name x.y.z-1" git push
Users will communicate with you primarily through the comments section on your AUR package page.
- Out-of-Date Flags: If a user flags your package as out-of-date, investigate and update it as soon as possible. Once you push the update, the flag will be removed automatically.
- Orphan Requests: If you no longer wish to maintain a package, you can "disown" it from the AUR web interface. If a maintainer is unresponsive for a significant period (generally over two weeks after an out-of-date flag), users can file an "orphan request" to have the package assigned to a new maintainer.
To create high-quality, reliable packages that benefit the community, it is essential to adhere to the official Arch package guidelines. The following is a summary of the most important points for AUR maintainers.
- Dependencies are Critical: The most common packaging error is incorrect dependencies. Use tools like
namcapon yourPKGBUILDand built package to detect missing or redundant dependencies. Do not rely on "transitive dependencies" (dependencies of your dependencies). - Use
optdepends: For functionality that is not essential, list the required packages in theoptdependsarray with a clear explanation (e.g.,optdepends=('cups: for printing support')). - Quote Your Variables: Always quote variables that may contain spaces, especially
$srcdirand$pkgdir. - PKGBUILD Readability: Keep line length below 100 characters and preserve the standard order of variables for consistency.
- Package Naming (
pkgname): Use only lowercase alphanumeric characters and@,.,_,+,-. Do not start the name with a hyphen or dot. - Upstream Version (
pkgver): This must match the version released by the upstream developer. If the upstream version contains a hyphen, replace it with an underscore (_). - Package Release (
pkgrel): This is your version number for the package build. It starts at1. Increment it every time you release a fix or improvement to thePKGBUILDfor the same upstream version. Whenpkgveris updated,pkgrelresets to1.
- Use Secure URLs: Always prefer
https://sources for downloads andgit+https://for Git repositories. - Verify Sources: Whenever possible, use PGP signatures to verify source integrity. This is more secure than checksums alone. Add the required PGP fingerprints to the
validpgpkeysarray. - Do Not Weaken Security: Never
'SKIP'a checksum or remove PGP verification just because an upstream release is broken or missing a signature. Address the issue properly.
The package() function is responsible for placing files in the correct locations within the $pkgdir directory. Adhere strictly to the standard Arch filesystem hierarchy.
| Directory | Purpose |
|---|---|
/etc/ |
System-wide configuration files. Use a subdirectory /etc/$pkgname/ if you have multiple files. |
/usr/bin/ |
Executable binaries. |
/usr/lib/ |
Libraries. |
/usr/lib/$pkgname/ |
Private package modules, plugins, etc. |
/usr/share/licenses/$pkgname/ |
The license file for the software. |
/usr/share/man/ |
Man pages. |
Important: Your packages must NEVER contain any of the following top-level directories: /bin, /sbin, /dev, /home, /srv, /media, /mnt, /proc, /root, /sys, /tmp, or /run.
Being a good package maintainer also means being a good open-source citizen.
- Report Bugs: If you find a bug that needs to be patched for the software to build or run correctly, report it to the upstream developers.
- Use Upstream Patches: Whenever possible, use official patches from upstream.
- Add Comments: If you apply a patch, add a comment in your
PKGBUILDwith a link to the relevant bug report or upstream commit. This helps future maintainers (including yourself) understand why the patch is needed.