QOF - Query Object Framework

# Packaging and building against QOF

- Introduction
- QOF and libgda
- Packaging documentation.
- SourceForge
- Documentation
- Downloads
- Development
- Online
- Origins
- Function
- Goals
- Status
- Why QOF?
- Data Freedom
- Support

## Advice for packagers / maintainers

### Updated December 2007 for QOF 0.7.4

- Building against QOF
  - AUTOMAKE example
  - libqof1 API/ABI compatibility.
  - MAX_REQUIRED specifiers
  - DWI now unsupported.
  - Date and time changes
  - libgda versions.
- Packaging QOF.
  - libxml2 >= 2.5.10
  - There is no QOF dependency on Gtk!
  - There is no need for perl or intltool
  - Which backend to use?
  - QOF for embedded devices
- Using libqof-dev
- Preparing for libqof2

## BUILDING AGAINST QOF

### AUTOMAKE

The simplest way to use QOF is with PKG_CHECK_MODULES in configure.ac Note the change in the pkgconfig filename from qof-1 to qof in 0.7.4 - this is to allow easier migration to the upcoming libqof2. qof-1.pc will be removed in libqof2.

    dnl *************************************
    dnl QOF
    dnl *************************************

    QOF_REQUIRED=0.7.4
    PKG_CHECK_MODULES([QOF], [qof >= ${QOF_REQUIRED}])
    AC_SUBST(QOF_CFLAGS)
    AC_SUBST(QOF_LIBS)

You can add further commands to retrieve other information:

- QOF Version string:

      QOF_VERSION=`$PKG_CONFIG --silence-errors --modversion qof`

- QOF prefix

      QOF_PREFIX=`$PKG_CONFIG --silence-errors --variable=prefix qof`

- Location of QOF backend modules

      QOF_LIB_DIR=`$PKG_CONFIG --silence-errors --variable=libdir qof`

- Location of the QSF XML schemas

      QOF_XML_DIR=`$PKG_CONFIG --silence-errors --variable=xmldir qof`

Or consider this more verbose example:

    dnl *************************************
    dnl QOF
    dnl *************************************

    QOF_REQUIRED=0.7.4
    AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
    if test pkg-config = no; then
    	AC_MSG_ERROR([Please install pkgconfig])
    	exit 1
    fi
    AC_MSG_CHECKING([for QOF - version >= $QOF_REQUIRED])
    QOF=`$PKG_CONFIG --silence-errors --exists 'qof >= $QOF_REQUIRED'`
    QOF_LIBS=`$PKG_CONFIG --silence-errors --libs qof`
    QOF_CFLAGS=`$PKG_CONFIG --silence-errors --cflags qof`
    QOF_VERSION=`$PKG_CONFIG --silence-errors --modversion qof`
    QOF_PREFIX=`$PKG_CONFIG --silence-errors --variable=prefix qof`
    QOF_LIB_DIR=`$PKG_CONFIG --silence-errors --variable=libdir qof`
    QOF_XML_DIR=`$PKG_CONFIG --silence-errors --variable=xmldir qof`

    AC_SUBST(QOF_CFLAGS)
    AC_SUBST(QOF_LIBS)
    AC_SUBST(QOF_PREFIX)
    AC_SUBST(QOF_LIB_DIR)
    AC_SUBST(QOF_XML_DIR)
    if test x$QOF_XML_DIR = x; then
            AC_MSG_RESULT([no])
            AC_MSG_ERROR([
            The package requires the Query Object Framework: QOF.
            You need to install QOF >= ${QOF_REQUIRED} (libqof1).
            You can find it at http://qof.sourceforge.net/
    ])
            exit 1
    else
            AC_MSG_RESULT([yes (found $QOF_VERSION)])
    fi

For more information, see the source for Pilot-QOF, gpe-expenses or CashUtil which include an optional method to build from QOF CVS source as well as the package.

http://pilot-qof.sourceforge.net/

http://cashutil.sourceforge.net/

http://gpe-expenses.sourceforge.net/

### libqof1 API/ABI compatibility.

During the life of the QOF the 0.6.x and 0.7.x trees, various functions will be deprecated and renamed - leaving a #define or deprecated version to support the old name. New code will be expected to use the new name and old code the deprecated version. Then when all such code has been sorted out, applications have two choices:

