logoHow to make packages for Fatdog64

Making a package for Fatdog64 consist of 3 (three) steps.

  1. Building the binaries.
  2. Collecting the files that will (or would) be installed.
  3. Combining all of these files into a package file.

Step 1 - Building the binaries

You first need to download the source code that you want to compile, and read any README or INSTALL text files for information on how to compile.

Typically it looks like this for autoconf-based build system:

./configure --prefix=/usr --libdir=/usr/lib64 --sysconfdir=/etc --localstatedir=/var

Or for cmake build system:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=/usr/lib64
In both systems, the usual next step usually mentioned in package's README is "make install" (or "sudo make install") but don't do it yet. Doing this will immediately install the application to your system, but does not package it in a format that you can re-use later (e.g. installing it in another machine).

Instead, what you want is to collect the files that would be installed, and turn these loose files into a package. This is step 2.

Step 2 - Collecting install files

There are a few ways of doing so.
  1. Traditional autoconf method, using make install DESTDIR=/tmp/xxx
  2. Traditional Puppy method, using new2dir
  3. Using paco -lp and paco2pkg
  4. Using Fatdog sandbox
  5. Using Fatdog native pkgbuild system

The FAQ will only discuss the first three; the last two will only be discussed briefly. Since there are so many options and it can confusing, this is explained last. For now, assuming you have collected the files, it is a simple matter to turn in them into a package in step 3.

Step 3 - Making a package out of loose files

Let's say you have already collected all the files, with the correct hierachy, in a directory called "/tmp/xxx" (using one of the methods in step 2). That is, your new application "abiword" binary has been placed in "/tmp/xxx/usr/bin/abiword", its desktop menu file is located in "/tmp/xxx/usr/share/applications/abiword.desktop", its icon in "/tmp/xxx/usr/share/pixmaps/abiword.png", etc.

Then to make the package, all you need to do is run makepkg like this:
cd /tmp/xxx
makepkg -c n -l n /path/to/where/you/want/to/keep/the/package-version-x86_64-num.txz
The filename package-version-x86_64-1.txz is a standard that you need to follow; it comprises of 4 components all separated by the "-" (dash, minus) character.
An example of a valid package name is "abiword-3.0.0-x86_64-1.txz." Another valid example is: "abiword-docs-3.0.0-noarch-1.txz".
You can actually use "tbz" and "tgz" too (the package will be compressed with bzip2 and gzip respectively, instead of "xz"), but there is little incentives of doing so in modern days.

That's it! After packaging is completed, you have your package.

If you want to get a little fancy, you can add "descriptions" to your package. You can also add an install and uninstall script (like "pinstall.sh" / "puninstall.sh" for those familiar with PET packages) - both scripts are optional. An install script can be added as follows, do this before you run makepkg.
cd /tmp/xxx
mkdir install
slackdesc "package" "version" "short summary" "long description" "source URL" | tee install/slack-desc
cp /your/prepared/install-script install/doinst.sh
cp /your/prepared/un-install-script install/slack-uninstall.sh
makepkg -c n -l n /path/to/where/you/want/to/keep/the/package-version-x86_64-num.txz
1. Note for slackdesc: "package" must match the package name you used in makepkg, exactly (sans the other 3 components); "version" must match the version you use in makepkg exactly. All other components are optional.

