ZenWalk buildfile tutorial

Version: 0.05
Author : prfaasse
date   : 27-mrt-2006
license: This tutorial is subject to the GPL version 2 or later.
status : request for comment

Update history:

13-feb-2006: file-appending set for the info file
13-feb-2006: converted to html
14-feb-2006: removed some spelling errors, elaborated upon the intermediate build-dir and the makepkg command
15-feb-2006: removed a stupid bug in the example buildfile: <<EOF makes no sense at all; This prevented the separator lines from showing up in the ..-info.txt file
27-mrt-2006: Added a section on building packages in directories other than /usr/src/myApp; Removed some spelling errors.

Summary:

This tutorial contains a description of how to create a buildfile for a ZenWalk package.

Intended audience:

ZenWalk package builders and anyone interested in building or learing about building a ZenWalk-compatible package.

Rationale:

ZenWalk is a SlackWare-derived distribution. ZenWalk, just like SlackWare, is based upon a packaging mechanism for software packages: Each software package is distributed in the form of a small set of files. The minimal set of files for a ZenWalk package is two files:

The .tgz file contains all files used by the ZenWalk package installer(s) to install the software package. The .md5 file contains the md5 checksum of the .tgz file; The .md5 file can be used to verify the correct transmission of the contents of the .tgz file.

Both the .tgz and .md5 files are generated from the package source, using a so-called buildfile. Linux in general and ZenWalk in particular form a dynamic environment. New versions of software are released every day. New versions of ZenWalk are released at more or less regular intervals as well. This implies that software packages for ZenWalk have to be re-built from time to time. It is quite possible to perform the generation of ZenWalk software packages manually, but this is quite error-prone. So much error-prone that for a ZenWalk package the use and distribution of this buildfile is required for a package that is to be included in the ZenWalk Linux distribution.

This tutorial describes what a buildfile does to generate ZenWalk package files and how to prepare one for your own ZenWalk software package.

License:

All ZenWalk buildfiles are subject to the GPL, version 2 or -at your discretion- later versions of the GPL.

The build process:

A buildfile is a bash shell script. The buildfile automates the configuration, compilation and packaging of the source of a software package into a set of files (.tgz and .md5) that form the ZenWalk package. Before going into the buildfile script's internals let me briefly describe the 'standard' build-process of modern Linux software. There are two reasons for this:

  1. A buildfile quite closely follows the same steps
  2. When generating a buildfile for a new ZenWalk software package you'll usually have to perform these steps at least one time 'by hand' to determine the details of what to put in your buildfile. Taking notes when doing this is strongly encouraged :-)

Nowadays, software sources are usually distributed as either pre-compiled (binary) archive files such as the .RPM, .DEB files, as well as in the form of a source-files archive. For the generation of a ZenWalk package we'll usually start from a sources-files archive. These source-files archives are usually distributed in the form of a file with the filename extension .tar.gz or .tar.bz2 . The .gz or .bz2 part of the filename indicates the compression method used for the archive:

The .tar part of the filename indicates that the 'tar' program was used to package the (possibly many) source files into one file. Many, but not all, software is packaged into one single .tar.gz or .tar.bz2 file. Sometimes more than one of these files must be loaded onto your system to get a complete set of sources for some software package.

The usual way to acquire the source-files archive(s) for a software package is to download them from the internet. Each file on the internet can be addressed by means of a so-called url. The url of a file indicates the computer where the file is located, the internet protocol needed to download it and the file on the computer. If you want to make a ZenWalk package for some software package it is important that you keep track of the url's you use to get hold of the source-archive file(s): the url's of the source-archives are a required part of the buildfile for the ZenWalk package.

For the discussion, i'll assume that the source files archive for a software are contained in a single source file archive called myApp.tar.gz . In a more realistic case you would have to substitute the real software package name in the place of myApp.

In the case of a 'manual' build-process the first step of building an executable is to unpack the sources from the source achive file(s). In the case of a .tar.gz file that is done with the command:

  tar xvzf myApp.tar.gz

In the case of a bz2-compressed archive that becomes:

  tar xvjf myApp.tar.bz2

This should result in the decompression and unpacking of the source files into a directory tree. The root of this directory tree is usually called myApp. For the second step of a manual build process, you normally do:

  cd myApp

