PKGFILE(5) | File Formats Manual | PKGFILE(5) |
Pkgfile
— build
file for pkgmk
Pkgfile |
This manual page describes the format of the Pkgfile file. The file is a POSIX sh(1p) script with some exceptions (see below), which defines a number of variables (name, version, release and source) and a function (build) that should be executed in order to compile a package.
In POSIX sh, “local
” is
undefined. You can adopt some convention to avoid accidentally overwriting
variable names, e.g. prefixing with the function name:
build() { _build_foo="bar" ... }
However, “local
” is
supported in many shells, including
bash(1),
ksh(1),
dash(1) (which is used in Zeppe-Lin as
default /bin/sh provider), and BusyBox'
ash(1). So, strictly speaking, it's not
POSIX, but since quite a lot of real world shells support this feature,
prefixing variables is little ugly, and finding bugs with overwriting
variables is a big headache for developers, it was decided to allow
"local
". In the end, the choice is yours
to use or not.
The name of a package should always be lowercase (e.g. “name=eterm” and not “name=Eterm”). Dashes are also allowed.
In case the package is added to the packages sources tree the exact same name should be used for the name of the directory in the packages sources structure (e.g. /usr/src/pkgsrc-???/eterm).
Do not combine several separately distributed programs/libraries into one package. Make several packages instead.
In general packages should install files in these directories. Exceptions are of course allowed if there is a good reason. But try to follow the following directory structure as close as possible.
Directory | Description |
/usr/bin | User command/application binaries |
/usr/sbin | System binaries (e.g. daemons) |
/usr/lib | Libraries |
/usr/include | Header files |
/usr/lib/⟨prog⟩ | Plug-ins, add-ons, etc |
/usr/share/man | Man pages |
/usr/share/⟨prog⟩ | Data files |
/usr/etc/⟨prog⟩ | Configuration files |
/etc | Configuration files for system software (daemons, etc) |
/opt directory is reserved for manually compiled/installed applications, or binary distributable packages. Good packages (built from sources) should never place anything there.
/usr/libexec is not used, thus packages should never install anything there. Use “/usr/lib/⟨prog⟩” instead.
Packages should not contain “junk files”. This includes info pages and other online documentation, man pages excluded (e.g. “/usr/share/doc”, “README”, “*.info”, “*.html”, etc).
Also should be removed:
Do not add new variables to the Pkgfile. Only in very few cases does this actually improve the readability or the quality of the package. Further, the only variables that are guaranteed to work with future versions of pkgmk(8) are “name”, “version”, “release”, and “source”. Other names could be in conflict with internal variables in pkgmk(8). Use the “$name” and “$version” variables to make the package easier to update/maintain. For example,
source=http://xyz.org/$name-$version.tar.gz
is better than
source=http://xyz.org/longprogramname-1.0.3.tar.gz
since the URL will automatically updated when you modify the “version” variable.
Note that “source” variable is a string, where each item is separated by a whitespace. If you want to specify multiple URIs/files, use quotes:
source="http://xyz.org/$name-$version.tar.gz http://xyz.org/$name-$version.patch"
By the way, while building packages, sometimes source tarballs have names that could collide with other sources. So, pkgmk(8) allows renaming the downloaded source by prefixing the URL like this:
source="$name-$version.tar.gz::http://xyz.org/v$version.tar.gz $name-$version.patch::http://xyz.org/$name.patch"
Provide a header including the following fields:
Name | Meaning |
Description | Short description of the package (keep it factual) |
Maintainer | Your full name and e-mail address (can be obfuscated) |
URL | Website with more information on this software package |
Depends on | List of dependencies, separated either by spaces |
“Depends on” can be omitted if there are no dependencies.
Dependencies are supported by pkgman(1). The following rules should be respected:
Examples:
The reasoning for this policy is that you can use revdep(1) to find packages that need to be updated if one of the dependent libraries has become binary incompatible. To find out what libraries a binary is linked to, use ldd(1) or finddeps-linked(1).
Also, in the case of updating the major version of Perl/Python/etc, it will be useful that the libraries or programs that create Perl/Python bindings have a dependency on them. We will have to rebuild everything that depends on Perl/Python with one command. See pkgman-rdep(1).
The actual scripts that control services should be named “rc.⟨prog⟩”, and installed to “/etc/rc.d/⟨prog⟩”. See RC Script for template script for a package.
Runscripts are supported by pkgman(1). Packages should be built with the idea in mind that people won't execute the “pre-install”, “post-install”, “pre-remove”, and “post-remove” scripts. This is entirely true for “corepkgsrc collection”, and varies from one to another collections. Such strict requirements for core comes from the fact that the packages in this collection are designed to be installed in a separate root directory by pkgadd(8) utility.
If a package adds an user to the system using “pre-install”, a “pre-remove” script must remove that user.
What these scripts should not do:
The above prohibitions apply only to packages in the official pkgsrc repositories. You may not follow them in your own collections if you need more sophisticated setups. Obviously enough.
The “build” function should use the “$SRC” variable whenever it needs to access the files listed in the “source” variable, and the “$PKG” variable as the root destination of the output files.
Being a shell script executed in the context of pkgmk(8), the entire Pkgfile file has access to the variables initialized in pkgmk.conf and the default values set by pkgmk(8). Also, as an undocumented side affect of how it is used by pkgmk(8), it can also change the behaviour of pkgmk(8) by rewriting some of its functions and variables while the current package is built. However, the build function has only read access to these mentioned above.
Most of the command failures in build function will stop the build process. There is no need to explicitly check the return codes. If you need/want to handle a command failure you should use constructs like:
if ! command ... ; then ... ; fi command || ...
# Description: Concise description without articles and trailing dot # URL: http://www.gnu.org/software/somelib/index.html # Maintainer: Joe Maintainer, joe at myfantasticisp dot net # Depends on: someotherlib coolness name=somelib version=1.2.3 release=1 source="ftp://ftp.gnu.org/gnu/$name/$name-$version.tar.gz Makefile.in.patch" build() { cd $name-$version patch -p1 -i ../Makefile.in.patch ./configure --prefix=/usr make V=1 make DESTDIR=$PKG install rm -rf $PKG/usr/info }
#!/bin/sh # # /etc/rc.d/daemon: start/stop daemon(8) daemon # SSD=/sbin/start-stop-daemon PROG=/usr/sbin/daemon PID=/run/daemon.pid OPTS="--some-opts" case $1 in start) $SSD --start --pidfile $PID --exec $PROG -- $OPTS ;; stop) $SSD --stop --pidfile $PID --retry 10 ;; restart) $0 stop $0 start ;; status) $SSD --status --pidfile $PID case $? in 0) echo "$PROG is running with pid $(cat $PID)" ;; 1) echo "$PROG is not running but the pid file $PID exists" ;; 3) echo "$PROG is not running" ;; 4) echo "Unable to determine the program status" ;; esac *) echo "usage: $0 [start|stop|restart|status]" ;; esac # End of file.
The initial version of this manual page was written by Just-The-Real-Fun <just.the.real.fun@gmail.com> for CRUX.
This implementation was extensively re-worked and adapted for Zeppe-Lin by Alexandr Savca <alexandr.savca89@gmail.com>.
September 6, 2023 | Zeppe-Lin |