1. Move to the new API with the library, or
2. Integrate the #define's in a header of their own.

Either way, the deprecated functions will then be removed from QOF in a single operation that takes us smoothly from libqof1 to libqof2. This is expected to happen with QOF v0.8.0, once the GDA backend is functional.

### MAX_REQUIRED specifiers

Some packages have previously used:

    LIBQOF_REQUIRED_MIN=0.5.2
    LIBQOF_REQUIRED_MAX=0.5.2

The MAX value is no longer required. QOF will only change the API/ABI on a SONAME increment. So each release of libqof1 will always be API/ABI compatible with previous releases of libqof1. It is recommended to only specify a minimum and accept any later version of QOF.

### DWI has stalled

#### Updated for QOF 0.7.2

DWI - Data With Interaction - was in development but it's SourceForge project has seen little recent activity and is now out of date with the main QOF library. DWI support will be retained in CVS but will not be implemented in libqof2.

### Date and Time changes

The date and time handlers have been overhauled and there are large changes. Timespec has been deprecated and replaced by QofTime which is an opaque type. QofTime has completely replaced the previous code and includes handlers to avoid pitfalls of incompatible date/time format conversions. QofTime only handles times in seconds. All date handling is done exclusively in a new type, QofDate, an extended version of struct tm. Applications using QOF should now use QofTime to replace time_t and QofDate to replace struct tm. Functions like localtime, gmtime, mktime and time can be used externally - subject to the more limited range of values supported in each case.

QOF_TYPE_DATE is now deprecated, to be replaced by QOF_TYPE_TIME. This is the first change in the QofObject API in libqof1 and requires significant changes within all QOF objects to be supported by libqof2. libqof2 will therefore use a incremented QOF_OBJECT_VERSION. libqof1 retains the existing version, using QOF_TYPE_TIME as an optional extra. Packages using QOF_TYPE_TIME need to depend on QOF >= 0.7.0

QofTime is opaque, firstly, to implement strict validity checking and secondly to ensure consistent handling within objects. QofTime and QofDate now support all times and dates within a couple of dozen times the age of the universe by using 64bit values wherever necessary.

0.7.0 introduced strftime and strptime extended code based on the Debian coreutils package (specifically the 'date' command) and the glibc source code, providing support for nanosecond formats and the full range of QofTime and QofDate.

### Mac OSX

Specify your Mac OSX compiler settings as environment variables. e.g. for fink use:

    export CPPFLAGS="-I/sw/include"
    export LDFLAGS="-L/sw/lib"
    export LIBTOOL="glibtool"
    export PATH="/sw/bin:$PATH"
    export ACLOCAL_FLAGS="-I /sw/share/aclocal"

Helpful pair of settings for general manpage usage (to go into .bashrc in your home directory):

    export MANPATH="/sw/share/man:<build_path>"
    export PAGER="less -s"

To only use these for this one build, create a bash script and export the variables before calling ./autogen.sh

QOF is no longer routinely built on OSX. If you encounter problems, post the '`config.h`' file from the top directory of your build to the QOF-devel mailing list.

## PACKAGING QOF

### libxml2 >= 2.5.10

The version string is vital. (Earlier versions will break the QSF backend horribly.)

### There is no QOF dependency on Gtk!

Do not list a QOF runtime or build dependency on libgtk. The one example that could use Gtk has now been removed from the distribution tarball along with the other (outdated) examples.

That's all there ever was to the Gtk stuff. It's important because projects like pilot-link will not accept code that links to GUI stuff for no good reason.

### There is no need for perl or intltool

The `libxml-parser-perl` build dependency has been removed by migrating from `glib-gettextize` to `gettextize`. All `intltool-*` scripts are removed by running `./autogen.sh`.

### Which backend to use?

QSF XML has always been a separate module, the new SQLite backend is also a separate module. When packaging QOF >=0.7.1, maintainers have the option to use one or both backends (QOF requires at least one backend to be available).

- libqof-backend-qsf0 : Default XML backend for most applications.
- libqof-backend-sqlite0 : SQLite backend intended for embedded applications where libxml2 is simply too large for the available storage space.
- roll-your-own : Some applications already have their own backends for use via QOF.
- Future backends : GnomeDB support is expected for libqof2. This will add a further module which in turn allow for other plugins for libgda itself. (See the notes on libgda module delays.)