All modern source packages are provided with a mechanism that can be used to tailor the building of the software to the software environment that it is going to be used on. This mechanism is called the autoconf/automake mechanism. This mechanism is quite clever. For you -as a software packager- this mechanism shows up when an executable (shell-script) file named 'configure' is present in the directory of unpacked source files. The second step of building a software package from sources is usually to run this configure script:

  ./configure

For a package builder, it is often quite instructive to first run:

  ./configure --help

The autoconf/automake mechanism can quite often be 'controlled' by the package builder by passing options to the ./configure command; Running ./configure --help reports which options the configure script supports and what is the expected result of using the option.

Running ./configure (with appropriate options) will make the configure script evaluate the software infrastructure that it's software package is to be built for. This includes the checking if the minimal required infrastructure is preset (aka: if all dependencies are satisfied) and if there is a reasonable chance of generating a working version of the software package for the infrastructure found. If this all is the case, then the ./configure script will generate a Makefile (or lots of Makefiles..) for the software. If this is not the case, then the ./configure script will generate a warning of what it found missing and or lacking. This may well mean that some other software will have to be installed first.

Assuming that the ./configure has finished without warings and/or errors, the next step of building a software package itself is to do the actual compilation of the software by means of the command:

  make

This may very well take quite a while to finish: The software is compiled, linked and generally made ready for use. The previous (./configure) step is supposed to have taken care that the make process can run fault-free, but this is not always the case. All the steps up till now are usually performed within the directory that was created by running the first step (the tar xvzf/zvjf command). These steps can usually be performed without 'root' privileges, and without making any fundamental changes to the system that the steps are being performed on.

The next step however generally does require being run as user 'root': you're about to install the compilation result on your system. This may -in the worst case- completely de-stabilize your entire system; Don't say you where not warned :-) 'Are you sure (Y/N)' is generally not part of a Linux vocabulary; You're implicitly expected to be sure of what you are doing, and when running as 'root' that is even an absolute requirement. So after appropriate preparations, -a short meditation is recommended- running as the almighty 'root' user you should run the command:

  make install

This will copy the result of the 'make' command to the appropriate locations on your system. After this command has finished, the software you meticulously created will be installed on your system and should be ready for use. What you'll have to do to actually run your newly-installed software depends upon what you installed. I can not venture to make any predictions of what you've just installed, so i hope you have an idea what to expect at this point.

It is generally a very good idea to play around with your newly-installed software, to get a feeling if the software is performing according to expectations. I would recommend doing this 'playground stage' as 'normal' user (meaning not as 'root'), but it might well be that your software is something that requires root privilege to be used at all :-) Depending upon what you find, you may have re-run the previous steps to get your software to do what you want.

If the software is really doing what you want you are ready to start working on the real buildfile for a ZenWalk package. I hope you have taken notes -as recommended- because this is where you are really going to need them :-)

Creating a ZenWalk buildfile:

As a first step towards creating a ZenWalk buildfile i strongly recommend that you spend a moment looking at an existing buildfile. The steps performed in the buildfile should be more or less recognizable: they're quite close to the ones described in the previous section. There are some 'extra tricks' in a buildfile, but a buildfile basically does the same as the 'manual' build-process i've described. The main difference is that a buildfile does the configure/make/make-install process as a script, and that it 'tricks' the 'make install' part of the build-process to install -not to the system directories-, but into a separate directory where the set of complete build-results can be packed into the .tgz file of the ZenWalk package. As an example, i'll include the contents of one ZenWalk buildfile here. Note that this is not the 'ultimate truth' of buildfile technology. Other ZenWalk contributors do use slightly -or not so slightly- different buildfiles, but the general drift of them is the same.

Note that in any halfway 'modern' ZenWalk distribution, the buildfiles of software packages end up in subdirectories of the directory /usr/src. You should be able to find an abundance of examples there. For the discussion, i'll use the buildfile for the gambas package. If you have gambas installed on your ZenWalk system you should be able to find something very similar to this buildfile as the file /usr/src/gambas-1.0.14/build-gambas.sh on your system.

If you do not have any ZenWalk system, it may be of interest to know that members of the ZenWalk project team are currently setting up a separate repository dedicated entirely to the buildfiles. By the time you're reading this, it may very well be accessible from the ZenWalk main www-page (www.zenwalk.org).

>>>>>>>>> start of buildfile <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#!/bin/bash
#
# author           : P.R. Faasse (p.faase1@chello.nl)
# maintainer       : P.R. Faasse
# latest update    : 09-feb-2006
# status           : testing
# source location  : http://surfnet.dl.sourceforge.net/sourceforge/gambas/gambas-1.0.14.tar.bz2
# additional files : /usr/lib/libmikmod.la is required for compilation, Qt

