One of the most trivial and simple skel of hello world program can be made with the following skel in skel/hw.do:
[ -n "$BASS_ROOT" ] || BASS_ROOT="$(dirname "$(realpath -- "$0")")"/../../.. sname=$1.do . "$BASS_ROOT"/lib/rc . "$BASS_ROOT"/build/skel/common.rc mkdir -p "$SKELBINS"/$ARCH/$NAME/bin cd "$SKELBINS"/$ARCH cp ~/src/misc/hw/hw.pl $NAME/bin "$BASS_ROOT"/build/lib/mk-pkg $NAME
But let’s write a skel and build a skelpkg for convenient GNU parallel utility.
$BASS_RC
environment variable with
the path to it:
$ cd build/ $ cat >rc <<EOF MAKE_JOBS=8 SKELBINS=/tmp/skelbins EOF $ export BASS_RC=`realpath rc`
You can look for variables you can set in lib/rc. One of the most
important variable is $ARCH
, which sets what architecture you are
using. If you have got non-Git capable checkout, then probably you
should also set $BASS_REV
to some dummy string. When it is changed
– your skelbin’s hashes too. $SKELBINS
path is crucial to be the
same as it will be on the slaves.
According to parallel
’s homepage, it is advised to use GNU
mirrors for downloading, so let’s take its latest release with the
signature:
$ wget https://ftpmirror.gnu.org/parallel/parallel-20240122.tar.bz2 $ wget https://ftpmirror.gnu.org/parallel/parallel-20240122.tar.bz2.sig
Its .sig file contains non-signature related commentary, that we should strip off:
$ perl -i -ne 'print if /BEGIN/../END/' parallel-20240122.tar.bz2.sig
Many software provides signatures in binary format, that could be easily
converted with gpg --enarmor <....sig >....asc
.
Then we must create corresponding Metalink4 file, which includes
signature, URL(s) and checksums. I will use
meta4ra-create
utility for that purpose:
$ meta4ra-create \ -fn parallel-20240122.tar.bz2 \ -sig-pgp parallel-20240122.tar.bz2.sig \ https://ftpmirror.gnu.org/parallel/parallel-20240122.tar.bz2 \ <parallel-20240122.tar.bz2 >parallel-20240122.tar.bz2.meta4
[ -n "$BASS_ROOT" ] || BASS_ROOT="$(dirname "$(realpath -- "$0")")"/../../../.. sname=$1.do . "$BASS_ROOT"/lib/rc . "$BASS_ROOT"/build/skel/common.rc bdeps="rc-paths stow archivers/zstd devel/gmake-4.4.1" rdeps="lang/perl-5.32.1" redo-ifchange $bdeps "$DISTFILES"/$name.tar.bz2 $rdeps hsh=$("$BASS_ROOT"/build/bin/cksum $BASS_REV $spath) . "$BASS_ROOT"/build/lib/create-tmp-for-build.rc "$BASS_ROOT"/build/bin/pkg-inst $bdeps $rdeps . ./rc $TAR xf "$DISTFILES"/$name.tar.bz2 "$BASS_ROOT"/bin/rm-r "$SKELBINS"/$ARCH/$NAME-$hsh cd $NAME ./configure --prefix="$SKELBINS"/$ARCH/$NAME-$hsh --disable-documentation >&2 perl -i -ne 'print unless /^\s+citation_notice..;$/' src/parallel gmake -j$MAKE_JOBS >&2 gmake install >&2 cd "$SKELBINS"/$ARCH "$LIB"/prepare-preinst-010-rdeps $NAME-$hsh $rdeps mkdir -p $NAME-$hsh/skelpkg/$NAME-$hsh/hooks/postinst cat >$NAME-$hsh/skelpkg/$NAME-$hsh/hooks/postinst/01will-cite <<EOF #!/bin/sh echo yeah, yeah, will cite >&2 EOF chmod +x $NAME-$hsh/skelpkg/$NAME-$hsh/hooks/postinst/01will-cite "$BASS_ROOT"/build/lib/mk-pkg $NAME-$hsh
$ARCH
directory and link all missing skels to it:
$ pkg/mk-arch
$ redo pkg/FreeBSD-amd64-13.2-RELEASE/sysutils/parallel-20240122
% tar xfO pkg/FreeBSD-amd64-13.2-RELEASE/sysutils/parallel-20240122 bin | tar tf - parallel-20240122-xhVYojyMWD8XeHTuTe44q1NyHI2b_l5fKsopunYFzkc/ parallel-20240122-xhVYojyMWD8XeHTuTe44q1NyHI2b_l5fKsopunYFzkc/bin/ parallel-20240122-xhVYojyMWD8XeHTuTe44q1NyHI2b_l5fKsopunYFzkc/bin/env_parallel parallel-20240122-xhVYojyMWD8XeHTuTe44q1NyHI2b_l5fKsopunYFzkc/bin/[...] parallel-20240122-xhVYojyMWD8XeHTuTe44q1NyHI2b_l5fKsopunYFzkc/bin/parallel
Let’s describe what is happening in the skel:
redo
implementations it will be started with
the /bin/sh -e
command. So it is POSIX shell script file.
But you are free to use any interpreted language or even build and
even compile .do file itself with another .do.
$BASS_ROOT
(path to the root directory of the BASS project
(build/, master/, slave/)) and $BASS_RC
,
which was already set by you before. $BASS_ROOT
generally is
set by invoking script itself, considering its own path in BASS’es
hierarchy.
Line with $BASS_ROOT
setting just can be copy-pasted among all
skels.
$SKELPKGS
, so it can depend on subdir/pkg
packages.
$sname
variable with
current scripts name.
It will check if $BASS_RC
is specified and set:
$NAME
Base name of the script/skel, without .do extension.
$SPATH
Full path to the invoking script itself.
$ARCH
Current machine’s architecture, what it builds for.
$SKELBINS
Path to directory with unpacked skelbins.
$SKELPKGS
Path to directory containing built $ARCH/$SKELPKG skelpkgs.
$MAKE_JOBS
Number of Make’s parallel jobs. Cane be passed to make
.
$DISTFILES
Path to $BASS_ROOT/build/distfiles directory.
$BASS_REV
Current BASS’es source code revision.
$SETLOCK, $META4RA_HASHES, $FSYNC, $TAR, $TMPDIR
And of course they could be overridden in most cases with your
$BASS_RC
.
$bdeps
and $rdeps
are just a convenient variables not to
repeat them multiple in the whole script. parallel
requires Perl during build and runtime. I called it "runtime
dependency". Actually it builds perfectly with POSIX/BSD
make
, but as an exercise we assume that it builds only
with GNU make, so we also remember that is is "build dependency".
Nearly every skel requires rc-paths
(see below), stow
and zstd
skelpkgs.
stow
skelpkg is very special: it can be build without
invoking GNU Make and dependant Perl. It also can be installed by
pkg-inst
even if no Stow is installed: it will stow self
in postinst
hook. Also, it installs perl
skelpkg only
if it exists, so that way it works on a clean build system.
zstd
skelpkg makes zstd*
compressor available, when
invoking mk-pkg
command to create the resulting skelpkg.
Only a few skelpkgs use gzip
compressor.
redo-ifchange
to assure that our distfile
exists (otherwise it will be downloaded), as dependency packages
too. Remember that redo
guarantees that it will run script
in the directory it lives? So here are dependent packages too. If
any of them does not exist, then redo
will invoke its
building the same way as we invoked building of the
parallel
skelpkg. It also assures that rc-paths
,
stow
and zstd
skelpkgs exist too.
cksum
will hash all that information.
$tmp
)
$BASS_ROOT/build/bin/pkg-inst
command.
Pay attention that initially it installs stow
skelpkg, that
is required virtually by any other skelpkg for working properly. So
the order of skels is very important there.
postinst
hooks. rc-paths
skelpkg
is used solely for its side-effect of postinst
hook, that
creates that rc file with altered
$PATH
,
$MANPATH
,
$INFOPATH
,
$LD_LIBRARY_PATH
,
$CFLAGS
,
$CXXFLAGS
,
$LDFLAGS
variables, making them aware of local/ hierarchy.
When we install pkgconf
skelpkg, then it appends altering
of $PKG_CONFIG_PATH
variable in its postinst
hook too.
Now we are aware of various installed packages and specific environment variables.
$TAR
to current temporary
directory.
$BASS_REV
and corresponding
$hsh
value. So each time your new skelbin build should be in
different directory. But when you are developing your skel, no
commits and hashes are changed. Moreover your previous build attempt
may fail due to I/O or system error.
Because of redo
’s lockfiles it should be safe to remove
existing skelbin, because noone must be using it.
Why not trivial rm -fr
? Because skelbins are forced to be
read-only directories, that is why you just won’t have enough
permissions to remove them. $BASS_ROOT/bin/rm-r
deals with it.
configure
the program at
last! Pay attention to proper installation to immutable/permanent
path under $SKELBINS/$ARCH/$NAME-$hsh
.
Remember that any output to stdout is saved by redo
as a
result of the target! So do not forget to redirect messages to
stderr or silence them at all.
gmake
to build it up. Because gmake
skelpkg
is installed, that command will be available under that name even on
GNU systems. Use $MAKE_JOBS
if it is appropriate and safe to
be used. Aware that many programs can not be built in parallel build
mode.
parallel
requires Perl at runtime, we need to assure it
is installed when our skelpkg is going to be installed. Create a
preinst
hook for that purpose, that will
call pkg-inst
command.
Because runtime dependencies are often used hooks, there is
prepare-preinst-010-rdeps
for that. Its arguments will be
converted to corresponding
skelpkg/$namenhash/hooks/preinst/010-rdeps executable file.
postinst
hook, that
will print our promise that we will cite that GNU Parallel. Just an
ordinary 01will-cite script. After parallel-20240122
skelpkg installation, you will see that promise message.
$BASS_ROOT/build/lib/mk-pkg
takes a name of the directory you need to pack in skelpkg. It will
automatically include necessary name and buildinfo
files with corresponding .meta4 files.
mk-pkg
outputs skelpkg to the stdout, that is not
explicitly captured in that redo
target, passing it
through to the redo
itself, making it the resulting
skelpkg.