2. Note for doinst.sh: this script is identical to pinstall.sh; if you have an existing pinstall.sh you can use it right away. Note that this script is run in the installation directory (which isn't always root "/"), so you must always refer directories by their relative names, e.g. use "./usr/share/applications" (note the dot at the beginning) instead of "/usr/share/applications". This is actually required for pinstall.sh scripts in PET packages too.

3. Note for uninstall script: Standard Slackware packages don't support an uninstall script, but Fatdog packages do. The name of the script is slack-uninstall.sh, located in the same location as doinst.sh. It has the same requirements as doinst.sh above - you must refer directories by their relative names (puninstall.sh in PET packages has the same stipulation too).

4. Note for smaller packages: It is a good idea to strip all of the binaries and any libraries to make them smaller. Sometimes this is already done by the build system, but most of the time it isn't. To do this, you cd to the directory that contains any binaries or libraries (*.so files) and run:
strip --strip-unneeded *
before you run makepkg. Afterwards, you can also delete any thing else that is not needed (e.g. locale directories if you're going for English-only package, templates, documentations, etc). makepkg does not automatically create DEV or NLS package like dir2pet, it will just make a tarball of the entire contents of the directory it is in.

Step 2 Revisited - Collecting install files

To recap, there are a few ways of doing so:
  1. Traditional autoconf method, using make install DESTDIR=/tmp/xxx
  2. Traditional Puppy method, using new2dir
  3. Using paco -lp and paco2pkg
  4. Using Fatdog sandbox
  5. Using Fatdog native pkgbuild system

Method 1 - Using "make install" with DESTDIR

This is a method which is usually supported by many applications that are configured using GNU autoconf and cmake build system.

Instead of running "make install", you run "make install DESTDIR=/tmp/xxx".

Adding "DESTDIR=/tmp/xxx" to "make install" simply tells the build system to install the files with its correct hierachy to "/tmp/xxx" location instead of the usual root "/" location. Thus, for example, a file that will usually be installed to "/usr/bin/myprogram" will instead be installed to "/tmp/xxx/usr/bin/myprogram".

The end result - all the program installed files will be collected under "/tmp/xxx".

When "make install DESTDIR=/tmp/xxx" finishes you're ready for step 3 above.

This is a popular method to collect installed files. The downside of this approach is that not all packages supports the DESTDIR method, and some that claim they do, sometimes behave weirdly if you install them using DESTDIR.

Method 2 - Using new2dir

This is the traditional Puppy method to collect files to be installed: use new2dir make install instead of just "make install". Once you have run this, two things will happen:
  1. The program will be installed as usual
  2. The files that are installed are also copied to a directory usually called ../<app name>-x86_64.
After new2dir has finished, you can cd to that <appname>-x86_64 directory and continue with step 3.

This method has the benefit that it will work with larger number of applications; and it will not have the oddities that DESTDIR sometimes does. But this method is not fool-proof - some installed files may not be captured correctly by new2dir. This is rare, but usually happens for e.g. python programs.

This method has the disadvantage that the program you are trying to package is actually installed to your system.

Method 3 - Using paco -lp and paco2pkg

paco is program to perform installation file capture, just like new2dir. (The website for paco used to be here, but unfortunately when the author of paco deprecated paco in favour of a new program called "porg" that is identical in purpose to paco, he also took down the website. With very minor changes, however, information for porg is also applicable for paco).

To use paco, you run "paco -lp package-version -- make install" instead of just "make install".

After paco finishes, the package will be installed as normal but paco will keep a record of what files have been installed. The next step is to ensure you have a directory called "/archive/repo" as the output of the package will be stored there; then you just need to run "paco2pkg package-version" which will create the "/archive/repo/package-version-x86_64-1paco.txz" - ready for use.

Using paco has the benefit that it works with even more packages (even for programs where new2dir traditionally fails), and even though you still have to install the program when you try to package it, paco has the ability to uninstall the package that it installed during packaging method (use "paco -r package-version" command). Of course, uninstall this after you create the package, not before.

paco is a very versatile tool. It has a lot more features that what can be covered here. For example, it can create pacoballs (using the pacoball command) which is a complete package on its own; these pacoballs can be installed or uninstalled on demand. Paco can actually function as a full-fledged package manager by itself.

Note: Using this method, it isn't obvious how you can add the equivalent of slack-desc and doinst.sh script, as the packaging is done by paco2pkg instead of makepkg; but it can be done. Run "paco2pkg --help" for more details. This method is meant for batch creation of packages; where the doinst.sh and slack-desc files for multiple packages are pre-created in advance.

Method 4 overview - Using Fatdog sandbox

The idea is to build the packages inside Fatdog sandbox, and the install as usual (with "make install"). All the installed files (new or modified files) will be kept in the sandbox, after which you can use "sb2dir.sh" to extract them to the /tmp directory. From within this extraction directory, you can run "makepkg" as usual. Obviously you need to remove unneeded files first (the source tarball, etc).

When you're done, just leave the sandbox - and your base system is unchanged.

Method 5 overview - Using Fatdog native pkgbuild system

Fatdog's pkgbuild system expands on the idea of Fatdog sandbox above, to build and capture installed packages, and doing it automatically. This is called "native" as all Fatdog base packages are built using this system.

The system is "recipe" driven, you need to give the pkgbuild system a "recipe" - an set of instructions of how to build the package. A "recipe" is actually a shell script containing the commands that you usually use to build a package, e.g. the "configure" and "make" and "make install"; it also include commands where to download the source tarball.

The build system will execute the recipe (building the package as it goes), and automatically collect the files, strip them, and package the result into a nice Fatdog package at the end of it. Package description (slack-desc) and install script (doinst.sh) are packaged together if they are defined inside the recipe. As a bonus, the recipe itself is also included in the resulting package so you always know how to rebuild the package again, in exactly the same manner, in the future.

Fatdog pkgbuild system is located in /usr/src/pkgbuild (when Fatdog devx is loaded). It comes with samples. Put your own recipe in "pkg" directory. Finished package will be stored in "output" directory. "src" directory will contain the downloaded source tarball.

The "source" directory contains the recipes used to create installed Fatdog packages.

Final Note: Fatdog64 600 and earlier use PET package format, the same format used by Puppy Linux. To make pet packages, the steps are all the same, except that instead of "makepkg" you use "dir2pet". Fatdog64 700 switches to TXZ packages, and dir2pet is no longer supported, although you can still convert existing PET packages to TXZ using "pet2txz" command.