#
# what package is going to be built
#
softname='gambas'
softversion='1.0.14'
#
# where could you get the source
#
srcurl="http://surfnet.dl.sourceforge.net/sourceforge/$softname/$softname-$softversion.tar.bz2"
#
# ZenWalk standard: CPU type and architecture, as well as the
# version number of ZenWalk this package is made for (on?).
#
# arch='i486' -> the compiler uses only 80486 instructions
# cpu='i686'  -> the optimising is done for a PII and above CPU
# packageversion='1Z13' means: 
# 1  -> build 1, 
# Z  -> ZenWalk
# 13 -> ZenWalk version 1.3  
#
arch='i486'
cpu='i686'
packageversion='1Z20'
#
# where could you get the source
#
srcurl="http://heanet.dl.sourceforge.net/sourceforge/$softname/$softname-$softversion.tar.bz2"

#
# building-computer dependent: the number of parallel 'jobs' of 'make'
#
# 'heavy' computer: 6 build-jobs at once
#
#numjobs='-j6'
#
# 'light' computer: 2 build-jobs at once
#
numjobs='-j2'

#
# parameters needed for the build process
#
buildir=$(pwd)
package="$softname-$softversion-$arch-$packageversion"

#
# check pre-requisites for the build
#
if [ -d /usr/lib/qt ]; then
   echo "Qt found .. ok"
else
   echo "Qt is needed to compile KDE, please install Qt in /usr/lib/qt first" 
   exit 1 ;
fi

#
# a 'strange' one: i don't know why, but it *is* needed
#
if [ -f /usr/lib/libmikmod.la ]; then
   echo "libmikmod found .. ok"
else
   echo "libmikmod is needed to compile gambas, please install libmikmod in /usr/lib first"
   exit 1 ;
fi
#
# do package-specific settings 
#

#
# prepare the build result directory
#
dest="$buildir/$package"
prefix=/usr
#
rm -rf $dest
#
mkdir -p $dest
mkdir -p $dest/install
mkdir -p $dest/$prefix/$softname
mkdir -p $dest/$prefix/bin
#
# These two are always needed: 
# applications for the $softname.desktop file, 
# icons for the application icon $softname.png
#
mkdir -p $dest/usr/share/applications
mkdir -p $dest/usr/share/icons
mkdir -p $dest/usr/doc
#
#
# prepare the directory for the build-file and assorted other 
# user-build related things
#
destsrc="$dest/usr/src/$softname-$softversion"
mkdir -p $destsrc
#
# make a slack-desc file
#
cat <<EOF > $dest/install/slack-desc
         |-----handy-ruler------------------------------------------------------|
$softname: $softname ($softversion)
$softname:
$softname: Gambas Almost Means BASic: an advanced integrated development 
$softname: environment for the BASIC language.
$softname: 
$softname: see also: http://gambas.sourceforge.net/
$softname: 
$softname:
$softname: 
$softname:
$softname: Compiled for $packageversion
EOF

#
# generate the desktop file, see below for the icon file
#
cat <<"EOF" >$dest/usr/share/applications/$softname.desktop
[Desktop Entry]
Name=Gambas
Comment=Integrated Basic Development Environment
Exec=gambas
Icon=gambas.png
Terminal=false
X-MultipleArgs=false
Type=Application
Categories=Application;Development;
Encoding=UTF-8
StartupNotify=true
EOF

