.\" .\" Pkgfile manual page. .\" (C) 2018 by Fun, updated 2021 by John McQuah .\" .TH Pkgfile 5 "" "pkgutils #VERSION#" "" .SH NAME Pkgfile \- sourced by \fBpkgmk\fP(8) when building a package in the ports tree .SH DESCRIPTION a \fBbash\fP(1) script that tells \fBpkgmk\fP(8) where the source code for a port may be downloaded, and what to do once that source code is unpacked. .SH FILE FORMAT \fBPkgfile\fP starts with a header of commented lines, which are read by \fBprt\-get\fP(8) to resolve dependencies, or by \fBportspage\fP(1) to generate an HTML index of the ports collection. After the header \fBpkgmk\fP will expect to find definitions of several mandatory variables, including \fIname\fP, \fIversion\fP, \fIrelease\fP, the bash array \fIsource\fP, and the bash function \fIbuild()\fP. .SS Example: .EX # Description: A library for demonstrating how to create delicious ports. # 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/archive/$version/$version.tar.gz Makefile.in.patch) renames=($name\-$version.tar.gz SKIP) build() { cd $name\-$version patch \-p1 < ../Makefile.in.patch ./configure \-\-prefix=/usr make make DESTDIR=$PKG install rm \-rf $PKG/usr/info } .EE .SS General guidelines The name of a package should always be lowercase (e.g. \fBname=eterm\fP and not \fBname=Eterm\fP). In case the package is added to the CRUX ports system the exact same name should be used for the name of the directory in the ports structure, i.e. \fI/usr/ports/???/eterm\fP. .LP Do not combine several separately distributed programs/libraries into one package. Make several packages instead. .LP Use \fBprtverify\fP(1) to check the port. .SS Variable names .LP Do not add new variables to the \fBPkgfile\fP. 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 \fBpkgmk\fP are \fIname\fP, \fIversion\fP, \fIrelease\fP, and \fIsource\fP. Other names could be in conflict with internal variables in \fBpkgmk\fP. .LP Use the \fI$name\fP and \fI$version\fP variables to make the package easier to update/maintain. For example, .EX source=(http://xyz.org/$name\-$version.tar.gz) .EE is better than .EX source=(http://xyz.org/myprog\-1.0.3.tar.gz) .EE since the URL will automatically update when you modify the \fI$version\fP variable. .SS Support for renaming source files Note that in the \fBsomelib\fP example above, Joe Maintainer chose to define the optional bash array \fIrenames\fP (same length as \fIsource\fP), so that the ambiguously\-named file retrieved by FTP would not collide with another port's files, if downloaded into a common directory. The keyword \(oqSKIP\(cq was given in the \fIrenames\fP array to indicate that renaming was not necessary for the corresponding source file. SKIP should always be used for a file retrieved by \(oqports \-u\(cq, because the port maintainer has the freedom to choose an unambiguous name in the \fisource\fP array itself. .PP Tools from prior versions of CRUX, ignorant of the \fIrenames\fP array, will execute the \fIbuild\fP function using the original filenames given by the remote sources, after unpacking anything that matches the glob \(dq*.(tar|tar.gz|tar.Z|tgz|tar.bz2|tbz2|tar.xz|txz|tar.lzma|tar.lz|zip|rpm|7z)\(dq. A \fIbuild\fP function that does not rely on the specific names you choose for the downloaded sources will have maximum compatibility with previous versions of CRUX. At present the number of CRUX 3.6 (or earlier) deployments is probably too low for the use of \fIrenames\fP to be an issue. It thus becomes possible to avoid redefining \fIunpack_source()\fP when you want to keep a particular tarball intact, or to handle it with something other than the default bsdtar: simply rename the not\-to\-be\-unpacked tarball so that the new name fails to match the glob above, and then work with the new filename in \fIbuild()\fP. .SS Directories 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 closely as possible. .EX Directory Description --------- ------------ /usr/bin/ User command/application binaries /usr/sbin/ System binaries (e.g. daemons) /usr/lib/ Libraries /usr/include/ Header files /usr/lib// Plug\-ins, addons, etc /usr/share/man/ Man pages /usr/share// Data files /usr/etc// Configuration files /etc/ Configuration files for system software (daemons, etc) .EE .LP \fI/opt\fP directory is reserved for manually compiled/installed applications. Packages should never place anything there. .LP \fI/usr/libexec/\fP is not used in CRUX, thus packages should never install anything there. Use \fI/usr/lib//\fP instead. .SS Junk files .LP Packages should not contain "junk files". This includes: .IP \[bu] 2 info pages and other online documentation, man pages excluded (e.g. \fIusr/doc/*\fP, \fIREADME\fP, \fI*.info\fP, \fI*.html\fP, etc). .IP \[bu] Files related to NLS (national language support). If \fB\-\-disablei\-nls\fP is not available as an option to \fBconfigure\fP, then manually inserting \(oqrm \-rf $PKG/usr/share/locale\(cq near the end of the \fBbuild\fP function is an acceptable alternative. .IP \[bu] Useless or obsolete binaries (e.g. \fI/usr/games/banner\fP and \fI/sbin/mkfs.minix\fP). .LP Apart from these global rules, the definition of "junk" is often a matter of personal taste. One user might regard as "junk" the same files that another user sees as indispensible. See \fBOptional dependencies\fP below for a simple way to let your port handle such individual preferences automatically. .SS Header Provide a header including the following fields: .EX Name Meaning ---- ------- Description A short description of the package; keep it factual Maintainer Your full name and e\-mail address, obfuscated if you want URL A webpage with more information on this software package Depends on A list of dependencies, separated either by spaces or commas Optional A list of ports whose presence might affect the build process .EE Note that you should use the obfuscated email address (illustrated in the example above) if you want to put your ports in any of the official CRUX repositories. \fIDepends on\fP can be omitted if there are no dependencies. \fIOptional\fP can be omitted entirely, or just pared down to the set of optional dependencies that the maintainer has been able to test. There is currently no obligation for a maintainer to test all possible configurations when writing a port. .SS Dependencies Dependencies are supported by CRUX tools like \fBprt\-get\fP and \fBpkg\-get\fP. The following rules should be respected: .IP "" 4 List all runtime dependencies except for gcc (libstdc++) and glibc. .IP "" 4 \fBcore\fP contains essential packages for a CRUX system, and our scripts and ports expect the programs provided by \fBcore\fP to be installed; this means that: .IP "" 8 build dependencies provided by \fBcore\fP are not listed in the dependency header .IP "" 8 run-time dependencies from \fBcore\fP which aren't dynamically linked in are not to be listed, either .TP Examples: .IP "" 4 \fBopt/sloccount\fP does \fInot\fP list \fBperl\fP, because the program is a perl script \-\- there's no binary that links to \fBlibperl\fP .IP "" 4 \fBopt/libxml2\fP \fIdoes\fP list \fBzlib\fP, because \fBlibxml\fP is linked to \fBlibz\fP. .LP The reasoning for these guidelines is that you can use \fBrevdep\fP to find ports 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 \fBldd\fP or \fBfinddeps\fP. .SS Optional dependencies A common practice among port maintainers is to put filesystem tests in the \fIbuild\fP function, allowing the package configuration to vary depending on what other packages the system administrator has installed. This practice can result in footprint mismatches. It is recommended that maintainers build their ports in a container with the bare minimum of dependencies, or prune the auto\-generated footprint so that the spurious files are not reported as MISSING on another user's system. .PP Filesystem tests are also useful at the end of a \fIbuild\fP function, for example when determining which shell completions should be installed. Here is a template for tests of this kind: .EX prt\-get isinst bash\-completion || rm \-rf $PKG/usr/share/bash\-completion prt\-get isinst zsh || rm \-rf $PKG/usr/share/zsh prt\-get isinst fish || rm \-rf $PKG/usr/share/fish .EE .PP If the maintainer built the package in a clean container, then another user with fish installed will see the path /usr/share/fish listed as NEW in the footprint mismatch, and that user can proceed with installation if PKGMK_IGNORE_NEW was enabled in \fBpkgmk.conf\fP(5). More dangerous is the reverse situation: the maintainer built the package in a system with fish, and a user without fish sees /usr/share/fish listed as MISSING in the footprint mismatch. Users should not be encouraged to disregard MISSING, but enabling PKGMK_IGNORE_NEW is generally safe. .PP Maintainers are encouraged to build offline documentation (man\-pages) into their ports, but this practice nowadays might involve dependencies that are not necessary for running the actual program. If the dependency chain is too convoluted, list the man\-page\-generating dependency as \fBOptional\fP, or provide pre\-compiled man\-pages with the port itself. .TP Examples: .IP "" 4 \fBgreetd\fP lists \fBscdoc\fP among the optional dependencies, which if installed will allow the man\-pages to be generated during the build. .IP "" 4 \fBmpd\fP lists \fBpython3\-sphinx\fP among the optional dependencies for the same reason. .SS rc start scripts You can use the following template for ports that provide some sort of daemon. The runnable script should be called \fI$name.rc\fP, and your port should install it to \fI/etc/rc.d/$name\fP. The installation can happen by calling the following in your \fIbuild\fP function: .EX install \-D \-m 755 $SRC/$name.rc $PKG/etc/rc.d/$name .EE .LP See the existing scripts under /etc/rc.d for examples of using \fBstart\-stop\-daemon\fP(8) to generate the necessary pid files, temp directories, and logs for your daemon. .SH ERRORS .LP Most of the command failures in \fIbuild()\fP 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: .EX \fBif ! command...; then ...\fP \fBcommand || ...\fP .SH ENVIRONMENT .LP The \fIbuild\fP function should use the \fISRC\fP variable whenever it needs to access the files listed in the source variable, and the \fIPKG\fP variable as the root destination of the output files. .LP Being a shell script executed in the context of \fBpkgmk\fP(8), the entire \fBPkgfile\fP has access to the variables initialized in \fBpkgmk.conf\fP(5) and the default values set by \fBpkgmk\fP(8). Also, as a side effect of how it is used by \fBpkgmk\fP(8), the Pkgfile can also change the behaviour of \fBpkgmk\fP(8) by rewriting some of its functions and variables before \fIbuild()\fP is called. However, the \fIbuild\fP function itself has only read access to these environment variables and shell functions. .LP The separation between the bash\-interpreted lines (uncommented) and the Pkgfile header (commented, at the top) does not map cleanly onto the separation between \fBpkgmk\fP(8) and \fBprt\-get\fP(8). At least two of the variables initialized in the Pkgfile are also parsed by \fBprt\-get\fP(8), namely, \fIversion\fP and \fIrelease\fP which are needed to obtain the filename that should be passed to \fBpkgadd\fP(8). Note that to determine the value of \fIversion\fP (or \fIrelease\fP), \fBprt\-get\fP uses neither \fBbash\fP(1) nor the rest of the Pkgfile, but instead /bin/sh and the single line that begins with \(dqversion=\(dq (or \(dqrelease=\(dq). Defining \fIversion\fP (or \fIrelease\fP) as anything other than a constant string (or positive integer) might cause breakage after the pkgmk step. .SH FUTURE\-PROOFING Ideas for future development of \fBpkgmk\fP, if implemented, would entail corresponding amendments of the Pkgfile format. Port maintainers should be alert to several such possibilities. .PP One shortcoming of the current pkgmk is its lack of support for the git protocol when downloading sources. If this feature is added, then the \fIsource\fP array will acquire further restrictions (e.g., a special prefix that tells pkgmk to switch from curl/wget and use git instead). Implementing git support should not cause widespread breakage, unless Pkgfile authors inadvertently populate their \fIsource\fP arrays with names that collide with the globs we decide to reserve for git. .PP Another proposal under consideration is to allow end users to incorporate their port customizations at the pkgmk step, rather than into a post\-sync hook (where the attempt to apply an outdated patch might corrupt a freshly-synced ports tree). To plan for this possibility, Pkgfile authors should avoid the function names \fIoverlay_download\fP and \fIoverlay_build\fP, which might complement \fIdownload_source\fP or replace \fIbuild\fP, respectively. The simple overlay proposal in its current form cannot influence dependency resolution, because there is no mechanism for passing information from pkgmk into a prt\-get dependency calculation. Authors of Pkgfiles can still expect feedback from downstream users who want to see something added or removed in the \(dqDepends on:\(dq or \(dqOptional:\(dq lines; the current overlay proposal would not distribute this aspect of port maintenance among the wider CRUX userbase. .PP Breaking up the current \fIbuild()\fP into two separate functions, \fIconfigure()\fP and \fIbuild()\fP, would make the simple overlay proposal smoother to implement. Pkgfiles that define a standalone \fIconfigure()\fP and call that function from within the current \fIbuild()\fP are well\-prepared for transitioning to such a future Pkgfile format. .PP A crux\-devel thread from February 2004 debated whether to have dependencies listed as array variables (visible to the pkgmk process) or to leave them as commented lines in the header (visible to prt\-get and tools of a similar scope). The current separation of concerns (prt\-get and friends concerned with the header and a few of the uncommented lines, from \fBevery port in the active repos\fP; pkgmk concerned only with the uncommented lines, in the Pkgfile under $PWD and the global config /etc/pkgmk.conf) was regarded as the tidiest way to coordinate our tools. If the simple overlay proposal acquires ambitions to influence prt\-get operations too, then a channel must be opened to inform prt\-get about whatever pkgmk learns from the user's overlay. Such a channel can only rely on definitions that pkgmk is aware of, which might require promoting some header fields to actual shell variables. To guard against such a promotion causing problems, port maintainers are advised to inspect their Pkgfile header fields for strings that bash would not accept as values of a shell variable. .EE .SH SEE ALSO .TP pkgmk(8) .TP pkgmk.conf(5) .TP https://crux.nu/Main/PortGuidelines .TP https://crux.nu/Main/PrePostInstallGuidelines .TP https://lists.crux.nu/archives/list/crux\-devel@lists.crux.nu/thread/CW7FMOR2QZYUY5BU3GNKMY3G6BMP7Q3U/#52BWHNUXTTLKB4X53PT52T7XGBT7QURV .TP https://crux.nu/Wiki/PkgutilsIdeas .SH COPYRIGHT pkgmk (pkgutils) is Copyright (c) 2000\-2005 Per Liden and Copyright (c) 2006\-2024 CRUX team (https://crux.nu). pkgmk (pkgutils) is licensed through the GNU General Public License. Read the COPYING file for the complete license.