Dan Mahoney (gushi) wrote,
Dan Mahoney

How to build wkhtmltopdf 0.9.6 under FreeBSD AMD64

Installing wkhtmltopdf 0.9.6 under FreeBSD

At my day job, our knowledge base software needs a specific version of wkhtmltopdf to work. Further, it needs the version built against a specially patched set of QT libraries in order to do certain critical things (for example, to run headless). If you run ./wkhtmltopdf against a non-patched version, it will issue this warning:


Reduced Functionality:
  This version of wkhtmltopdf has been compiled against a version of QT without
  the wkhtmltopdf patches. Therefore some features are missing, if you need
  these features please use the static version.

  Currently the list of features only supported with patch QT includes:

 * Printing more then one HTML document into a PDF file.
 * Running without an X11 server.
 * Adding a document outline to the PDF file.
 * Adding headers and footers to the PDF file.
 * Generating a table of contents.
 * Adding links in the generated PDF file.
 * Printing using the screen media-type.
 * Disabling the smart shrink feature of webkit.


FreeBSD has a port for wkhtmltopdf, which includes a patched QT, but version 0.9.6 will not build against this patched QT. Thus, we need to build both from scratch.

Further, when attempting to build the patched QT from source, there are at least two active bugs.

First, javascript compilation will fail with a couple of minor type conversion errors.

This is a similar error reported with another piece of software:

../JavaScriptCore/runtime/JSValue.h: In constructor ‘JSC::JSValue::JSValue(JSC::JSCell*)’:
../JavaScriptCore/runtime/JSValue.h:472: error: cast from ‘JSC::JSCell*’ to ‘int32_t’ loses precision
../JavaScriptCore/runtime/JSValue.h: In constructor ‘JSC::JSValue::JSValue(const JSC::JSCell*)’:
../JavaScriptCore/runtime/JSValue.h:478: error: cast from ‘JSC::JSCell*’ to ‘int32_t’ loses precision
make[1]: *** [WebKit/gtk/WebCoreSupport/libwebkit_1_0_la-ChromeClientGtk.lo] Error 1

Patches in this bug listing tell us how to fix it, mostly (the patches are not FreeBSD specific, but the exact nature of the fix is easy to glean).

