307 lines
12 KiB

! The Ports System
!! Introduction
!!! What is a Port?
A port is a directory containing the files needed for building a package using
'''pkgmk'''. This means that this directory at least has the files %fn%Pkgfile%%
(which is the package build description) and %fn%.footprint%% (which is used for
regression testing and contains a list of files this package is expected to
contain once it is built). Further, a port directory can contain patches and/or
other files needed for building the package. It is important to understand that
the actual source code for the package is not necessarily present in port
directory. Instead the %fn%Pkgfile%% contains an URL which points to a location
where the source can be downloaded.
The use of the word ''port'' in this context is borrowed from the BSD world,
where a ''port'' refers to a program that has been ported to a system or
platform. The word can sometimes be a bit misleading since most programs require
no actual porting to run on CRUX (or on Linux in general).
!!! What is the Ports System?
The term ''Ports System'' refers to a remote repository containing ports and a
client program capable of downloading ports from that repository. The
administrator of a CRUX system runs the '''ports(8)''' bash script to download
ports from the remote repository and place them in %fn%/usr/ports/%%. The
'''ports''' script uses rsync(1) or httpup(1) or git(1) to do the actual
!!! Port collections
CRUX ports are organized in so-called 'collections'. There are three different
layers of ports:
!!!! The official collections 'core', 'opt', 'xorg' and 'compat-32'
%fn%core%%, %fn%opt%%, %fn%xorg%% and %fn%compat-32%% are the four primary
collections of CRUX. They're maintained by the CRUX development team which
ensures that they're consistent and working well together. The first three are
enabled by default. The %fn%compat-32%% collection is disabled by default and
contains 32-bit compatibility ports.
!!!! The user contributed collection 'contrib'
The %fn%contrib%% collection is a collection which is provided by experienced
port maintainers: some are part of the CRUX development team, while others are
regular users. Its goal is to reduce the number of duplicate ports provided in
the individual collections. If you're a seasoned port maintainer, you might
even want to join the contrib collection.
As those ports are not provided officially by the CRUX development team, this
collection is disabled by default.
!!!! The individual collections from CRUX users
Using [[HttpUp]] or git, every user can publish his or her own ports easily; the
only requirement for that is some webspace to upload the ports. Maintaining an
HttpUp repository of ports, which you've tested and gotten successfully running,
is a simple way to contribute back to the CRUX community.
!! Using the Ports System
!!! Synchronizing Your Local Ports Structure
When CRUX is installed for the first time the local ports structure
(%fn%/usr/ports/%%) is empty. To bring your local ports structure up to date you
use the '''ports''' utility with the '''-u''' option. Example:
$ ports -u
The '''-u''' option means update, and tells '''ports''' to contact the ports
repository and download new and updated ports. The output from this execution is
something like this:
Updating file list from
Updating collection ports/crux-3.7/core/
Updating file list from
Updating collection ports/crux-3.7/opt/
Updating file list from
Updating collection ports/crux-3.7/xorg/
Finished successfully
The output reveals which files are downloaded, updated and deleted.
!!! Listing Local Ports
When the local ports structure has been updated the directory %fn%/usr/ports/%%
will contain at least two collections, %fn%core%% and %fn%opt%%. Under each of
these directories you will find ports. You can simply browse around in the
directory structure to find out which ports are available.
$ cd /usr/ports/core/
$ ls
acl/ httpup/ nftables/
attr/ iana-etc/ ninja/
autoconf/ inetutils/ openssh/
automake/ iproute2/ openssl/
bash/ iptables/ patch/
bc/ jansson/ pciutils/
binutils/ jsoncpp/ perl/
bison/ kbd/ pkgconf/
bzip2/ kmod/ pkgutils/
ca-certificates/ less/ ports/
cmake/ libarchive/ procps/
coreutils/ libcap/ prt-get/
cpio/ libdevmapper/ psmisc/
curl/ libedit/ python3/
dash/ libffi/ python3-setuptools/
db/ libgmp/ rc/
dcron/ libmnl/ rdate/
dhcpcd/ libmpc/ readline/
diffutils/ libmpfr/ rhash/
dumb_runtime_dir/ libnftnl/ rsync/
e2fsprogs/ libnghttp2/ sed/
ed/ libnsl/ shadow/
elfutils/ libpcre/ signify/
eudev/ libpcre2/ sqlite3/
exim/ libpipeline/ start-stop-daemon/
expat/ libtirpc/ sudo/
file/ libtool/ sysfsutils/
filesystem/ libusb/ sysklogd/
findutils/ libuv/ sysvinit/
flex/ linux-pam/ tar/
gawk/ lzlib/ time/
gcc/ lzo/ tzdata/
gdbm/ m4/ usbutils/
gettext/ make/ util-linux/
glibc/ man-db/ vim/
glibc-32/ man-pages/ which/
gperf/ meson/ xz/
grep/ mlocate/ zlib/
groff/ mpdecimal/ zstd/
gzip/ nasm/
hdparm/ ncurses/
You can also use '''ports''' with the '''-l''' option to list all local ports. Example:
$ ports -l
If you are looking for a specific package, a command like @@ports -l | grep sendmail@@
provides a straightforward way to find out if the package is available and if so
in which collection it is located. More complicated searches (eg., based on
footprint, description, or maintainer) can be performed using @@prt-get@@.
!!! Listing Version Differences
To find out if the ports structure carries ports that are different (likely
newer) compared to the versions currently installed, you can use the option
'''-d'''. If differences are found (in either 'version' or 'release'), the
output from the above command could look something like this:
$ ports -d
Collection Name Port Installed
core glibc 2.3.6-3 2.3.6-2
opt gtk 2.8.12-1 2.8.11-1
If no version differences were found, i.e. the system is in sync with the ports
structure, the output will simply be:
$ ports -d
No differences found
!!! Building and Installing Packages
Once you have found a port that you want to build and install you simply go into
the desired port directory and use '''pkgmk''' to build it. Example:
$ cd /usr/ports/core/gawk
$ pkgmk -d
The '''-d''' option means download missing source files and tells '''pkgmk''' to
download the source(s) specified in the Pkgfile (in case the source is already
downloaded, this option is ignored). When the download is completed the package
will be built. If the package was built successfully you can use '''pkgadd''' to
install or upgrade it. Example:
$ pkgadd gawk#3.1.5-3.pkg.tar.gz
To make life a bit easier these two steps can be made into one by using the
options '''-i''' (for install) or '''-u''' (for upgrade). Example:
$ pkgmk -d -i
$ pkgmk -d -u
This will download, build and then install/upgrade the package. Note that the
package will only be installed/upgraded if the build is successful.
-> If you enable [[#NonRootBuilding | building ports as an unprivileged user]]
and give that user write permissions on the directories for pkgmk {sources, work,
packages}, the unprivileged user will be able to create a package but not to
exercise the '''-i''' and '''-u''' options of '''pkgmk'''. There are forks of
pkgmk that automatically invoke '''sudo''' or '''doas''' when performing the
'''pkgadd''' step, but these forks are not part of the official CRUX utilities
at this time.
!!! Enabling the 'contrib' collection
As previously mentioned, the 'contrib' collection contains useful ports of
experienced port maintainers. Since they are not provided by the CRUX
development team, you should be slightly more critical with respect to quality
and security. However, members with write permissions for 'contrib' are usually
well-known and active in the CRUX community.
To enable the 'contrib' collection so that @@ports -u@@ will bring it up to
date, just rename its rsync file.
$ cd /etc/ports
$ mv contrib.rsync.inactive contrib.rsync
You will probably also want to let %fn%prt-get%% know about the newly-enabled
'contrib' tree. This can be done by editing fn%/etc/prt-get.conf%% and
uncommenting the line @@prtdir /usr/ports/contrib@@ (i.e. remove the hashmark in
the beginning of the line. After that, it should look like this:
### prt-get conf
# note: the order matters: the package found first is used
prtdir /usr/ports/core
prtdir /usr/ports/opt
# the following line enables the user maintained contrib collection
prtdir /usr/ports/contrib
Now, run @@ports -u@@ and you're ready to use the ports from %fn%contrib%%.
!!! Enabling the 'compat-32' collection
The 'compat-32' collection contains compatibility ports needed for 32-bit
support (32-bit applications running on a 64-bit multilib system.)
To enable it for %fn%ports%%, do
$ cd /etc/ports
$ mv compat-32.rsync.inactive compat-32.rsync
The 'compat-32' collection is enabled in the same way as the 'contrib'
collection (described previously) for usage with %fn%prt-get%%.
As with 'contrib', run @@ports -u@@ and you're ready to use the ports from
!!! Additional tools
[[#NonRootBuilding]] !!!! Building ports as unprivileged user
Building packages requires root privileges in order to create files with the
correct owner and group. This is a security concern because a malicious or badly
designed port can run arbitrary commands when its Pkgfile is sourced by the
shell. The '''fakeroot''' command provides a way to build ports as normal user.
Particularly when you build packages from user contributed repositories you are
advised to use '''fakeroot''':
$ fakeroot pkgmk -d
* You can also make '''prt-get''' use '''fakeroot''', by modifying the line in
%fn%prt-get.conf%% that contains @@makecommand@@. This line would allow a
non-root user running @@prt-get@@ to create packages with no footprint
mismatches (wrong owner/group), but the installation of these packages (and
the running of pre-/post-install scripts) needs additional privileges.
* Additional lines in %fn%prt-get.conf%%, defining @@addcommand@@ and
@@runscriptcommand@@ with '''sudo''' or '''doas''', is one way to let
@@prt-get@@ work properly for a non-root user.
* Another possibility is to write a '''sudo''' or '''doas''' configuration that
grants permission to run @@prt-get@@ itself, and then as a non-root user you
would always run @@sudo prt-get@@ rather than @@prt-get@@ directly.
* Read the man pages for %fn%prt-get.conf%% and %fn%sudo/doas%% to learn how
these pieces fit together, and choose whichever option you like best. To give
extra scrutiny to ports you find outside the official repositories, it helps to
restrict yourself to low-level commands @@pkgmk@@ and @@pkgadd@@ rather than the
wrapper program @@prt-get@@. This practice forces you to be in the directory of
the unofficial port, where the %fn%Pkgfile%% source array and build function are
more likely to receive your careful attention.
!!!! Useful scripts
Regarding package and ports management there are many tasks which can be done in
several steps with the CRUX standard tools introduced above. The %fn%opt%%
repository contains a port called [[PrtUtils|prt-utils]] with many such scripts.
Other combinations of low-level tools, using UNIX pipes, command substitution,
and text processing utilities, can be found in the bug tracker, the mailing
list, and IRC logs. Efforts are underway to bring this diaspora of institutional
knowledge into a central place, such as the EXAMPLES section of the most
relevant man page.