#
# loop over expanded package source files
#
cd $buildir
for file in \
$softname-$softversion.tar.* \
; do
  ( 
  if [ "$(echo $file | grep ".tar.bz2" )" ]; then
      srcdir="$(basename $file .tar.bz2)" 
      rm -rf $srcdir
      tar jxvf $file
      cd $srcdir  
  elif [ "$(echo $file | grep ".tar.gz" )" ]; then
      srcdir="$(basename $file .tar.gz)" 
      rm -rf $srcdir
      tar zxvf $file
      cd $srcdir   
  fi

#
# make the package-dependent directories
#
    mkdir -p $dest/usr/doc/$srcdir
#
# set target permissions
#
    chown -R root.root . 
    find . -perm 777 -exec chmod 755 {} \;
    find . -perm 775 -exec chmod 755 {} \;
    find . -perm 666 -exec chmod 644 {} \;
    find . -perm 664 -exec chmod 644 {} \;

#
# prepare the build-log-file
#
    touch "$buildir/$softname-info.txt"
    
#
#
# configure package for compilation
#
	 cat <<"EOF" >>"$buildir/$softname-info.txt"
-- configure -----
EOF

    export CFLAGS="-O2 -march=$arch -mtune=$cpu"  
    export CXXFLAGS="-O2 -march=$arch -mtune=$cpu"  
    ./configure \
      --prefix=$prefix \
      --localstatedir=/var \
      --mandir=/usr/man \
      --sysconfdir=/etc \
      --disable-debug \
      2>&1 | tee -a "$buildir/$softname-info.txt"
#
# make package
#
	 cat <<"EOF" >>"$buildir/$softname-info.txt"
-- make -----
EOF

    make $numjobs \
      2>&1 | tee -a "$buildir/$softname-info.txt"
#
# install package to the target directory
#
	 cat <<"EOF" >>"$buildir/$softname-info.txt"
-- make install -----
EOF

    make install DESTDIR=$dest \
      2>&1 | tee -a "$buildir/$softname-info.txt"    
#
# do a normal install too, mostly needed for multiple and dependent packages
#    
#    make install
#
# add 'default' files
#
    cp -a \
      AUTHORS COPYING INSTALL NEWS README TODO \
      $dest/usr/doc/$srcdir 
#
# copy the icon file from the gambas source tree
#
    cp  $buildir/$srcdir/app/gambas/.icon/48.png $dest/usr/share/icons/$softname.png
#
# gambas requires libtool, for it's libraries
#
    cat <>$dest/install/doinst.sh
libtool --finish /$prefix/$softname/lib/$softname
EOF
# 
# as per package rules: add the build-file itself
#
    cp "$buildir/build-$softname.sh" \
       "$destsrc/build-$softname.sh"
    chmod a+x "$destsrc/build-$softname.sh"
#
# generate an executable script that can be used to get the source
#
    cat < "$destsrc/getsrc.sh"
# 
# get the source(s) script
#
wget -c $srcurl
EOF
    chmod a+x "$destsrc/getsrc.sh"

#
#
# post-build processing: 
# - strip executables 
# - compress man-pages
#
    ( cd $dest
      find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | \
                   xargs strip --strip-unneeded 2> /dev/null
      find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | \
                   xargs strip --strip-unneeded 2> /dev/null
      for mandir in $(find . -name man -type d) ; do
        if [ -d $mandir ]; then
          ( cd $mandir
            find . -type f -name "*.?" -exec gzip -9 {} \;
          )
        fi
      done
    )
  )
  
done
#
# real packaging work: 
#
chown -R root.bin $dest/usr/bin
chown -R root.bin $dest/$prefix/$softname
#
cd $dest
makepkg -l y -c n $dest.tgz
md5sum $dest.tgz >$dest.md5

>>>>>>>>> end   of buildfile <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Now, let's 'walk through' this build-file, and see how it relates to the previous section:

The first 'comment' line:

  #!/bin/bash

assures that /bin/bash will be used to 'execute' this script. The #! as first characters of the comment line is a 'well-known' trick to make unix run the file using the specified interpreter.

The rest of the comment block indicates what will be built, and indicates which other packages must be installed to be able to use the package results.

The next part: a number of parameter settings. This may be my personal style, but i like being able to configure the build-process by means of a number of settings that appear at the beginning of the buildfile. The reason for this is that this enables me to easily modify the buildfile for new-newer-latest versions of the source, and even re-use a buildfile to generate one for a not yet packaged application.

The softname and softversion are the name and the version number of the source files package. They are usually also used as part of the name and version number of the ZenWalk package.

The srcurl is the the url where the source files package has been downloaded from.

The arch and cpu vars are -for ZenWalk- fixed at i486 and i686 respectively. The i486 means that the package requires an 80486 minimally to run, and the i686 means that the compiler optimises the executable(s) for an Pentium II and above CPU. There are 'exceptions based upon reasonable grounds' for using these settings: some multimedia applications run really bad when they are not making use of the full features set of the processor. In those cases, using arch=i686 is accepted.

The packageversion is an indicator of which build version and for which version of ZenWalk the package is made. The first digit is 0 or 1..9, meaning:

