%%textdomain fatdoghelp
![Fatdog](fatdog64.png)

# How to make packages for Fatdog64

## Opening Note

Fatdog64 600 and earlier used the PET package format, the same format used by Puppy Linux.

To make PET packages for Puppy Linux, use the steps described below, but replace "makepkg" with "dir2pet", "doinst.sh" with "pinstall.sh", and "slack-uninstall.sh" with "puninstall.sh").

Fatdog64 700 switched to the TXZ package format, and dir2pet is no longer supported. You can convert existing PET packages to TXZ using the "pet2txz" command.

## Making a package

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

Building the binaries.

Collecting the files that will (or would) be installed.

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 an autoconf-based build system:
		./configure --prefix=/usr \
		--libdir=/usr/lib64 \
		--sysconfdir=/etc \
		--localstatedir=/var
		make

Or for the cmake build system:
		mkdir build &;&; cd build
		cmake .. -DCMAKE_INSTALL_PREFIX=/usr \
		-DLIBDIR=/usr/lib64
		make

In both systems, the typical next step usually mentioned in a 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. to install 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

This 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 will be explained last (see step 2 below).
For now, assuming you have collected the files, it is a simple matter to turn 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 is comprised of 4 components, all separated by a "-" (dash, minus) character.

- *package* can be anything, e.g. *abiword*. This is the name of the package. The package name can have "-" in it as long as the rest of the components are given correctly.

- *version* must be something that starts with a number, e.g. *3.0.0* or *2.8.6patched* or simply *2014.09git*. This identifies the version of the package.

- *x86_64* is the architecture name. For Fatdog64 it must be x86_64.$ For FatdogArm, it would be *armhf* for hardfloat binaries, *armel* for softfloat binaries, and *armeb* for big-endian ARM systems (rare). For 32-bit binaries, you have the choice of *i386**, i486, i586, i686, *or *x86* depending which flavour of x86 you compiled the package for. If the package is non-architecture specific (e.g. shell or Perl scripts, which will work equally well in 32-bit/64-bit/ARM etc), use *noarch*.

- *num* is the build number. It is usually "1", but it can be "2", or "700", or "PET", or anything really. It identifies the build number. An identical package can otherwise be shown multiple times (because the first build is buggy, the second build you forgot to put in the desktop file, the 3rd build is good, the 4th build is only for Chromebooks, etc). In Fatdog64 800 official packages the build number is usually "1", but it will be updated as time passes.

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 incentive to do so in modern days.

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

---

If you want to get a little fancy, you can add "descriptions" to your package.

You can also add optional install and uninstall scripts ( "*doinst.sh*" and "*slack-uninstall.sh*" for those familiar with TXZ packages).
Either 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/uninstall/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" and "version" must match the package name and version you used in makepkg, exactly.  The other two naming components are not used here.

All other components are optional.

**2.** 
Note for doinst.sh: this script is identical to the pinstall.sh script found in a PET package; if you have an existing pinstall.sh for your package, 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 to 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 a requirement of pinstall.sh scripts in PET packages too.

**3.** 
Note for making 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 packages 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 -l p* and *paco2pkg*

**paco** is program to perform installation file capture, just like new2dir.
(The website for paco used to be [http://paco.sourceforge.net/ 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 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 a package; 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 then 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*" - a set of instructions on 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 includes commands for 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.

The Fatdog pkgbuild system is located in /usr/src/pkgbuild when the Fatdog development SFS "fd64-devx.sfs" is loaded.
It comes with samples.
Put your own recipe in the "*localpkg*" directory.
The finished package will be stored in the "*output*" directory.
The "*src*" directory will contain the downloaded source tarball, and the "*patches*" directory should contain the patches needed to build the package (if they aren't self-contained in the recipe itself).

The *pkg* directory contains the recipes used to create installed Fatdog packages.

