[cairo] Breaking the dependency on libX11

Behdad Esfahbod behdad at behdad.org
Wed Aug 13 11:03:49 PDT 2008

Vladimir Vukicevic wrote:
>> Open design question: how do we get pkgconfig to return a  
>> different .so
>> depending on what backends the client is planning to use?
>> One could have multiple .pc files, such as cairo.pc, cairo-image.pc,
>> cairo-pdf.pc, but how would we handle the various situations for  
>> people
>> who want just one library with all the backends?

We already do that.

> That situation doesn't exist -- an app has to explicitly know which  
> backends it intends to use, otherwise it won't end up using them.
> Figuring out how to split them would be great, but that ship may have  
> sailed due to .so compat issues...

That part is easy to fix:

  - cairo-core.so: only image backend and user fonts
  - cairo-png.so, cairo-ft.so, cairo-xlib.so, ...: depend on cairo-core.so
  - cairo.so: depend on all of them.

Then change cairo.pc to link to cairo-core.so instead of cairo.so.  Or keep
that one as is and add a cairo-core.pc or cairo-minimal.pc.  Or just add
cairo-image.pc and cairo-user-font.pc.  Any use of cairo has to depend on some
surface and/or backend afterall.

Next problem is that cairo-features.h hardcodes list of enabled features.
Ugh!  This one also can be worked around, by moving, say, the #define
CAIRO_HAS_PDF_SURFACE to cairo-pdf.pc as -DCAIRO_HAS_PDF_SURFACE.  This forces
everyone to use pkg-config and is uglier, but again, we can make it be opt-in.
 That is, only disable them if you are using cairo-core instead of cairo.  So
it would be back-compat.

Next, the open question so far, is how to let the backend and core .so's
communicate without exposing the API.  The surface-backend-API part is
actually easy:

  1) No need to expose the API.  All surface constructors reside in the
backend .so's.  They just assume that the other .so is of the same version of
cairo.  We can enforce that it need be.  We can even instead add some padding
to the backend struct and only append to it (like we already do).  This way we
are in fact maintaining an adhoc stable API.

  2) Like 1, but also expose that backend API in cairo-backend-surface.h.
Mark it unstable across micro releases.  Like Pango module/backend API is.
This has worked for Pango.  Pippin liked the idea as it means he can write his
OpenVG backend using it.  Keep reading though.

The same thing would be harder to do for font backends as the toy text API
needs to have a default backend.  so the cairo-core.so needs to hook into
higher-level .so's.  One way around it would be to move the toy font stuff
higher, instead of leaving in core.  Another would be to include the main font
backend in the core.  That may drag in a surface backend too (win32, quartz?).

Finally, the harder part of the backend interface question is the functions /
surfaces that the cairo-core.so needs to expose for backends to use.  That one
I have no way around.  This is a large chunk of the stuff in cairoint.h.
That's a LOT to risk exposing, even if with the "_cairo" prefix.  Also
includes things like meta-surface, analysis-surface, etc.  This is the part I
have not found any answer to yet.  Which makes me ask again, is it really
worth it?

All this ignoring the 4k memory per process overhead of each additional .so.
We may save by not dragging in libdirectfb.so, libxcb.so, libpng.so, libz.so,
etc unnecessarily, but for the most common uses (GTK+ apps), all but directfb
are dragged in anyway.

>      - Vlad


More information about the cairo mailing list