The numjobs is used during the make process: it sets the number of jobs that make is allowed to use when compiling. On a 'heavy-metal' machine you can use lots of jobs, on my rather modest machine, compiling two files at the same time about fills up the machine's RAM, so i usually restrict this to 2 jobs at once. The make process will not get faster when my machine is forced to swap :-)

The buildir is set to the directory where the package creation is started.

The package var is set to the basename of the package. This is the same name as the name of the (final) result: the .tgz file and the .md5 file.

After these 'configuration settings', the real build-script starts: I do some 'manual' dependencies checking: For the package we're building her, the Qt and libmikmod is required. The configure part *will* find out, but in this case i prefer to do the check myself (and less reliably than configure would...), and generate a more usable (for me that is..) error message.

The dest var is set to the directory where the intermediate install (see about that later) will be done.

The prefix var is set to /usr: All ZenWalk packages are by default installed in /usr.

The intermediate install directory is removed to ensure that only the files from this build can end up there. This prevents that possible remains of previous (differently configured?) package generations are also packaged into the .tgz file.

Next, a lot of directories are made: This comes down to preparing the $dest directory tree for use.

Next, the destsrc is set, and it's directory made. This is a preparatio for something that will be used later on in the buildfile.

A file named slack-desc is made by means of a so-called here-document: Everything from the 'cat' line till line that only contains the text EOF will be copied into the $dest/install/slack-desc file. This is a handy trick to incorporate text-file data into the buildscript. From the use of things like $softname etc. in the text of the so-called 'here-document' you will no doubt have concluded that these are expanded in the actual $dest/install/slack-desc file.

The actual text in the slack-desc file is the text that will be displayed whe the package is installed. The text indicated is quite traditional. One thing to notice is that this text is to be exactly 11 lines long, and has to 'fit' within the 'handy ruler'. Should your package ever make it to the actual ZenWalk iso, then this is particularly important: if the text does not fit, the ascii-graphical install screen of the ZenWalk install would be 'messed up'.

The next section of the build-file generates a so-called 'desktop' file for the Gambas package we're making a package for: this is a file that ensures that the Gambas development environment will properly show up in the menu's of the X11 desktop manager (xfce or kde...). Note: putting the "EOF" instead of 'plain' EOF means that bash does a literal copy of the her-document text, no variable expansion or computations are performed...

The 'for' part of the buildfile is the beginning of a loop: The loop iterates over all entries in the list that -for this package- consists of only '$softname-$softversion.tar.*' (alias gambas-1.0.14.tar.* which is expanded to gambas-1.0.14.tar.bz2...). This is provision for the case where one package is built from more than one source file. In the current (and most..) situations the loop is run only once, which does no harm at all :-)

The if..elif..fi section does three things:

  1. it expands the source archive using the correct expansion command for eiter .gz ot .bz2 archives
  2. it sets the variable srcdir to the directory where the expanded and unpacked results are.
  3. before unpacking, it clears the target directory

Next the documentation directory is created, and the permissions of the source-files are set.

A build-info.txt file is created: it will be used to accumulate all status and error messages that are generated during the package creation process. A Header line in the is written to it.

From here on the buildfile should start to resemble the 'manual build' that was described before: The basic compiler flags are set and then (finally?) the ./configure is started with appropriate options. Most of these are defined only for the configure script that comes with the source archive (configure --help...), but --prefix=$prefix is one that is common for all ZenWalk packages. This option is very common for configure scripts as well. The configure command is split over multiple lines using the trailing \, and all output and errors (2>&1) is sent to both the screen and to the info.txt file.

After another separator line in the info.txt file, the make process is started, immediately followed by another separator command and the make install. The make install is passed a 'special': DESTDIR=$dest. This instructs the make install to perform the install, but not in the system directories, but in a set of directories that are prefixed with the contents of the $dest variable. This is -in a way- the core of the ZenWalk (and Slackware) package creation: compile the sources, and install in a 'well-defined' directory: It is quite hard to find out where all parts of a package will end up in the system directories, but when they are installed in a separate directory tree, they -all of a sudden- become quite easy to find. This is the intermediate install directory i mentioned earlier in the description. The idea is to tar-gzip the contents of the internediate install directory, so that it will be copied into the system directories when the resulting tgz file is extracted.

