The proposal was raised in this thread: It seems like exploring scons for GNOME is worthwhile.

Proposed Schedule

But there is lots of work involved - GNOME's build system is huge and complex. Some kind of rough schedule:

1. Creating a demo prototype for gnome-hello with scons.

2. Make scons work with a few low-level libraries.

3. Make the scons-system modularized. It should require more code per component than what autotools does.

4. Maybe reevaluate? Raise the issue on desktop-devel-list again and see if the effort so far convinced more people?

TODO: bksys...

Scratch pad

SConstruct primer:

A SConstruct is a Python script which replaces the top-level Makefile. When building a software project, the SConstruct is automatically scanned by the SCons program, and project dependencies (and/or optional components) are defined inside SConscript(s). The differences between a SConstruct and a SConscript are subtle, but as a rule of thumb there should only be 1 SConstruct per project and any number of optional SConscripts.


RichardHughes: Problems that I perceived initially with scons and building gnome-power-manager: * No existing framework defined -- a new project would have to itself define "make dist" and more importantly "make distcheck". GustavoCarneiro: solved in my pygtk scons, see below.

* No existing framework to get deps, something like defining different constants for differing versions of dbus-glib. GustavoCarneiro: I don't see a problem here; you have the full power of python and env.Append(CPPFLAGS=" -DFOO=BAR"). Also check my PkgCheckModules configure test in pygtk below.

* No GNOME template for this sort of thing -- some of this should be abstracted like gnome-common? GustavoCarneiro: one can define scons 'tools' for this; check my pygtk work below.

* It's not clear how we can call an external program such as glib-genmarshal for the dbus introspection stuff. GustavoCarneiro: one has to use scons' Builder or Command constructors; check the Codegen builder in the pygtk example below.

Basically, for serious adoption by the GNOME community we need many more examples on how to do the common stuff, with howtos and easy to follow guides converting specific autotools syntax to the SCons equivalent. For a long time we will need both buildsystems in each project until the critical mass is achieved. GustavoCarneiro: I'm not sure I agree individual projects should have both build systems at the same time; maintaining two build systems will likely introduce bugs due to one being updated and not the other. More feasible is that we migrate projects gradually, and throughout GNOME some projects are left using autotools, others switch completely to scons.

Example: PyGTK SCons

GustavoCarneiro: I have been working with converting PyGTK to scons: tarball, patch (work in progress). Let me highlight some of the more interesting parts: Here's in the Sconstruct file how to define the environment, requesting the 'gnome' tool that I defined, and defining package name and version:

env = Environment(ENV=os.environ,
                  toolpath=['scons'], tools=['default', 'gnome'],
                  VERSION='.'.join(str(x) for x in pygtk_version))

The next snippet shows how to add some 'configure' checks. I couldn't find any neat way of automatically registering the configure tests defined in scons/; so, as workaround, I exported them through the environment, and use them in the SConstruct:

conf = Configure(env, custom_tests=env['GNOME_TESTS'])

if not conf.CheckPython((2,3,5)):
    print "Python too old or missing"

if not conf.CheckPythonHeaders():
    print "Missing python headers"

conf.CheckPython((2,3,5)) defines env['PYTHON'] to the correct python exe path, env['PYTHON_VERSION'], and also env['pythondir'] and env['pyexecdir'] for the locations to install python modules. This is all more or less a translation of the equivalent autoconf macros. conf.CheckPythonHeaders() checks for python includes and defines env['PYTHON_INCLUDES'].

Now to demonstrate conditionals and actually building something:

## --- pango ---
build_pango = conf.PkgCheckModules("PANGO", "pango >= %s" % pango_required_version)
if build_pango:
    pango = env.SharedLibrary('pango', ['pangomodule.c', 'pango.c'],
                              CCFLAGS="$CCFLAGS $PANGO_CFLAGS $PYTHON_INCLUDES",
                              LINKFLAGS=env['PANGO_LIBS'], SHLIBPREFIX='')
    env.Alias("install", env.Install('$pygtkdir', pango))
    env.DistFiles(['pango.override', 'pango-types.defs'])

You'll notice:

  • As you see, the PKG_CHECK_MODULES autoconf macro was ported over to scons. Like in autoconf, it defines env['PANGO_CFLAGS'] and env['PANGO_LIBS'].

  • Next we have env.Codegen("pango") which is a scons 'Builder' I defined earlier to invokes the pygtk code generator to transform foo.defs into foo.c.

  • The pango = env.SharedLibrary(...) part is quite trivial and documented in the scons manual.

  • The line env.Alias("install", env.Install('$pygtkdir', pango)) demonstrates the correct way to handle the 'scons install' target (standard scons stuff, it's in the scons faq).

  • Next we have env.DistSources(pango) which is a small function I wrote which recursively walks up the dependency tree of a scons 'node' object and adds to env['DISTFILES'] all files that are not built from any other source. In this case, notice that pango sources are defined as ['pangomodule.c', 'pango.c'] but pango.c is generated from pango.defs, therefore pango.c is not added to DISTFILES but instead pango.defs is added. Finally env.DistFiles is used to add additinal files to DISTFILES. The variable env['DISTFILES'] is used by the 'dist', 'distdir', and 'distcheck' targets to generate a distribution tree. Caveat: there's a small problem in this example; if the maintainer doesn't have pango libraries/headers then not only is pango module not built but also it is not included in the distribution.

Attic/scons (last edited 2013-12-04 02:49:22 by WilliamJonMcCann)