Skip navigation.

Compiling with SCons and GTK

SCons is a rather nice build system written in Python. It compiles many languages, including C and Java. But the problem is that not many people have it, and making your code unnecessarily hard to compile by depending on an uncommon build system is not a good idea. In this article I'll show how you can get your build scripts to automatically download (and cache) SCons as part of the build process...

The SCons developers have produced a "local" version, which you can bundle with your own programs, but it's a bit inefficient if every program you download includes a copy of the build system and you (the author of the main program) then have to keep your scons version up-to-date manually.

Therefore, I've made it available using the injector, and I've created a little GTK demo package to show it off. The demo program itself isn't very exciting, but the build process is unusual as it gets both the GTK header files and the SCons build system using Zero Install.

To build it, you will need gcc, Zero Install (0.18 or later) and bzip2. You do not need the GTK header files or the SCons build system already installed.

Download the archive, unpack it and run 'make':

$ wget
$ tar xzf GTK-Sample-0.1.tgz
$ cd GTK-Sample-0.1
$ make

(The Makefile just runs 0launch ./GTK-Sample-src.xml, and isn't strictly necessary, but people are used to just typing make to build things!)

You will be presented with the familiar injector download box asking you to confirm the versions of everything:

Building a GTK application with SCons

When you click on Execute, the dependencies will be downloaded and unpacked and a binary called demo should be produced, which you can then run:

$ ./demo

Library problems

SCons itself worked perfectly, but I discovered a slight problem with the GTK headers. Building on my main machine worked fine: I got a binary compiled against GTK-2.4 (see Easy GTK binary compatibility).

But when I tried building in a Debian/sarge chroot without the gtk2.0-dev package installed, it failed because ld couldn't find a symlink /usr/lib/ It seems that this (and other similar symlinks for the other packages) tell the linker which major interface version of the library to use. So, if it's a symlink to then we link against a version of the library with major version 0.

This seems a bit of an odd way of doing things. It would make more sense to me if the library versions were given in the .pc files. It also means that you can't compile programs which use different library versions without uninstalling and reinstalling Debian packages, although once built you can run them at the same time!

I got around this problem by listing the major version numbers in the SConstruct file (SCons's equivalent of a Makefile) and having it replace these library names with full paths (e.g., in the output from pkg-config --libs gtk+-2.0, I replace -lgtk-x11-2.0 with /usr/lib/ This seems to work, but it doesn't look very portable and it makes the SConstruct file look ugly. Anyone know a better way?

Publishing SCons for Zero Install

Publishing an interface for SCons was extremely easy, as the SCons developers actually provide a scons-local package which worked without any patching at all. All I had to do was:

$ wget
$ 0publish -x --archive-url= SCons.xml

Those two commands:

  1. Downloaded the archive (0publish doesn't do this for you),
  2. Created a new interface and added the archive's information to it (download URL and digest),
  3. Opened an editor to let me fill in the uri, name, description, homepage, etc (from information on freshmeat), and
  4. XML signed the result (-x).

I uploaded the XML file and an icon to and it worked first time :-)

If you want to have a local scons command (e.g., to follow the user guide), you can get it in the normal way:

$ 0alias scons
$ scons --version
SCons by Steven Knight et al.:
        script: v0.96.92.D002, 2006/04/11 07:39:43, by knight on roxbury
        engine: v0.96.92.D002, 2006/04/11 07:39:43, by knight on roxbury
Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation

Of course, when writing your build scripts, you shouldn't rely on users having this command or alias though, but use the full URI. Then Zero Install can use the local cached copy if available, or download one if it's not present.

See also:


I've discovered the ${pcfiledir} pkg-config special variable, which simplifies things quite a bit. I've uploaded new versions of all the header file packages which now use this, and a shorter version of the sample app:

(do make config and click on Refresh all now to discover the new versions)

Library links

If you put the .so -> .so.0 symlink in the -dev package, and make sure that directory is in the linker search path, then that should take care of it.

I think the path is LD_LINK_PATH or LD_LIBRARY_PATH.

RE: Library links

Link to what, though? A target of /usr/lib/ would work on many systems, but it's not a general solution.

If the runtime library (.so) package also came via Zero Install it would all be fine, because we'd just include the link in that (since each version of the library would go in its own directory we wouldn't have any conflicts).

But, to have a Zero Install header package work with a traditionally-installed .so package (the common case), searching in the SConstruct file seems to be the only way.

RE: Library links

Distributing the runtime library through Zero Install would be more compatible,and allow seamless use of newer versions, and would allow me to run 32-bit executables on my 64-bit system (I only have 32-bit versions of the core libraries, not GTK etc.).

It would make for bigger downloads though, and perhaps more memory use if different versions are in use at the same time.

The advantages outweigh the disadvantages for me. (But I can't speak for those with old computers or slow network access...)

Syndicate content