The intermediate install directory is in fact a directory tree 'image' of what the package installer will produce on the target computer. This means that if you want -for instance- to make the installer put a file with name /usr/local/myFile on the target computer, you will have to generate -using the buildfile- a file $dest/usr/local/myFile. There are two 'special' files that are generated in this intermediate install directory: The '$dest/install/slack-desc' file we saw before, and the '$dest/install/doinstall.sh' file. The slack-desc file is displayed when the package is installed. It is meant to give the user of your package some feedback of what is being installed. The same file is displayed for each package when a ZenWalk install CD is installing packages. The doinstall.sh file is run as a shell-script by the package installer (on the target computer) after it has extracted what you have put in the intermediate install directory and written the files of the package to the target computer. Note that the entire /install directory is removed by the package installer after it has served it's purpose. I am not quite sure what will happen if an unwarned sysadmin of a target computer decides to use the /install directory as a 'standard' directory of the target system; It may very well be that the package installer blissfully destroys it at each package install.

From here on, the package creation becomes non-manual-equivalent again: Some files from the source archive are copied into the same directory where the make install

At this point i complete the desktop information for gambas by copying one of the icons from the source archive to the place where the desktop file expects to find it.

During my 'manual build' the Gambas build process warned me that i'd have to run libtool with some options to make sure that the gambas libraries are found. I converted that command and here i append it to a file named doinstall.sh in the intermediate install directory's install subdir. This file is one that will be executed by the package installer at each install of the resulting package.

The ZenWalk package rules decree that the buildfile itself is made part of the package. This ensures that everyone who has a package, also has the means to (re-)create the package. If you 'look through' the shell-variables, you will see that i copy the build-gambas.sh file to $dest/usr/src/gambas-1.0.14/build-gambas.sh . This means that it will end up at /usr/src/gambas-1.0.14/build-gambas.sh . That is the standard ZenWalk location for buildfiles. A if you are running a recent ZenWalk version (2.0.1 and up..) a quick look in /usr/src should result in a lot of subdirs, with each (minimally) a buildfile for a package...

I generate one extra file in the $dest/usr/src/gambas-1.0.14 directory: getsrc.sh . This is a file that can be used to download the sources of the package. This means that the $dest/usr/src/gambas-1.0.14 directory is quite ready for being used to re-generate the gambas package: this buildfile and a command file to get the source archive should be enough to build a new gambas package.

I recently stopped (re-)building packages in the /usr/src/myApp directory itself. The reason for this is what i see as a nasty trick of the removepkg shell-script. removepkg is what i use to de-install a package. It is the counterpart of installpkg, which installs a package. removepkg removes all files that where installed from a package's tgz file. This includes the buildfile in /usr/src/myApp/ . When attempting to rebuild a package i have twice fallen into the trap of:

Building in a directory other than /usr/src/myApp prevents this scenario.

Next, some of the result-files are post-processed:

As we're nearing the end of the buildfile, the ownership of all files in the intermediate install directory is set.

Finally, the intermediate install directory is processed by a SlackWare script that converts the directory contents to a SlackWare package. That is also the format of ZenWalk packages :-) This script generates -in one easy go- the .tgz file that is one of the two files of a ZenWalk package. The makepkg script does support a few options, have a look at the result of running 'makepkg --help' for a short explanation.

One thing worth knowing about the makepkg script is that it converts all symbolic links in the intermediate install directory. These symlinks are correct should you wish to run your package from the intermediate install directory, but they will be patently wrong on the target computer. The makepkg script 'solves' this by removing all symbolic links in the intermediate install directory. For each symlink it removes, it generates a line in the doinstall.sh script that generates a correct symlink on the target computer. If you give the makepkg script the option '-p' it will put these symlink-generation commands before the text it finds in the doinstall.sh file when the script is run, without the '-p' option it will append these symlink-creating commands to the existing doinstall.sh text.

It is perhaps a bit of an anticlimax to see that the .md5 file that is the second part of a ZenWalk package is generated by simply running the md5sum program on the .tgz file, but that is life...

The two files: gambas-1.0.14-i486-1Z20.tgz and gambas-1.0.14-i486-1Z20.md5 form the ZenWalk package for gambas.

Rantings and Ravings:

Remains to say that the gambas buildfile of this example is one of my style. Others package-makers on the ZenWalk project have their own style of buildfiles. They will -no doubt- be different from mine. I cannot venture to judge which style fits you personal style best. If in any doubt, have a look at some of them and copy the one that fits yours best. The details may be different, but the general drift should be the same: generate a directory tree with the package's compile results, and package that using the SlackWare 'makepkg' script. Now that you know that they are supposed to be in the /usr/src directory of a ZenWalk install, you should be able to find plenty examples...