IPFire 2.x - Building Addons

IPFire is expandable by using Pakfire, its built-in package management system. There are some useful add-ons that can be installed this way, but in some cases, you will need to create your own. The following instructions shows an example of how to build a custom add-on called foo2zjs.


To build an Addon for IPFire, you will need to set up a build system up and the source code of the add-on you want to build.

This example uses a host computer with a recent version of Ubuntu 64-bit. Some tweaking is required.

See Requirements for Building Addons

Basic principles

The build process for Linux software is usually the same for each program:

  • Unpack your tarball/archive: tar xvf <yourfile>.tar.gz
    • or whatever fits your needs to unpack
  • Change the directory to the source-dir: cd <yourfile>
  • Run the configuration-script: ./configure
  • Compile: make
  • Install: make install
    • run this command as root

To compile a package for IPFire (it actually is a LFS requirement) you have to insert the build sequence in the general compilation framework. To do this You have to:

  • Write a compilation script for the package and put it in lfs/
  • Link the script adding a line to make.sh
  • Define which, produced by the build, will be in your package.

Each of these steps will be detailed below.

Download the source

You should be familiar with building the new addon package in a standard Linux environment. Making experiments in the IPFire build environment can be very time-consuming and error-prone, so I strongly advise to download the source code and install the package on your standard Linux distribution first, and keep track of what you did. This includes:

  • Where you got the package from
  • Any package dependencies
  • What command, exactly, you used to unpack it
  • What is the minimum set of commands needed to configure, compile and install the package
  • If you needed to change anything, patching code or configuration files
  • If you needed to download anything else to complete the installation

If you needed package dependencies, stop now and start building those first.

There must be some prerequisite depending just on standard IPFire packages; start from that and build on the results.

If you need to have Internet access while building (i.e.: after you start configuration and before you can install) you will need a DNS proxy on your build machine (e.g.: dnsmasq).

In my example I will build the foo2zjs printer driver to be used together with foomatic to support my Samsung CLP-315 printer. The driver depends only on foomatic which is already supported by IPFire, so I can directly proceed.


Start by placing a copy of the source code for your addon into the cache folder with the rest of the sources for all of the packages. The file will be compressed e.g. as .xz or .tar.gz. The file name we will use is foo2zjs-source.tar.gz.

The LFS build fragment

The next step is to write a build fragment for LFS. This file requires a well defined structure that we need to customize.

A generic template for this file is available in the LFS build fragment for building Addons page or you can just copy one of the files from the lfs/. You will need to change a few lines in this template:

  • VERSION The version number of the new package; it will be used in building the archive name.
  • THISAPP The package name
  • DL_FROM The default points to IPFire repository, but this package isn't there, so we need to modify.
  • PROG The name of the main program, usually the same as THISAPP
  • DEPS The dependencies needed by this application.
  • PAK_VER Continuously incrementing package version counter. Set this to a number one higher than previously released version of this package starting at 1 when no earlier release exists.
  • The build recipe: the default is the minimal make, but we may need to expand/modify it.

Save your lfs file as foo2zjs in the lfs/ folder.

See LFS build fragment for building Addons.

Linking in the build script

To incorporate the new build in IPFire build script you have to add a line in make.sh. This line should be near the end of the buildipfire() function:

buildipfire() {
  lfsmake2 rfkill
  lfsmake2 amazon-ssm-agent
  lfsmake2 foo2zjs # <-- this line was inserted and matches the filename in lfs

buildinstaller() {

First compilation

The build environment is now complete and we can try to compile our package. It is enough to issue:

sudo ./make.sh build

It should run very quickly and you should see, at the end of * * * Building IPFire section something like:

rfkill                [       0.5 ]             [        0 ] [ DONE ]
amazon-ssm-agent      [   2.3.930.0 ]           [        0 ] [ DONE ]
foo2zjs               [  noversion ]            [      141 ] [ DONE ]
*** Building installer (Last sta      versionec options    time (sec)   status

If something went wrong You can try to manually install in the IPFire build environment this is done using make.sh shell. This command will set-up the same chroot environment used for building and start a shell in it. When you are done with your tests you can just close the shell with <Ctrl>D.

$ sudo ./make.sh shell
Resetting our nice level to 10                                         [ DONE ]
Checking if we're running as root user                                 [ DONE ]
Checking for necessary space on disk                                   [ DONE ]
Entering to a shell inside LFS chroot, go out with exit

$ cd /tmp

$ tar xzf /usr/src/cache/foo2zjs-source.tar.gz

$ cd foo2zjs/

$ ls
COPYING         foo2qpdl.1in         icc2ps
foo2qpdl-wrapper.in hplj10xx_gui.tcl     zjsdecode.c

$ exit

I used this environment to understand why downloading from the Internet failed consistently in the build environment while it worked perfectly well at the shell prompt.

Please Note:

  • I am always working as "normal" unprivileged user, so I need to prepend sudo to build commands
  • Changing anything in the compilation script will not cause module recompilation. The easiest way I found to force rebuild is to touch the archive file from cache (or delete it).

Package definition

At this point we are almost there.

You still need to define which files need to be in the packages.

The IPFire build system is very kind and will prepare for you a file containing all files added or removed by the installation. At the very end of the compilation you will see something like:

xvid                            [      1.2.1 ]            [        0 ] [ DONE ]
xen-image                       [     ipfire ] [ ED=full ][      200 ] [ DONE ]
Generating files list from logs                                        [ DONE ]
*** Checking Logfiles for new Fi      versionge options8 s time (sec)   status
Changes in cdrtools-2.01.01 check rootfile!
Changes in foo2zjs-source check rootfile!
***Build is finished now and took 0 hour(s) 29 minute(s) 57 second(s)!

This file have the same name as your filename (foo2zjs-source) and is located in the log directory. Copy it into config/rootfiles/packages but also rename it to the lfs filename you used before:

cp log/foo2zjs-source config/rootfiles/packages/foo2zjs

Now open the file in a text editor. It contains a list of all files added, removed or changed by your make install (a changed file will appear as added and deleted).

You will need to remove the prepended plus (+) or minus (-) sign and, possibly, to comment out some files.

Rule-of-thumb is as follows:

  • remove all lines with a minus (-) sign.
  • remove all plus (+) signs.
  • comment out (prepending a hash (#) sign) all lines pointing to directories.
  • comment out (prepending a hash (#) sign) all lines pointing to "useless" files.

Useless files are:

  • manpages (are usually located in /usr/share/man)
  • pkg-config files ( are usually located in /usr/lib/pkgconfig)
  • *.so files (are usually located in /usr/lib)
  • *.a files (are usually located in /usr/lib)
  • *.la files (are usually located in /usr/lib)
  • *.h files or header files (are usually located in /usr/include)
  • *.m4 files (are usually located in /usr/share/aclocal)
If your new rootfile contains files which are located in /usr/local this is really bad. Nothing should go there. If files are located there for example library files this cause a lot of trouble because in the most cases they are not found by the program. To avoid this you should always use --prefix=/usr.

Original and edited files for foo2zjs can be found in the Package for foo2zjs page.

Pakfire Routines

Last bit of customization is about the installation/removal routines.

Pakfire provides a set of standard scripts for install, uninstall and upgrade; they can be found in src/paks/default.

If these are not enough, for any reason, you can customize them.

Required steps are:

  • copy src/paks/default to src/paks/<yourPackage>
  • edit src/paks/<yourPackage>/install.sh, src/paks/<yourPackage>/uninstall.sh or src/paks/<yourPackage>/update.sh

I had to customize the routines to add cups update. See Pakfire Routines wiki page.

Final build

Finally you have to restart the build to produce the final product using the following commands:

sudo ./make.sh clean
sudo ./make.sh build


You should now have a brand new packages/<youraddon>-<version>-#.ipfire, so in this example we would have packages/foo2zjs-noversion-2.ipfire

To test it you have to send it to your installed IPFire and install it. This is easily done via scp/ssh:

$ scp -P 222 foo2zjs-noversion-2.ipfire root@ipfire:/tmp
foo2zjs-noversion-2.ipfire                          100%   19MB   9.6MB/s   00:02

$ ssh -p 222 root@ipfire
Last login: Thu Nov 18 08:51:10 2010 from vmrunner.condarelli.it

$# cd /opt/pakfire/tmp/

$# tar xvf /tmp/foo2zjs-noversion-2.ipfire

$# ls -l
total 39426
-rw-r--r-- 1 root root 20080640 2010-11-17 18:33 files
-rw-r--r-- 1 root root 20111360 2010-11-18 08:50 foo2zjs-noversion-2.ipfire
-rwxr-xr-x 1 root root     1735 2010-11-17 18:33 install.sh
-rw-r--r-- 1 root root    13306 2010-11-17 18:33 ROOTFILES
-rwxr-xr-x 1 root root     1717 2010-11-17 18:33 uninstall.sh
-rwxr-xr-x 1 root root     1691 2010-11-17 18:33 update.sh

$# NAME=foo2zjs ./install.sh
Extracting files...
Stopping CUPS Printserver...                                                               [  OK  ]
Starting CUPS Printserver...                                                               [  OK  ]

$# rm *
rm: remove regular file 'files.tar.xz'? y
rm: remove regular file 'install.sh'? y
rm: remove regular file 'ROOTFILES'? y
rm: remove regular file 'uninstall.sh'? y
rm: remove regular file 'update.sh'? y

$# logout
Bye bye.
Connection to ipfire closed.

The Package is now installed and ready to run.

If there's something wrong and you need to modify some of the files in the upstream archive (i.e.: the archive downloaded from ${DL_FROM}/${DL_FILE}), you will need to prepare a patch and to add the information in the recipe. I plan to write a page on that; it will be linked here.

Next Step: Sharing with others

TODO: How can your package be added to the pakfire list in ipfire?
Pakfire build services??
How to change Branches (stable, testing, unstable) Process to submit??

How can someone install an unhosted, unofficial pakfire? Only using the testing steps?

The End

That's all, Folks!

Edit Page ‐ Yes, you can edit!

Older Revisions • March 28 at 9:22 pm • Robin Roevens