Raptor RDF Syntax Library - Upgrading to the Raptor V2 API

Raptor V2 is a major new version of the Raptor V1 API with many cleanups and changes that include adding, removing and re-ordering parameters, adding and removing return types as well as renaming the functions.

The headers and libraries install to different places or names so that Raptor V1 and Raptor V2 can both be present (including headers) on the same system without clashing. However, if you do try linking the same binary with both libraries, the symbols will clash and the program will fail in mysterious ways if it runs at all. There are only two installed files that overlap - the rapper utility and it's manual page.

Configuration and compiling changes

Raptor V2 uses pkg-config(1) to provide the compile and link parameters whereas Raptor V1 supports that as well as a script raptor-config. The recommended linking approach is now as follows:

  cc -o prog prog.c  `pkg-config raptor2 --cflags` `pkg-config raptor2 --libs`

Shown here as a compile in link all in one line but you typically split that into two stages.

  cc -c `pkg-config raptor2 --cflags` raptor-module.c
  ...
  cc -o prog raptor-module.c ... other modules ... `pkg-config raptor2 --libs`

Code changes

There are significant API changes, which are described in the Release Notes in long summary form with some background to why, in the ChangeLog in very long form. The reference manual contains a section describing what was added, deleted, renamed and otherwise changed for both the functions exported from the library, as well as the typedefs and enum values.

There is no fully automatic way to handle updating the code however there is a perl script provided in the docs directory that renames what it can, and otherwise inserts a WARNING comment near code that needs manual updating. This cannot be automated in some places such as when the fields of the raptor_statement object were replaced with raptor_term pointers. The script is used like perl docs/upgrade-script.pl source files for example

  $ perl docs/upgrade-script.pl prog.c

and then edit the file prog.c and search for WARNING: for any places that manual editing is needed.

Handling Raptor V1 or Raptor V2 in the same code

If you need to handle both APIs in the same codebase as alternatives, it is recommended that you use the following approach.

Create an application #define that records the choice of which API you want to use. You can do this triggered on whichever raptor.h is in the include path by #ifdef RAPTOR_V2_AVAILABLE but that may be dangerous if both libraries and headers are present. A better choice is an application specific define that is determined by a configuration step.

Once the choice is made, it is recommended you convert the code to the Raptor V2 API and then add backwards-compatible macros for the changed functions:

#ifdef APP_WANTS_RAPTOR_V2
/* nop */

#else
#define raptor_v2_function(arg1, arg2, arg3) raptor_v1_function(arg2, arg3)

#endif

Where the code cannot be done by simple expansion such as use of raptor_init() and raptor_finish() in V1 that are replaced by the functions around the world object in V2, use an #ifdef that provides the two code paths.

rasqal in GIT (will be 0.9.20) uses this approach.

Another approach if the Raptor V1 code is in a separate module / source file is to copy it and make a V2 version and then choose the file to use at configure or build time.

librdf 1.0.11 uses this approach.

Either way, basing the interface on the V2 APIs makes it clear what to remove when V1 is no longer supported.

Packaging recommendations for distributors

Since Raptor V2 probably needs to be installed in parallel with V1 for some time, at least for the different libraries and headers, both need to be packaged such that no files clash.

There are, however, two files that are shared after a 'make install': rapper(1) and rapper.1 the manual page.

For packaging systems that split the installation into multiple packages (libraries, headers, docs, debug files), these two files should be in a package of their own that replace and conflict with the earlier files. (This is what I have done with the Debian packages raptor-utils and raptor2-utils). For packaging systems that do not use multiple packages, you will have to either leave these files out of the V2 package or migrate them from the V1 package to the V2 package using dependencies to ensure there are no conflicts.

The advantage of making the V2 version of rapper is that it means the command-line utility under the well known name uses the latest Raptor code.


Copyright 2010-2023 Dave Beckett