Second, WebKit seems to suffer a bug (referenced here) whereby it will pick up the system header files (even if you've told it to build with the builtin versions), so it will believe that the list of available functions is off, with an error like:

: undefined reference to `png_set_longjmp_fn'
/data/home/dmahoney/wkqt/lib/libQtGui.a(qpnghandler.o)(.text+0x1b7c): In function `QPngHandlerPrivate::readPngHeader()':
: undefined reference to `png_set_longjmp_fn'
/data/home/dmahoney/wkqt/lib/libQtGui.a(qpnghandler.o)(.text+0x23a0): In function `QPngHandlerPrivate::readPngImage(QImage*)':
: undefined reference to `png_set_longjmp_fn'

It's my hope that I can show how to get this tool, at this specific version, to install, and help others who may hit this. I'm also pasting in the actual compiler output such that people can google for it and find this entry.


It's probably a good idea to make and install this port anyway as it will pull in a bunch of X11 and font dependencies that we may later need, but once it's installed, it's probably safe to "make deinstall" it.

Part 1: wkhtmltopdf-qt

Get the wkhtmltopdf source

We grab the source for wkhtmltopdf at this phase because we need a file from it to get the build arguments for qt. Grab wkhtmltopdf version 0.9.6 from google code downloads page. Since it is a deprecated release, it will not be in the default list. Go here Select "All Downloads" and search for 0.9.6, to get:


Grab this with "fetch" or "wget" or just scp it over to the system.

Get the wkhtmltopdf-qt version you need

There was, at one time, a git repository at: git://gitorious.org/+wkhtml2pdf/qt/wkhtmltopdf-qt.git. It no longer seems to answer.

Luckily, the repository has been mirrored onto Github.

Clone wkhtmltopdf-qt from this github page, then isolate it down to the 0.9.6 release tag.

%git clone git://github.com/jcsalterego/wkhtmltopdf-qt.git
Cloning into wkhtmltopdf-qt...
remote: Counting objects: 563729, done.
remote: Compressing objects: 100% (104214/104214), done.
remote: Total 563729 (delta 455301), reused 563645 (delta 455222)
Receiving objects: 100% (563729/563729), 376.20 MiB | 2.34 MiB/s, done.
Resolving deltas: 100% (455301/455301), done.

(the above took about ten minutes on my very fast connection)

You can see that there are several "tagged" releases of code in this repository:

%git tag -l

So you're going to want to reduce the repository to that version:

%git checkout wkhtmltopdf-0.9.6
Checking out files: 100% (22888/22888), done.
Note: checking out 'wkhtmltopdf-0.9.6'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at e63d059... Fix pdf title writeout

(this took 3-5 minutes) Welcome to 2010!!!

Without the output, the two commands you really need are:

git clone git://github.com/jcsalterego/wkhtmltopdf-qt.git
git checkout wkhtmltopdf-0.9.6

Patch wkhtmltopdf ### :

There's a trivial change we need to make in the javascript code if we're on a 64 bit platform.

Manually apply this patch, but add a line for PLATFORM_FREEBSD.
So, on line 721 of ./src/3rdparty/javascriptcore/JavaScriptCore/wtf/Platform.h, change:




Do the same on line 712 of ./src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h.

Configure wkhtmltopdf-qt

Per the build guide, you can get the configure arguments by doing cat ../wkhtmltopdf/static_qt_conf_base ../wkhtmltopdf/static_qt_conf_linux | sed -re 's/#.*//'

Then, you get to go into a text editor and put them all on one line.

./configure -release -static -fast -no-exceptions -no-accessibility -no-stl -no-sql-ibase -no-sql-mysql -no-sql-odbc -no-sql-psql \
-no-sql-sqlite -no-sql-sqlite2 -no-qt3support -no-xmlpatterns -no-phonon -no-phonon-backend -webkit -no-scripttools -no-mmx \
-no-3dnow -no-sse -no-sse2 -qt-zlib -qt-gif -qt-libtiff -qt-libpng -qt-libmng -qt-libjpeg -graphicssystem raster -opensource \
-nomake tools -nomake examples -nomake demos -nomake docs -nomake translations -no-opengl -no-dbus -no-multimedia -fast -openssl \
-largefile -rpath -no-nis -no-cups -no-iconv -no-pch -no-gtkstyle -no-nas-sound -no-sm -no-xshape -no-xinerama -no-xcursor \
-no-xfixes -no-xrandr -no-xrender -no-mitshm -no-xinput -no-xkb -no-glib -no-openvg -no-opengl -no-xsync -no-svg -prefix "../wkqt"

(later amended to add -system-png instead of -libqt-png, due to a QT bug whereby QT will use the system header file but build against the bundled lib, thus causing linking errors)

Once you type this, you'll have to type "yes" to accept the GPL. (Yes, GPL code with a EULA). It will run for a few minutes.

Build the library

If all went well, all you should need to do is:

gmake -j3 && gmake install

When this is done, you should have a "wkqt" directory just above your build dir, that has a ./bin/qmake in it (along with some other stuff).

Building wkhtmltopdf itself

This one is shockingly easy, presuming all the rest of the code worked:

cd ../wkhtmltopdf

(I get a warning about WARNING: /data/home/dmahoney/wkhtmltopdf/wkhtmltopdf.pro:21: Unable to find file for inclusion /data/home/dmahoney/wkqt/lib/QtGui.framework/QtGui.prl, but this seems to be mostly harmless since we're building a headless version.

Then, type make. It should spin for a few more minutes, and if all went correctly, you should have a wkhtmltopdf file in your home directory.

Test it with ./wkhtmltopdf and see if you get a basic help page. If you do, you're probably in business!

Finishing up

If you're going through all this pain for Knowledge Base Manager Pro, copy it to the appropriate directory in your web root, and test it out.

If you're doing this for some other reason -- like, "you like running old, hard to compile code when there's an easy install option", there are self-help groups and therapy for this sort of thing :)

You probably don't need the "wkqt" directory any more, and you can probably also delete all the source files after that.



Compiling Guide: http://code.google.com/p/wkhtmltopdf/wiki/compilation http://code.google.com/p/wkhtmltopdf/wiki/static


wkhtmltopdf: http://code.google.com/p/wkhtmltopdf/downloads/list wkhtmltopdf-qt: https://github.com/jcsalterego/wkhtmltopdf-qt

About the author

Dan Mahoney is a sysadmin in the San Francsico Bay Area. He fixes computers.

  • Post a new comment


    Comments allowed for friends only

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded