Thanks throgh. This will be enough to get me on my way.
Also for educational purposes I found some resources for creating PKGBUILDs. Please review and correct me if I said something wrong. My notes yanked from what I read:
1. Download the source tarball of the software to package.
2. Try compiling the package and installing it into an arbitrary directory.
3. Copy over the prototype /usr/share/pacman/PKGBUILD.proto and rename it to PKGBUILD in a temporary working directory.
4. Edit the PKGBUILD according to the needs of your package.
5. Run makepkg and check whether the package builds correctly.
6. If not, repeat the previous two steps.
PKGBUILDs are simply bash scripts with pre-defined names for the functions and variables.
Lines 1-5 contain comments (non-code) that credit the maintainers and contributors. These are just for reference when you distribute your PKGBUILD, and are ignored when the package is built. If you write your own PKGBUILD, or start to maintain one, then you generally put your name as the Maintainer along with an email address. Just sending in patches to help things build you can add your name to the list of Contributors. This will help people that have build failures know who to contact. Keep the Arch/Debian/etc other distro's maintainers and contributors in the top and add the Hyperbola ones beneath that, as one Maintainer and however many Contributors. If you are the new maintainer of a previously maintained Hyperbola package, move the previous maintainer's name to the contributor list and take over maintainership.
Lines starting with pkgname all the way to sha512sums contain variable declarations. A PKGBUILD has certain variables that describe the package that is going to be built. 6 variables are required: pkgname, pkgver, pkgrel, pkgdesc, url, and license. You can do man pkgbuild to get all possible variables.
pkgname. Usually the pkgname is the same as the upstream name for the software, but for certain things you may want a different name in case you are going to have conflicts with other packages. (ie: grep-kaictl if I add a patch to the official grep package, but want it to be seen separately). There are also development packages that are called 'foo-git' or 'bar-svn', etc.
Example: the official grep package fails to work on my system because something is wrong with it, and i need to fix it. I could just edit the grep pkgbuild and add the patch without changing the name, however on the next -Syu, if the version of grep in the repos is higher than my local grep, it will replace mine with the official package.
Example: I have custom PKGBUILDs for gtk3 which disables a few options and includes a patch to fix a focus issue. I called the package gtk3-light-fixed so that it won’t conflict when pacman wants to update gtk3.
pkgver, _debver, _debrel, and pkgrel: While they all help to describe the full version of the package, they are separate. pkgver describes the upstream version, and pkgrel is used when something on the Hyperbola side changes (ie, configure flags change, a rebuild is required, etc.) _debver and _debrel refer to Debian and _debver is the upstream equivalent while _debrel refers to the Debian package version.??? "The variable is not allowed to contain colons or hyphens" (from pkgbuild manpage). The reason for this is due to how pacman finds the package version. When upstream package versions have hyphens, you replace them with periods (.) or underscores (_). Pacman uses hyphens as delimiters to determine the package name and version, so otherwise it would get confused. (Here is the code which describes why no hyphens are allowed in the pkgver variable: <https://projects.archlinux.org/pacman.g … il.c#n1060>. It is also well commented.)
pkgdesc and url: These have no format, except that they must be a single 'word' as seen by bash. Note that a 'word' is anything in quotes, so "this is a single word to bash". If you glance at the pkgbuild man page, they say to keep the description to 1 line, most of the time this means 80 characters or so. The url should send people to a place containing more verbose descriptions.
The next few variables are all arrays, or ordered lists. Bash arrays are used quite often in PKGBUILDs. Anything structured foo=('bar' 'baz') is an array foo with elements bar and baz. If you use python, it's exactly like a list(), not a set() ... the array is delimited by spaces, and every variable in the array should be in quotes. Single and double quotes both have different meanings. Each array element is delimited by something called the "IFS" (Internal Field Seperator). By default this is set to " \n\t", so it will delimit on a space, a tab and a newline. But it is good to have quotes.
arch: so if we look at the arch=() array, you can see that it contains the two arches that Hyperbola supports. There are three choices for arch=(): 'i686', 'x86_64', and 'any' if you use the 'i686' or 'x86_64', when the package is built it is created for the system that built it (if I build mdadm, it will it will make it x86_64, and won't run on i686 machines). 'Any' is used for scripts and things that are not arch dependent. So when I build an 'any' package, the final product can be used anywhere. For example, a bash or python script which doesn't use compiled code. Or anything not dependent on CPU architecture. These can run on any machine.
license=(). Example: license=('GPL2' 'LGPL2.1' 'MIT') This is an array, not a single variable, because some packages use multiple licenses for their software. If you look in /usr/share/licenses/common/, you will see a list of licenses that you can use in your packages. If the license the package uses has been modified, then you should manually include it in the package function. If the package uses a totally different license, then you can use the 'custom:licensename' declaration. Make sure the license is an approved license, compatible with the GPL per Hyperbola's software guidelines. Keep in mind that some licenses /require/ that it is shiped with the software. Such as MIT or BSD-2clause. Those packages need the LICENSE file to be installed. When looking for and identifying the license of a package, usually you will find licenses in the source in a file such as 'COPYING', or 'LICENSE'; otherwise, it may be at the top of the source code files.
groups=(). This refers not to the user groups, but to package groups in the distro. It's just a convenient way to install multiple packages without typing each name. When you go to install arch linux from a live cd, you run 'pacstrap base', which installs the 'base' package group. This pulls in all the packages belonging to that group. Other examples include gnome and kde. A package can be part of multiple groups. You can use pacman -Sg <group> to see the packages in a group. You can also use pacman -Qg to list installed members of a group.
depends, makedepends, checkdepends, and optdepends: depends=() is for things that are required /after/ the build, sometimes known as runtime dependencies. You may need them to build, but you also need them to run the final product. If you use comparison operators, such as '>' and '<=', etc. in an array it MUST be single quoted. depends=(bash>=3.2) will fail whereas depends=('bash>=3.2') will work. Also, it is generally discouraged to use the version comparison stuff, as that requires rebuilds each time your requirements change.
makedepends=() are only required for building the package. For most -git packages, 'git' is a makedepend. It's required to build the package, but whatever came out the other side doesn't need git to run.
Some packages have a check() function to make sure things built correctly, and may require extra packages for running these checks. You would include these packages in the checkdepends=() array. This allows people using --no-check not to get those packages that are only needed for checking.
optdepends: each word is more than just a pkgname, it's a 'pkgname: reason why', which lets people know dependencies that are not required for the software to run, but may be for things that are useful or extra functionality.
provides=(), conflicts=(), replaces=():
provides=() is used to give pacman 'virtual packages'. In the past, pacman was a split package, including pacman and pacman-contrib. Some packages required scripts in pacman-contrib, and have not been updated in the AUR or the official packages yet, so if you tried to install them without the provides array in pacman, you would get an error since nothing you have matches pacman-contrib and nothing in the repos is called pacman-contrib. 'Virtual dependencies' solve this problem. Now, with pacman installed, the other package will see that pacman *provides* another package as well. Most of the time this is used for development packages, or for patched packages like grep-kaictl. Because 'grep' is required by a whole bunch of stuff, i would add 'provides=('grep')' to my grep-kaictl pkgbuild so that those packages can continue to see grep installed on my system.
But usually just providing a package is not enough. Because your package provides the files in package-2, you also have to conflicts=() with package-2 so that users can't try to install 2 of the same packages.
replaces=() is rarely used. e.g. pacman and pacman-contrib were combined into a single package. This means that pacman replaces pacman-contrib. if it was just a conflict, then there would be a choice to keep /either/ pacman or pacman-contrib. with replaces, pacman takes precedence. So, it should really only be used for combined or renamed packages.
backup=() tells pacman to backup specified configuration files in /etc so pacman does not blindly overwrite them when upgrading. And pacman will write them as .pacnew and .pacsave files. .pacnew files are created when a new backup file is installed, so not overwrite the original. .pacsaves are backups that are generated after you remove a package. A .pacsave cannot be created on an upgrade, and a .pacnew cannot be created on a removal. You should only put files that you expect the user to edit in place. Don't put files in /usr/share/doc or anything in there when the user is expected to copy them to /etc or some other location. You can see the status of your installed backup files with pacman -Qii and if they've been modified.
source=(): The source array contains the sources you will be using. In pacman.conf, you can see two of the 3 types: an external link and a local file. These will be transferred to the $srcdir, and extracted if needed. If you don't use an http, ftp, etc. link to the source, you need to put the source=() files into the $SRCDEST or $startdir. ($SRCDEST can be set in your makepkg.conf, and is just a place to download source files, like $HOME/.cache/pacman/src). $SRCDEST is where source tarballs and files are downloaded, $srcdir is where they are extracted to. As you can see, any bash syntax is acceptable here, and while there is only one line of 'ftp://', there are actually two network files. By default, $SRCDEST goes to $startdir, not to $BUILDDIR/src -- but back to the main point: if you need source files to do things, put them in the source=() array.
validpgpkeys=() specifies which GPG keys are valid to verify package integrity, this would be the 40 character long public key fingerprint.
checksums: there are 5 different types of checksums you can have for the source files, md5, sha1, sha256, sha384, and sha512 checksums. (You only need one of these. Some people like to put in more than one, but that's really not needed.) Each file in the source array must have a value in the *sum array, and they must be in the same order.
However, if you look at the md5sums=() in pacman, there is one that says 'SKIP'. This is used for files that are constantly changed, or things where an md5sum would not be appropriate. Usually it is used for VCS sources. 'SKIP' is a valid sum in pacman's eyes, and it will skip validation of the file that 'SKIP' corresponds to.
Also, you can use 'makepkg -g' to generate a list of checksums for the sources a PKGBUILD, and there is a script called updpkgsums that can be used to update them inline. updpkgsums and makepkg -g will also download the sources if they aren't already there. In the makepkg.conf file you can set what type of sum makepkg -g will spit out, as well.
prepare(), pkgver(), build(), check(), and package(): Only these 5 will be called by makepkg in that order, any custom functions would have to be called in one of these official functions.
prepare() is used to set up sources, apply patches, run sed, etc. If your package has a ./configure, it should *not* go in prepare().
pkgver(): already mentioned above
build(): where actual building should go on. For sources with a Makefile, that's usually just './configure && make'. build() is where you build files. This is not a required function, however, and you don't need it. (e.g. if you're just installing some scripts to /usr/bin, you can't do that in build().) So if everything is prebuilt, and it just needs to be organized, you can use just the package() function, but you always have to have at least package, having only build() is no longer supported.
check(): is for checking the sanity of the build. If anything in the pkgbuild returns anything but 0 (non-0 exit status), makepkg will exit saying the checks failed. Generally only used for major system packages, like glibc or gcc or pacman, etc. It's also useful for development packages to make sure things will work after it's been installed. '|| return' is a common holdover from Gentoo build scripts, but is completely unnecessary.
package(): required in a PKGBUILD. In the makepkg script, $pkgdir gets set to 000 at the start. Nothing can write to it till the package() function can actually use the $pkgdir. The package() function is where you would put `make install`. After setting variables and writing these functions, you should have a root file structure in $pkgdir. Then, makepkg identifies the files for this package and puts them in a tarball. And that's what you get as a package (with a few extra files, too.) But if you have nothing in $pkgdir, then you're not going to get a package. In $pkgdir you will have a directory for the name of each package that is in the PKGBUILD. The thing that makepkg produces is a self contained package.