QOF can be packaged separately from the modules but care is needed to ensure that existing applications can locate and load the necessary backend. Applications that cannot load the necessary backend will typically fail to start or be unable to load or save data.

At present, only pilot-qof and gpe-expenses support all available QOF backends. In most cases, it is wise to ensure that at least libqof-backend-qsf0 is available for all existing QOF applications. New applications and new versions of existing applications can be configured to load new and additional backends.

### libgda versions

`libda-3.3` is now in Debian. QOF only uses the SQL handling code, originally copied out of libgda but built by QOF internally if libgda is either not found or is disabled. libgda can be explicitly disabled by passing the `--disable-libgdasql` flag to ./configure. See also libsql in QOF.

If you choose to disable libgdasql from libgda3-3, ensure that the internal `lib/libsql/libqofsql.so` library is available in the packages. For example, in Debian, this is done using the regular expression: `usr/lib/libqof[s.]*so.*` This ensures that whether libgdasql is used or not, the libqof1 package contains libqof.so.* and libqofsql.so.* (if built) without including the libqof-backend* modules into the main package (which would lose the benefits of smaller dependencies).

Disabling libgdasql removes the libgda3-3 dependency from libqof1 and allows the installation of libqof1 and libqof-backend-sqlite0 without requiring libxml2.

### QOF for embedded devices

libxml2 is getting quite large; too large for some embedded devices, especially as it is only a backend. The SQLite backend was written especially for embedded devices or other situations where QOF is to be used on systems with limited resources. QOF >= 0.7.1 provides two backend modules that can be packaged separately:

- libqof-backend-qsf0 : Depends on libxml2.
- libqof-backend-sqlite0 (new) : Depends on libsqlite0.

libqof1 and libqof2 require the installation of at least one backend module, QSF XML should be the default for all systems that can support libxml2 because the sqlite backend is not yet comprehensive. Full support is due in the next backend module based on GnomeDB (via libgda).

To get the full benefits of using the sqlite backend instead of qsf, ensure that you use `--disable-gdasql` so that libqof1 and libqof2 does not depend on libgda3-3 and therefore libxml2.

### Replacement of lib/libsql

The code in lib/libsql came from the libgda package at about v1.0.3 and is now commonly available, including on Mac OSX via fink - albeit at only v1.0.4-3.

This code is used if libgda3-3 is not available or disabled when either `--disable-gdasql` or `--enable-embedded` option is given to `./configure`

### libqof-dev usage

The QOF API specifies the use of:

    #include "qof.h"

or

    #include <qof.h>

- this is because some headers in libqof-dev need to be included in the correct sequence. Individual filenames and file contents are also subject to change during the life of libqof1 and packages using QOF need to only use qof.h to avoid problems moving to libqof2.

### libqof2

Once the GDA backend is functional, QOF will migrate to libqof2. To test compatibility, pass the --disable-deprecated-qof option to ./configure and rebuild your application.

Once the migration starts, the rest of QOF will be reviewed - including moving certain sections of code around within the codebase to make the overview clearer and the library easier to follow. A series of pre-releases for libqof2 can then begin. Note that libqof2 will start with the last release of libqof1 but with all deprecated code removed. Users who migrate with libqof1 will be able to transfer to libqof2 without problems. The libqof2 API will then remain stable, just as with libqof1, but with a reduced release cycle. No large changes are anticipated in libqof2, the aim is to get all those done in libqof1.

### Packaging documentation

The doxy symlink in the website directory is provided for CVS users and the main SourceForge site. When packaging the website HTML alongside the Doxygen output, ignore the symlink and just package the Doxygen output:

- `doc/html/*` => `/usr/share/doc/libqof-doc/html/doxy/`

and the website content:

- `website/*.html` => `/usr/share/doc/libqof-doc/html/`
- `website/*.css` => `/usr/share/doc/libqof-doc/html/`
- `website/*.png` => `/usr/share/doc/libqof-doc/html/`
- `website/*.jpg` => `/usr/share/doc/libqof-doc/html/`

Written by Neil Williams <linux@codehelp.co.uk> December 2005.

Last updated by Neil Williams <linux@codehelp.co.uk> December 2007.

The copyright licensing notice below applies to this text.

Copyright © 2005-2007 Neil Williams

Permission is granted to copy, distribute, and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. In installed versions, the licence can be found in the copyright file.