[cig-commits] commit:

Mercurial hg at geodynamics.org
Mon Nov 24 11:58:40 PST 2008


changeset:   71:a8dba1da20c0
user:        LukeHodkinson
date:        Mon Apr 07 00:36:43 2008 +0000
files:       Makefile.system SConfigure SConscript SConstruct StgSCons config/SConfig/Node.py config/SConfig/Package.py config/SConfig/Platform.py config/SConfig/Project.py config/SConfig/SConscript config/SConfig/__init__.py config/SConfig/packages/BlasLapack.py config/SConfig/packages/CompilerFlags.py config/SConfig/packages/HDF5.py config/SConfig/packages/MPI.py config/SConfig/packages/OSMesa.py config/SConfig/packages/OpenGL.py config/SConfig/packages/PETSc.py config/SConfig/packages/PETScExt.py config/SConfig/packages/PICellerator.py config/SConfig/packages/SDL.py config/SConfig/packages/SVNRevision.py config/SConfig/packages/StGermain.py config/SConfig/packages/StgDomain.py config/SConfig/packages/StgFEM.py config/SConfig/packages/X11.py config/SConfig/packages/__init__.py config/SConfig/packages/cmath.py config/SConfig/packages/dl.py config/SConfig/packages/libFAME.py config/SConfig/packages/libJPEG.py config/SConfig/packages/libPNG.py config/SConfig/packages/libTIFF.py config/SConfig/packages/libXML2.py config/SConfig/packages/libavcodec.py config/SConfig/packages/pcu.py config/packages/StgDomain.py config/packages/__init__.py
description:
Big cleanup on the build system including the
following improvements:
  - We now properly parse PETSc's 'petscconf'
    file for additional libraries we need. This
    should help when PETSc has been configured
    with 'download' options.
  - I've included a 'Project' package that contains
    a subset (currently) of the usual configuration
    options associated with a project (debugging,
    shared/static libs, etc) which allows us to
    remove the extra package I had to create for
    each individual project (StGermain, StgDomain,
    etc).
  - The individual projects can now be built
    independantly outside of a virtual repo.
  - StGermain now has a python script which can
    be loaded to extend SCons' build functionality.
    It includes an SCons builder for use with
    converting .meta files to .c files and some
    helper utilities for globbing and building
    source files.
  - The new unit test framework now has it's own
    script for extending SCons, much like StGermain,
    which adds an SCons builder for creating a
    unit test suite runner automatically.  This is
    quite nice as we don't have to modify any C
    code (except for actually writing the test
    itself, of course) OR modify any of the build
    scripts in order to add a new unit test to the
    project.


diff -r 085c968bf217 -r a8dba1da20c0 Makefile.system
--- a/Makefile.system	Thu Apr 03 07:05:15 2008 +0000
+++ b/Makefile.system	Mon Apr 07 00:36:43 2008 +0000
@@ -2,22 +2,22 @@ ifndef WHICH
 	WHICH=/usr/bin/which
 endif
 ifndef UNAME
-	UNAME=/usr/bin/uname
+	UNAME=/bin/uname
 endif
 ifndef UNAME_M
-	UNAME_M=/usr/bin/uname -m
+	UNAME_M=/bin/uname -m
 endif
 ifndef UNAME_R
-	UNAME_R=/usr/bin/uname -r
+	UNAME_R=/bin/uname -r
 endif
 ifndef MACHINE
 	MACHINE=i686
 endif
 ifndef KERNEL_RELEASE
-	KERNEL_RELEASE=2.6.22-gentoo-r5
+	KERNEL_RELEASE=2.6.22-14-generic
 endif
 ifndef UNAME_S
-	UNAME_S=/usr/bin/uname -s
+	UNAME_S=/bin/uname -s
 endif
 ifndef SYSTEM
 	SYSTEM=Linux
@@ -221,7 +221,7 @@ ifndef DL_INCLUDES
 	DL_INCLUDES=-I/usr/include
 endif
 ifndef NOPYTHON
-	NOPYTHON=
+	NOPYTHON=1
 endif
 ifndef DOXYGEN
 	DOXYGEN=/usr/bin/doxygen
@@ -275,7 +275,7 @@ ifndef REGRESSTOR_URL
 	REGRESSTOR_URL=http://localhost/~alan/cgi-bin/RegresstorServices/Regresstor.cgi
 endif
 ifndef STGERMAIN_DIR
-	STGERMAIN_DIR=/home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/build
+	STGERMAIN_DIR=/home/luke/VPAC/stgUnderworld/build
 endif
 ifndef OPTIONS
 	OPTIONS=
@@ -284,19 +284,19 @@ ifndef USE_RUN_LONG_TESTS
 	USE_RUN_LONG_TESTS=
 endif
 ifndef PROJ_ROOT
-	PROJ_ROOT=/home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/StgDomain
+	PROJ_ROOT=/home/luke/VPAC/stgUnderworld/StgDomain
 endif
 ifndef BLD_DIR
-	BLD_DIR=/home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/build
+	BLD_DIR=/home/luke/VPAC/stgUnderworld/build
 endif
 ifndef PREFIX_DIR
 	PREFIX_DIR=
 endif
 ifndef EXPORT_DIR
-	EXPORT_DIR=/home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/build
+	EXPORT_DIR=/home/luke/VPAC/stgUnderworld/build
 endif
 ifndef TMP_DIR
-	TMP_DIR=/home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/build/tmp
+	TMP_DIR=/home/luke/VPAC/stgUnderworld/build/tmp
 endif
 ifndef BIN_DIR
 	BIN_DIR=${EXPORT_DIR}/bin
@@ -308,7 +308,7 @@ ifndef INC_DIR
 	INC_DIR=${EXPORT_DIR}/include
 endif
 ifndef TST_DIR
-	TST_DIR=/home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/build/tests
+	TST_DIR=/home/luke/VPAC/stgUnderworld/build/tests
 endif
 ifndef PYB_DIR
 	PYB_DIR=${EXPORT_DIR}/Python
@@ -327,7 +327,7 @@ ifndef MAKEFILE_FIND_SUBDIRS
 	MAKEFILE_FIND_SUBDIRS=$(shell ${FIND_SUBDIRS})
 endif
 ifndef GET_MODNAME
-	GET_MODNAME=basename /home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/StGermain
+	GET_MODNAME=basename /home/luke/VPAC/stgUnderworld/StGermain
 endif
 ifndef MAKEFILE_GET_MODNAME
 	MAKEFILE_GET_MODNAME=$(shell ${GET_MODNAME})
@@ -336,7 +336,7 @@ ifndef MAKEFILE_CHECK_DEPENDENCIES
 	MAKEFILE_CHECK_DEPENDENCIES=$(foreach DEP,${DEPENDS},$(shell cd ${LIB_DIR} && if test -z `find . -name ${PROJECT}${DEP}*` ; then echo Compiling dependency: ${DEP} 1>&2 && cd ${PROJ_ROOT}/src && if test ! -z `find . -type d -name ${DEP}` ; then cd `find . -type d -name ${DEP}` && make 1>&2 ; else echo Cannot find dependency: ${DEP} 1>&2 ; fi ; fi ) )
 endif
 ifndef STGERMAIN_DIR
-	STGERMAIN_DIR=/home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/build
+	STGERMAIN_DIR=/home/luke/VPAC/stgUnderworld/build
 endif
 ifndef STGERMAIN_INCDIR
 	STGERMAIN_INCDIR=${STGERMAIN_DIR}/include
@@ -393,40 +393,40 @@ ifndef XML_INCLUDES
 	XML_INCLUDES=-I/usr/include/libxml2
 endif
 ifndef XML_LIBS
-	XML_LIBS=-L/usr/lib -lxml2 -lz -lm
+	XML_LIBS=-L/usr/lib -lxml2
 endif
 ifndef MPI_DIR
-	MPI_DIR=/usr/local/mpich-1.2.6-gcc34-shmem
+	MPI_DIR=/usr/local/mpich2-1.0.6
 endif
 ifndef MPI_BINDIR
-	MPI_BINDIR=/usr/local/mpich-1.2.6-gcc34-shmem/bin
+	MPI_BINDIR=/usr/local/mpich2-1.0.6/bin
 endif
 ifndef MPI_LIBDIR
-	MPI_LIBDIR=/usr/local/mpich-1.2.6-gcc34-shmem/lib
+	MPI_LIBDIR=/usr/local/mpich2-1.0.6/lib
 endif
 ifndef MPI_INCDIR
-	MPI_INCDIR=/usr/local/mpich-1.2.6-gcc34-shmem/include
+	MPI_INCDIR=/usr/local/mpich2-1.0.6/include
 endif
 ifndef MPI_INCLUDES
-	MPI_INCLUDES=-I/usr/local/mpich-1.2.6-gcc34-shmem/include
+	MPI_INCLUDES=-I/usr/local/mpich2-1.0.6/include
 endif
 ifndef MPI_IMPLEMENTATION
-	MPI_IMPLEMENTATION=mpich
+	MPI_IMPLEMENTATION=mpich2
 endif
 ifndef MPI_LIBFILES
-	MPI_LIBFILES=-lmpich -lpmpich   
+	MPI_LIBFILES=-lmpich      -lrt   
 endif
 ifndef MPI_RPATH
-	MPI_RPATH=-Xlinker -rpath -Xlinker /usr/local/mpich-1.2.6-gcc34-shmem/lib
+	MPI_RPATH=-Xlinker -rpath -Xlinker /usr/local/mpich2-1.0.6/lib
 endif
 ifndef MPI_LIBS
-	MPI_LIBS=-L/usr/local/mpich-1.2.6-gcc34-shmem/lib -lmpich -lpmpich   
+	MPI_LIBS=-L/usr/local/mpich2-1.0.6/lib -lmpich      -lrt   
 endif
 ifndef MPI_RUN_COMMAND
 	MPI_RUN_COMMAND=mpirun
 endif
 ifndef MPI_RUN
-	MPI_RUN=/usr/local/mpich-1.2.6-gcc34-shmem/bin/mpirun
+	MPI_RUN=/usr/local/mpich2-1.0.6/bin/mpirun
 endif
 ifndef MPI_NPROC
 	MPI_NPROC=-np
@@ -439,55 +439,12 @@ ifndef BLASLAPACK_LIBDIR
 	BLASLAPACK_LIBDIR=/usr/lib
 endif
 ifndef LAPACK_BLAS_LIBS
-	LAPACK_BLAS_LIBS=-L/usr/lib -llapack -lblas -lg2c
-endif
-ifndef PYTHON_DIR
-	PYTHON_DIR=/usr/
-endif
-ifndef PYTHON_VERSION
-	PYTHON_VERSION=2.4
-endif
-ifndef PYTHON_INCDIR
-	PYTHON_INCDIR=/usr//include/python2.4
-endif
-ifndef PYTHON_INCLUDES
-	PYTHON_INCLUDES=-I/usr//include/python2.4 -DHAVE_PYTHON
-endif
-ifndef PYTHON_BINDIR
-	PYTHON_BINDIR=/usr//bin
-endif
-ifndef PYTHON
-	PYTHON=/usr//bin/python
-endif
-ifndef PYTHON_LIB
-	PYTHON_LIB=python2.4
-endif
-ifndef PYTHON_LIBDIR
-	PYTHON_LIBDIR=/usr//lib
-endif
-ifndef PYTHON_MODDIR
-	PYTHON_MODDIR=/usr//lib/python2.4
-endif
-PYTHON_HAVE_SO_LIB=1
-ifndef PYTHON_COMPILEALL
-	PYTHON_COMPILEALL=/usr//bin/python /usr//lib/python2.4/compileall.py
-endif
-ifndef PYTHON_EXTERNAL_LIBS
-	PYTHON_EXTERNAL_LIBS=-lpthread -ldl -lutil
-endif
-ifndef PYTHON_LIBS
-	PYTHON_LIBS=-L/usr//lib -lpython2.4 -lpthread -ldl -lutil
-endif
-ifndef PYTHON_STATIC_LIB
-	PYTHON_STATIC_LIB=/usr//lib/config/libpython2.4.a
-endif
-ifndef HAVE_PYTHON
-	HAVE_PYTHON=1
+	LAPACK_BLAS_LIBS=-L/usr/lib -llapack -lblas
 endif
 ifndef APPS_XML_DIR
-	APPS_XML_DIR=/home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/build/lib/STGDOMAIN
-endif
-	EXPORT_INCLUDE_DIR=/home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/build/lib/StGermain/StgDomain
+	APPS_XML_DIR=/home/luke/VPAC/stgUnderworld/build/lib/STGDOMAIN
+endif
+	EXPORT_INCLUDE_DIR=/home/luke/VPAC/stgUnderworld/build/lib/StGermain/StgDomain
 	EXAMPLES_DIR=${EXPORT_DIR}/share/StgDomain
-	STG_INCLUDE_PATH=/home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/build/lib/StGermain
-	EXPORT_INCLUDE_DIR=/home/steve/Projects/ComputationalMechanics/ClubStGermain/v0.3-domainRework200709/build/lib/StGermain/StgDomain
+	STG_INCLUDE_PATH=/home/luke/VPAC/stgUnderworld/build/lib/StGermain
+	EXPORT_INCLUDE_DIR=/home/luke/VPAC/stgUnderworld/build/lib/StGermain/StgDomain
diff -r 085c968bf217 -r a8dba1da20c0 SConfigure
--- a/SConfigure	Thu Apr 03 07:05:15 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,577 +0,0 @@
-import os, sys
-Import('env opts')
-
-#
-# Helper functions.
-#
-
-def push_paths(cpp=[], lib=[]):
-    cpp = [cpp] if not isinstance(cpp, list) else cpp
-    cpp = [p for p in cpp if p is not None]
-    lib = [lib] if not isinstance(lib, list) else lib
-    lib = [p for p in lib if p is not None]
-    old = [list(env['CPPPATH']), list(env['LIBPATH'])]
-    env.AppendUnique(CPPPATH=cpp)
-    env.AppendUnique(LIBPATH=lib)
-    return old
-
-def pop_paths(old):
-    env.Replace(CPPPATH=old[0])
-    env.Replace(LIBPATH=old[1])
-
-#
-# Custom configuration checks.
-#
-
-def print_result(ctx, state, libs):
-    if state[0]:
-        if isinstance(state[0], list):
-            for d in state[0]:
-                ctx.Display('      %s\n' % d)
-        else:
-            ctx.Display('      %s\n' % state[0])
-    if state[1]:
-        if isinstance(state[1], list):
-            for d in state[1]:
-                ctx.Display('      %s\n' % d)
-        else:
-            ctx.Display('      %s\n' % state[1])
-    ctx.Display('   using library names:\n')
-    if libs:
-        if isinstance(libs, list):
-            ctx.Display('      %s' % libs[0])
-            for l in libs[1:]:
-                ctx.Display(', %s' % l)
-            ctx.Display('\n')
-        else:
-            ctx.Display('      %s\n' % libs)
-
-def CheckPackage(ctx, name, check, state_gen, lib_gen):
-    ctx.Message('Checking for package %s ... ' % name)
-
-    # If options given, use that. If fails then fatal.
-    for state in state_gen('options'):
-        old = push_paths(state[0], state[1])
-        for libs in lib_gen(state):
-            libs = [libs] if isinstance(libs, str) else libs
-            res = check(ctx, libs, state[1])
-            if res:
-                env['PACKAGES'][name] = (state, libs)
-                ctx.Result(res)
-                return res
-        pop_paths(old)
-        ctx.Result(res)
-        ctx.Display('  invalid options\n')
-        return res
-
-    # Try and link to package with no state modification.
-    for libs in lib_gen():
-        libs = [libs] if isinstance(libs, str) else libs
-        res = check(ctx, libs)
-        if res:
-            env['PACKAGES'][name] = (None, libs)
-            ctx.Result(res)
-            return res
-
-    # Try and extract package location from shell environment.
-    for state in state_gen('environment'):
-        old = push_paths(state[0], state[1])
-        for libs in lib_gen(state):
-            libs = [libs] if isinstance(libs, str) else libs
-            res = check(ctx, libs, state[1])
-            if res:
-                env['PACKAGES'][name] = (state, libs)
-                ctx.Result(res)
-                ctx.Display('   found using environment variables:\n')
-                print_result(ctx, state, libs)
-                return res
-        pop_paths(old)
-
-    # Cycle through default locations.
-    for state in state_gen('default'):
-        old = push_paths(state[0], state[1])
-        for libs in lib_gen(state):
-            libs = [libs] if isinstance(libs, str) else libs
-            res = check(ctx, libs, state[1])
-            if res:
-                env['PACKAGES'][name] = (state, libs)
-                ctx.Result(res)
-                ctx.Display('   found in default location:\n')
-                print_result(ctx, state, libs)
-                return res
-        pop_paths(old)
-
-    ctx.Result(res)
-
-def CheckFortranSymbol(ctx):
-    fSrc = """
-      Program Conftest
-      external method
-      integer i
-      call method(i)
-      stop
-      end
-"""
-    cSrc = """
-#include <stdio.h>
-void method(int *i){printf("FORTRAN_NORMAL");}
-void method_(int *i){printf("FORTRAN_SINGLE_TRAILINGBAR");}
-void method__(int *i){printf("FORTRAN_DOUBLE_TRAILINGBAR");}
-void METHOD(int *i){printf("FORTRAN_UPPERCASE");}
-"""
-    ctx.Message('Checking for fortran symbol type... ')
-
-    res = ctx.TryCompile(cSrc, '.c')
-    if not res:
-        ctx.Result(res)
-        return res
-    cObj = ctx.lastTarget
-
-    oldLINK = env['LINK'] if 'LINK' in env._dict else None
-    oldLINKFLAGS = env['LINKFLAGS'] if 'LINKFLAGS' in env._dict else None
-    oldLIBS = env['LIBS'] if 'LIBS' in env._dict else None
-    env['LINK'] = env['_FORTRAND']
-    env['LINKFLAGS'] = str(cObj)
-    env['LIBS'] = []
-    res = ctx.TryRun(fSrc, '.F')
-    env['LINK'] = oldLINK
-    env['LINKFLAGS'] = oldLINKFLAGS
-    env['LIBS'] = oldLIBS
-    if not res[0]:
-        ctx.Result(res[0])
-        return res[0]
-
-    env.Append(CPPDEFINES=[res[1]])
-    ctx.Result(res[0])
-    return res[0]
-
-#
-# Package configuration generators.
-#
-
-## MPICH ##
-
-def mpich_state_gen(type):
-    if type == 'options':
-        if 'mpichDir' in env._dict:
-            yield (os.path.join(env['mpichDir'], 'include'),
-                   os.path.join(env['mpichDir'], 'lib'))
-        elif 'mpichLibDir' in env._dict or 'mpichIncDir' in env._dict:
-            inc = env['mpichIncDir'] if 'mpichIncDir' in env._dict else None
-            lib = env['mpichLibDir'] if 'mpichLibDir' in env._dict else None
-            yield (inc, lib)
-    elif type == 'environment':
-        if 'MPI_DIR' in env['ENV']:
-            yield (os.path.join(env['ENV']['MPI_DIR'], 'include'),
-                   os.path.join(env['ENV']['MPI_DIR'], 'lib'))
-    elif type == 'default':
-        yield ('/usr/include/mpich', '/usr/lib')
-        yield ('/usr/local/mpich/include', '/usr/local/mpich/lib')
-
-def mpich_lib_gen(state=None):
-    yield ['mpich']
-    yield ['pmpich']
-    yield ['mpich', 'pmpich']
-    yield ['mpich', 'rt']
-    yield ['pmpich', 'rt']
-    yield ['mpich', 'pmpich', 'rt']
-
-def check_mpich(ctx, libs, libpath=None):
-    src = """
-#include<mpi.h>
-int main(int argc, char** argv) {
-MPI_Init(&argc, &argv);
-MPI_Finalize();
-return (MPI_VERSION == 2) ? 0 : 1;
-}
-"""
-    old = list(env['LIBS']), list(env['RPATH'])
-    env.Append(LIBS=libs)
-    env.Append(RPATH=libpath)
-    res = ctx.TryRun(src, '.c')[0]
-    env.Replace(LIBS=old[0])
-    env.Replace(RPATH=old[1])
-    if not res:
-        return res
-
-    env.AppendUnique(LIBS=libs)
-    return res
-
-## libXML2 ##
-
-def libxml2_state_gen(type):
-    if type == 'options':
-        if 'libxml2Dir' in env._dict:
-            yield (os.path.join(env['libxml2Dir'], 'include'),
-                   os.path.join(env['libxml2Dir'], 'lib'))
-        elif 'libxml2LibDir' in env._dict or 'libxml2IncDir' in env._dict:
-            inc = env['libxml2IncDir'] \
-                if 'libxml2IncDir' in env._dict else None
-            lib = env['libxml2LibDir'] \
-                if 'libxml2LibDir' in env._dict else None
-            yield (inc, lib)
-    elif type == 'environment':
-        if 'LIBXML2_DIR' in env['ENV']:
-            yield (os.path.join(env['ENV']['LIBXML2_DIR'], 'include'),
-                   os.path.join(env['ENV']['LIBXML2_DIR'], 'lib'))
-    elif type == 'default':
-        yield ('/usr/include/libxml2', None)
-        yield ('/usr/include/libxml2', '/usr/lib')
-        yield ('/usr/local/libxml2/include', '/usr/local/libxml2/lib')
-
-def libxml2_lib_gen(state=None):
-    yield ['libxml2']
-
-def check_libxml2(ctx, libs, libpath=None):
-    src = """
-#include<libxml/xmlIO.h>
-int main(int argc, char** argv) {
-return 0;
-}
-"""
-    old = list(env['LIBS'])
-    env.Replace(LIBS=libs)
-    res = ctx.TryLink(src, '.c')
-    env.Replace(LIBS=old)
-    if not res:
-        return res
-
-    env.AppendUnique(LIBS=libs)
-    return res
-
-## StGermain ##
-
-def stgermain_state_gen(type):
-    if type == 'options':
-        if 'stgermainDir' in env._dict:
-            yield (os.path.join(env['stgermainDir'], 'include'),
-                   os.path.join(env['stgermainDir'], 'lib'))
-        elif 'stgermainLibDir' in env._dict or 'stgermainIncDir' in env._dict:
-            inc = env['stgermainIncDir'] \
-                if 'stgermainIncDir' in env._dict else None
-            lib = env['stgermainLibDir'] \
-                if 'stgermainLibDir' in env._dict else None
-            yield (inc, lib)
-    elif type == 'environment':
-        if 'STGERMAIN_DIR' in env['ENV']:
-            yield (os.path.join(env['ENV']['STGERMAIN_DIR'], 'include'),
-                   os.path.join(env['ENV']['STGERMAIN_DIR'], 'lib'))
-    elif type == 'default':
-        yield ('../StGermain/build/include', '../StGermain/build/lib')
-
-def stgermain_lib_gen(state=None):
-    yield ['StGermain']
-
-def check_stgermain(ctx, libs, libpath=None):
-    src = """
-#include<StGermain/StGermain.h>
-int main(int argc, char** argv) {
-StGermain_Init(&argc, &argv);
-StGermain_Finalise();
-return 0;
-}
-"""
-    old = list(env['LIBS'])
-    env.Replace(LIBS=libs)
-    res = ctx.TryLink(src, '.c')
-    env.Replace(LIBS=old)
-    if not res:
-        return res
-
-    env.AppendUnique(LIBS=libs)
-    return res
-
-## StgDomain ##
-
-def stgdomain_state_gen(type):
-    if type == 'options':
-        if 'stgdomainDir' in env._dict:
-            yield (os.path.join(env['stgdomainDir'], 'include'),
-                   os.path.join(env['stgdomainDir'], 'lib'))
-        elif 'stgdomainLibDir' in env._dict or 'stgdomainIncDir' in env._dict:
-            inc = env['stgdomainIncDir'] \
-                if 'stgdomainIncDir' in env._dict else None
-            lib = env['stgdomainLibDir'] \
-                if 'stgdomainLibDir' in env._dict else None
-            yield (inc, lib)
-    elif type == 'environment':
-        if 'STGDOMAIN_DIR' in env['ENV']:
-            yield (os.path.join(env['ENV']['STGDOMAIN_DIR'], 'include'),
-                   os.path.join(env['ENV']['STGDOMAIN_DIR'], 'lib'))
-    elif type == 'default':
-        yield ('../StgDomain/build/include', '../StgDomain/build/lib')
-
-def stgdomain_lib_gen(state=None):
-    yield ['StgDomain']
-
-def check_stgdomain(ctx, libs, libpath=None):
-    src = """
-#include<StGermain/StGermain.h>
-#include<StgDomain/StgDomain.h>
-int main(int argc, char** argv) {
-return 0;
-}
-"""
-    old = list(env['LIBS'])
-    env.Append(LIBS=libs)
-    res = ctx.TryLink(src, '.c')
-    env.Replace(LIBS=old)
-    if not res:
-        return res
-
-    env.AppendUnique(LIBS=libs)
-    return res
-
-## lapack ##
-
-def lapack_state_gen(type):
-    if type == 'options':
-        if 'lapackDir' in env._dict:
-            yield (None, os.path.join(env['lapackDir'], 'lib'))
-        elif 'lapackLibDir' in env._dict:
-            yield (None, env['lapackLibDir'])
-    elif type == 'environment':
-        if 'LAPACK_DIR' in env['ENV']:
-            yield (None, os.path.join(env['ENV']['LAPACK_DIR'], 'lib'))
-        if 'LAPACK_LIB_DIR' in env['ENV']:
-            yield (None, env['ENV']['LAPACK_LIB_DIR'])
-    elif type == 'default':
-        yield (None, '/usr/lib')
-
-def lapack_lib_gen(state=None):
-    yield ['lapack']
-
-def check_lapack(ctx, libs, libpath=None):
-    src = """
-int main(int argc, char** argv) {
-return 0;
-}
-"""
-    old = list(env['LIBS'])
-    env.Replace(LIBS=libs)
-    res = ctx.TryLink(src, '.c')
-    env.Replace(LIBS=old)
-    if not res:
-        return res
-
-    env.AppendUnique(LIBS=libs)
-    return res
-
-## PETSc ##
-
-def petsc_arch(base_dir):
-    petscconf = os.path.join(base_dir, 'bmake', 'petscconf')
-    if not os.path.exists(petscconf):
-        return None
-    f = file(petscconf, 'r')
-    arch = f.readline().split('=')[1][:-1]
-    f.close()
-    return arch
-
-def petsc_x11_libs(base_dir, arch):
-    petscconf = os.path.join(base_dir, 'bmake', arch, 'petscconf')
-    if not os.path.exists(petscconf):
-        return None
-    f = file(petscconf, 'r')
-    libs = []
-    for l in f.readlines():
-        if l[:7] == 'X11_LIB':
-            libs = l.split('=')[1].strip().split(' ')
-            libs = [lib[2:] for lib in libs]
-            break
-    f.close()
-    return libs
-
-def petsc_state_gen(type):
-    if type == 'options':
-        if 'petscDir' in env._dict:
-            arch = petsc_arch(env['petscDir'])
-            if arch:
-                yield ([os.path.join(env['petscDir'], 'include'),
-                        os.path.join(env['petscDir'], 'bmake', arch)],
-                       os.path.join(env['petscDir'], 'lib', arch),
-                       env['petscDir'],
-                       arch)
-    elif type == 'environment':
-        if 'PETSC_DIR' in env['ENV']:
-            dir = env['ENV']['PETSC_DIR']
-            if 'PETSC_ARCH' in env['ENV']:
-                arch = env['ENV']['PETSC_ARCH']
-            else:
-                arch = petsc_arch(dir)
-            if arch:
-                yield ([os.path.join(dir, 'include'),
-                        os.path.join(dir, 'bmake', arch)],
-                       os.path.join(dir, 'lib', arch),
-                       dir,
-                       arch)
-    elif type == 'default':
-        dir = '/usr/local/petsc'
-        arch = petsc_arch(dir)
-        if arch:
-            yield ([os.path.join(dir, 'include'),
-                    os.path.join(dir, 'bmake', arch)],
-                   os.path.join(dir, 'lib', arch),
-                   dir,
-                   arch)
-
-def petsc_lib_gen(state=None):
-    if state:
-        libs = petsc_x11_libs(state[2], state[3])
-    else:
-        libs = []
-    yield ['petsc', 'petscvec', 'petscmat', 'petscksp',
-           'petscsnes', 'petscdm'] + libs
-
-def check_petsc(ctx, libs, libpath=None):
-    src = """
-#include <petsc.h>
-#include <petscvec.h>
-#include <petscmat.h>
-#include <petscksp.h>
-int main(int argc, char** argv) {
-/*PetscInitialize();*/
-/*PetscFinalise();*/
-if( (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR < 3) ||
-    (PETSC_VERSION_MAJOR != 2) )
-printf("wrong version, need at least 2.3.2");
-return 0;
-}
-"""
-    old = list(env['LIBS']), list(env['RPATH'])
-    env.Append(LIBS=libs)
-    env.Append(RPATH=libpath)
-    res = ctx.TryRun(src, '.c')
-    env.Replace(LIBS=old[0])
-    env.Replace(RPATH=old[1])
-    if not res[0] or res[1] != '':
-        ctx.Log('  ! Output: ' + res[1] + '\n')
-        return 0
-
-    env.AppendUnique(LIBS=libs)
-    return res[0]
-
-#
-# Do configuration.
-#
-
-if not env.GetOption('clean'):
-    cfg = Configure(env,
-                    custom_tests={'CheckPackage':
-                                      CheckPackage,
-                                  'CheckFortranSymbol':
-                                      CheckFortranSymbol})
-
-    # Add a member to 'env' for storing package results.
-    env['PACKAGES'] = {}
-
-    #
-    # Check for the C math library.
-    #
-
-    if not cfg.CheckLib('m'):
-        print "Couldn't find the C standard math libaray."
-        env.Exit()
-
-    #
-    #
-    #
-
-    if not cfg.CheckPackage('MPICH', check_mpich,
-                            mpich_state_gen, mpich_lib_gen):
-        env.Exit()
-    opts.Save('config.cache', env)
-
-    #
-    # Check for libXML2.
-    #
-
-    if not cfg.CheckPackage('libXML2', check_libxml2,
-                            libxml2_state_gen, libxml2_lib_gen):
-        env.Exit()
-    opts.Save('config.cache', env)
-
-    #
-    # Check for an implementation of lapack
-    #
-
-    if not cfg.CheckPackage('lapack', check_lapack,
-                            lapack_state_gen, lapack_lib_gen):
-        env.Exit()
-    opts.Save('config.cache', env)
-
-    #
-    # Check for an implementation of PETSc
-    #
-
-    if not cfg.CheckPackage('PETSc', check_petsc,
-                            petsc_state_gen, petsc_lib_gen):
-        env.Exit()
-    env.Append(CPPDEFINES='HAVE_PETSC')
-    opts.Save('config.cache', env)
-
-    #
-    # Check for StGermain.
-    #
-
-    if not cfg.CheckPackage('StGermain', check_stgermain,
-                            stgermain_state_gen, stgermain_lib_gen):
-        env.Exit()
-    opts.Save('config.cache', env)
-
-    #
-    # Check for StgDomain.
-    #
-
-    if not cfg.CheckPackage('StgDomain', check_stgdomain,
-                            stgdomain_state_gen, stgdomain_lib_gen):
-        env.Exit()
-    opts.Save('config.cache', env)
-
-    #
-    # Check Fortran symbol type.
-    #
-
-    if not cfg.CheckFortranSymbol():
-        print 'Fortran symbol check failed.'
-        env.Exit()
-
-    #
-    # Extract revision number.
-    #
-
-    svnPath = os.path.join('.svn', 'entries')
-    if not os.path.exists(svnPath):
-        print "\nYou appear to be building the code from something"
-        print "that wasn't checked out of a repository. Bummer."
-        env.Exit()
-    f = file(svnPath, 'r')
-    f.readline()
-    f.readline()
-    f.readline()
-    ver = env['ESCAPE']('"' + str(int(f.readline())) + '"')
-    env.Append(CPPDEFINES=[('VERSION', ver)])
-    f.close()
-
-    #
-    # Add module extension to build commands.
-    #
-
-    ext = env['ESCAPE']('"' + env['SHLIBSUFFIX'][1:] + '"')
-    env.Append(CPPDEFINES=[('MODULE_EXT', ext)])
-
-    #
-    # Add the library directory.
-    #
-
-    libDir = os.path.join(Dir('.').abspath, 'build', 'lib')
-    libDir = env['ESCAPE']('"' + libDir + '"')
-    env.Append(CPPDEFINES=[('LIB_DIR', libDir)])
-
-    #
-    # Setup the dynamic library search paths.
-    #
-
-    env.Append(RPATH=[os.path.join(Dir('.').abspath, 'build', 'lib')])
-
-    env = cfg.Finish()
diff -r 085c968bf217 -r a8dba1da20c0 SConscript
--- a/SConscript	Thu Apr 03 07:05:15 2008 +0000
+++ b/SConscript	Mon Apr 07 00:36:43 2008 +0000
@@ -2,29 +2,50 @@ Import('env')
 Import('env')
 
 env = env.Copy()
-env.AppendUnique(CPPPATH=[os.path.join(env['buildPath'], # Add StgDomain include path.
-                                       'include',
-                                       'StgDomain')])
-env.project_name = 'StgDomain' # Need a project name.
-env.clear_all() # ... so that our structures are ready.
+env.AppendUnique(CPPPATH=[env.get_build_path('include/StgDomain')])
 
-env.build_directory('Geometry')
-env.build_directory('Shape')
-env.build_directory('Mesh')
-env.build_directory('Utils')
-env.build_directory('Swarm')
+# Collect our inputs from the directory structure.
+bases = ['Geometry', 'Shape', 'Mesh', 'Utils', 'Swarm']
+src_objs = []
+suite_hdrs = []
+suite_objs = []
+for base in bases:
+    env.build_files(env.glob(base + '/src/*.def'), 'include/StgDomain/' + base)
+    env.build_headers(env.glob(base + '/src/*.h'), 'include/StgDomain/' + base)
+    src_objs += env.build_sources(env.glob(base + '/src/*.c'), 'StgDomain/' + base)
+    src_objs += env.build_metas(env.glob(base + '/src/*.meta'), 'StgDomain/' + base)
+    suite_hdrs += env.glob(base + '/tests/*Suite.h')
+    suite_objs += env.build_sources(env.glob(base + '/tests/*Suite.c'), 'StgDomain/' + base)
 
-env.build_headers(env.glob('libStgDomain/src/*.h'), 'StgDomain')
-env.build_objects(env.glob('libStgDomain/src/*.c'), 'libStgDomain')
-env.build_metadata(env.glob('libStgDomain/src/*.meta'), 'libStgDomain')
+env.build_headers(env.glob('libStgDomain/src/*.h'), 'include/StgDomain')
+src_objs += env.build_sources(env.glob('libStgDomain/src/*.c'), 'StgDomain/libStgDomain')
+src_objs += env.build_sources(env.glob('libStgDomain/src/*.meta'), 'StgDomain/libStgDomain')
 
-env.build_library(env.get_hnodes(env.SharedObject), 'StgDomain')
+# Build library.
+if env['static_libraries']:
+    env.Library(env.get_build_path('lib/StgDomain'), src_objs)
+if env['shared_libraries']:
+    env.SharedLibrary(env.get_build_path('lib/StgDomain'), src_objs)
 
-env.build_objects(env.glob('libStgDomain/Toolbox/*.c'), 'Toolbox')
-env.build_metadata(env.glob('libStgDomain/Toolbox/*.meta'), 'Toolbox')
-env.build_library(env.get_hnodes(env.SharedObject, 'Toolbox'),
-                  'StgDomain_Toolboxmodule', ['StgDomain'],
-                  True)
+# Build toolbox.
+if env['shared_libraries']:
+    objs = env.build_sources(env.glob('libStgDomain/Toolbox/*.c'),
+                             'StgDomain/libStgDomain/Toolbox')
+    objs += env.build_metas(env.glob('libStgDomain/Toolbox/*.meta'),
+                            'StgDomain/libStgDomain/Toolbox')
+    env.SharedLibrary(env.get_target_name('lib/StgDomain_Toolboxmodule'), objs,
+                      SHLIBPREFIX='',
+                      LIBPREFIXES=[env['LIBPREFIXES']] + [''],
+                      LIBS=['StgDomain'] + env.get('LIBS', []))
 
-env.build_tests(env.glob('libStgDomain/tests/test*.c'),
-                'StgDomain', libs='StgDomain')
+# Build unit test runner.
+env['PCURUNNERINIT'] = ''
+env['PCURUNNERSETUP'] = """StGermain_Init( &argc, &argv );
+   StgDomain_Init( &argc, &argv );"""
+env['PCURUNNERTEARDOWN'] = """StgDomain_Finalise();
+   StGermain_Finalise();"""
+runner_src = env.PCUSuiteRunner(env.get_build_path('StgDomain/testStgDomain.c'), suite_hdrs)
+runner_obj = env.SharedObject(runner_src)
+env.Program(env.get_build_path('bin/testStgDomain'),
+            runner_obj + suite_objs,
+            LIBS=['StgDomain', 'pcu'] + env.get('LIBS', []))
diff -r 085c968bf217 -r a8dba1da20c0 SConstruct
--- a/SConstruct	Thu Apr 03 07:05:15 2008 +0000
+++ b/SConstruct	Mon Apr 07 00:36:43 2008 +0000
@@ -1,36 +1,44 @@ import os, sys
-import os, sys
+import sys, os
 
-# Source the configuration scripts.
 sys.path.insert(0, os.path.abspath(os.path.join(os.getcwd(), 'config')))
+import SConfig
 SConscript('config/SConfig/SConscript')
 
-# Create our base construction environment.
-env = Environment()
+#
+# CUSTOMISE THE ENVIRONMENT HERE.
+#
 
-# Configuring or building? Or helping?
+env = Environment(ENV=os.environ)
+env['_abspath'] = lambda x: File(x).abspath # Needed by Darwin.
+
+# Determine whether we are configuring, helping or building.
 if 'config' in COMMAND_LINE_TARGETS or 'help' in COMMAND_LINE_TARGETS:
-    import packages
-    opts = Options('config.cache') # Create our options database.
 
-    # Setup all the packages we want configured.
-    env.Package(packages.StgDomain, opts)
-    env.setup_packages(opts)
+    #
+    # INSERT CONFIGURATION HERE.
+    #
 
-    if 'help' in COMMAND_LINE_TARGETS:
-        env.Alias('help', '.')
-        print opts.GenerateHelpText(env)
+    proj = env.Package(SConfig.Project)
+    proj.dependency(SConfig.packages.StGermain)
+    proj.dependency(SConfig.packages.BlasLapack)
+    proj.dependency(SConfig.packages.HDF5, False)
+    env.configure_packages()
 
-    else:
-        env.configure_packages(opts)
+    # Need to define the extension for shared libraries as well
+    # as the library directory.
+    ext = env['ESCAPE']('"' + env['SHLIBSUFFIX'][1:] + '"')
+    lib_dir = env['ESCAPE']('"' + os.path.abspath(env['build_dir']) + '/lib' + '"')
+    env.AppendUnique(CPPDEFINES=[('MODULE_EXT', ext), ('LIB_DIR', lib_dir)])
+
+    # Save results.
+    env.save_config()
 
 else:
-    # Prepare our construction environment.
-    env.load_config('config.cfg') # Load configuration.
-    SConscript('StgSCons', exports='env') # Setup our StG specific utils.
-    if env['staticLibraries']: # Static libs or shared?
-        env.library_builder = env.StaticLibrary
-    else:
-        env.library_builder = env.SharedLibrary
-    env.Default(env['buildPath']) # Needed for different build paths.
+    # Load configuration.
+    env.load_config()
+
+    #
+    # INSERT TARGETS HERE.
+    #
 
     SConscript('SConscript', exports='env')
diff -r 085c968bf217 -r a8dba1da20c0 StgSCons
--- a/StgSCons	Thu Apr 03 07:05:15 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,290 +0,0 @@
-import os, glob as pyglob, platform, pickle
-from SCons.Script.SConscript import SConsEnvironment
-
-#
-# Setup some basic path utilities.
-#
-
-# Globbing for hierarchical SCons scripts.
-def glob(env, ptrn):
-    if not os.path.isabs(ptrn):
-        old = os.getcwd()
-        os.chdir(Dir('.').srcnode().abspath)
-        res = pyglob.glob(ptrn)
-        os.chdir(old)
-    else:
-        res = pyglob.glob(ptrn)
-    return res
-
-# Normalise an SCons path to the project root.
-def norm_path(env, path):
-    cur_dir = env.Dir('.').srcnode().path
-    if path[0] != '#':
-        path = os.path.join(cur_dir, path)
-    else:
-        path = path[1:]
-    return path
-
-# Copy a file immediately.
-def copy_file(env, dst, src):
-    dst = env.norm_path(dst)
-    old = os.getcwd()
-    os.chdir(env.GetLaunchDir())
-    if not File(os.path.abspath(dst)).is_up_to_date():
-        src = env.norm_path(src)
-        dst_dir = os.path.dirname(dst)
-        if not os.path.exists(dst_dir):
-            Execute(Mkdir(dst_dir))
-        Execute(Copy(dst, src))
-        os.chdir(old)
-
-# Add to the SCons main class.
-SConsEnvironment.glob = glob
-SConsEnvironment.norm_path = norm_path
-SConsEnvironment.copy_file = copy_file
-
-#
-# Setup the hierarchical build stuff.
-#
-
-def hbuild(env, builder, hpath, store=True, *args, **kw):
-    nodes = builder(*args, **kw)
-    if store:
-        if builder not in env.hnodes:
-            env.hnodes[builder] = {}
-        place = env.hnodes[builder]
-        if '.' not in place:
-            place['.'] = []
-        place['.'].append(nodes)
-        for h in hpath.split(os.path.sep):
-            if h not in place:
-                place[h] = {}
-            place = place[h]
-            if '.' not in place:
-                place['.'] = []
-            place['.'].append(nodes)
-    return nodes
-
-def get_hnodes(env, builder, hpath=None):
-    place = env.hnodes[builder]
-    if hpath:
-        for h in hpath.split(os.path.sep):
-            place = place[h]
-    return place['.']
-
-def hclear(env):
-    env.hnodes = {}
-
-SConsEnvironment.hbuild = hbuild
-SConsEnvironment.get_hnodes = get_hnodes
-SConsEnvironment.hclear = hclear
-
-#
-# Helper functions.
-#
-
-def to_list(var):
-    if isinstance(var, list):
-        return var
-    else:
-        return [var]
-
-def copy_includes(env, files, dst, inc_nodes, force=False):
-    files = to_list(files)
-    dst = os.path.join(env['buildPath'], dst)
-    for i in files:
-        node = env.Install(dst, i)
-        inc_nodes.append(node)
-        if force:
-            dst_path = os.path.join(dst, os.path.basename(i))
-            env.copy_file(dst_path, i)
-
-#
-# Builder helpers.
-#
-
-def get_target_name(env, src, suffix='.c'):
-    return os.path.join(env['buildPath'], env.project_name, src[:-len(suffix)])
-
-def build_defines(env, files, dst):
-    copy_includes(env, files, os.path.join('include', dst), 
-                  env.def_nodes, True)
-
-def build_headers(env, files, dst, force_copy=False):
-    copy_includes(env, files, os.path.join('include', dst),
-                  env.hdr_nodes, force_copy)
-
-def build_xmls(env, files, dst, force_copy=False):
-    copy_includes(env, files, os.path.join('lib', dst),
-                  env.hdr_nodes, force_copy)
-
-def build_objects(env, files, hpath, store=True):
-    files = to_list(files)
-    nodes = []
-    name = env.project_name + ''.join(hpath.split(os.path.sep))
-    mod = [('CURR_MODULE_NAME', env['ESCAPE']('"' + name + '"'))]
-    for src in files:
-        tgt = get_target_name(env, src)
-        cur_node = env.hbuild(env.SharedObject, hpath, store,
-                              target=tgt, source=src,
-                              CPPDEFINES=env['CPPDEFINES'] + mod)
-        nodes.append(cur_node)
-    return nodes
-
-def build_metadata(env, files, hpath):
-    files = to_list(files)
-    nodes = []
-    for m in files:
-        tgt = get_target_name(env, m, '.meta')
-        src = env.Meta(target=tgt, source=m)
-        tgt = src[0].path[:-2]
-        cur_node = env.hbuild(env.SharedObject, hpath,
-                              target=tgt, source=src)
-        nodes.append(cur_node)
-    return nodes
-
-def build_library(env, objs, name, libs=[], force_name=False):
-    objs = to_list(objs)
-    dst = os.path.join(env['buildPath'], 'lib', name)
-    if force_name:
-        cur_node = env.library_builder(
-            dst, objs,
-            SHLIBPREFIX='',
-            LIBPREFIXES=[env['LIBPREFIXES']] + [''],
-	    LIBS=libs + env.get('LIBS', []))
-    else:
-        cur_node = env.library_builder(dst, objs, LIBS=libs + env.get('LIBS', []))
-    env.lib_nodes.insert(0, cur_node)
-
-def build_tests(env, files, name, sup_objs=[], libs=None):
-    if not libs:
-        libs = env.lib_nodes
-    files = to_list(files)
-    sup_objs = to_list(sup_objs)
-    nodes = env.test_nodes
-    mod = [('CURR_MODULE_NAME', env['ESCAPE']('"' + name + '"'))]
-    l = to_list(libs)
-    for src in files:
-        tgt = get_target_name(env, src)
-        obj_node = env.SharedObject(tgt, src,
-                                    CPPDEFINES=env.get('CPPDEFINES') + mod)
-        dst = os.path.join(env['buildPath'], 'tests',
-                           os.path.splitext(os.path.basename(src))[0])
-        cur_node = env.Program(dst, obj_node + sup_objs,
-                               LIBS=l + env.get('LIBS', []))
-        nodes.append(cur_node)
-
-def build_directory(env, dir, extra_objs=[],
-                    test_libs=None, build_lib=True):
-    if not test_libs:
-        test_libs = env.lib_nodes
-    test_libs = to_list(test_libs)
-    extra_objs = to_list(extra_objs)
-    srcDir = os.path.join(dir, 'src')
-    tstDir = os.path.join(dir, 'tests')
-    hdrDir = os.path.join(env.project_name, dir)
-    mod = ''.join(hdrDir.split(os.path.sep))
-
-    env.build_defines(env.glob(os.path.join(srcDir, '*.def')), hdrDir)
-    env.build_headers(env.glob(os.path.join(srcDir, '*.h')), hdrDir)
-    env.build_metadata(env.glob(os.path.join(srcDir, '*.meta')), dir)
-    env.build_objects(env.glob(os.path.join(srcDir, '*.c')), dir)
-    if build_lib:
-        objs = env.get_hnodes(env.SharedObject, dir)
-        env.build_library(objs + extra_objs, mod)
-    if os.path.exists(tstDir):
-        tst_files = env.glob(os.path.join(tstDir, 'test*.c'))
-        sup_gen = env.glob(os.path.join(tstDir, '*.c'))
-        sup_files = [f for f in sup_gen if f not in tst_files]
-        sup = env.build_objects(sup_files, dir, False)
-        env.build_tests(tst_files, mod,
-                        sup_objs=sup,
-                        libs=test_libs + [mod])
-
-def build_plugin(env, dir, hpath, prefix=True):
-    name = hpath.split(os.path.sep)
-    if prefix:
-        name = [env.project_name] + name
-    name = '_'.join(name) + 'module'
-    hdr_dir = os.path.join(env.project_name, hpath.split(os.path.sep)[-1])
-
-    env.build_headers(env.glob(os.path.join(dir, '*.h')), hdr_dir)
-    objs = env.build_objects(env.glob(os.path.join(dir, '*.c')),
-                         hpath, False)
-    env.build_library(objs, name, [env.project_name], True)
-
-def clear_all(env):
-    env.hclear()
-    env.def_nodes = []
-    env.hdr_nodes = []
-    env.lib_nodes = []
-    env.test_nodes = []
-
-SConsEnvironment.build_defines = build_defines
-SConsEnvironment.build_headers = build_headers
-SConsEnvironment.build_xmls = build_xmls
-SConsEnvironment.build_objects = build_objects
-SConsEnvironment.build_metadata = build_metadata
-SConsEnvironment.build_library = build_library
-SConsEnvironment.build_tests = build_tests
-SConsEnvironment.build_directory = build_directory
-SConsEnvironment.build_plugin = build_plugin
-SConsEnvironment.clear_all = clear_all
-
-#
-# Custom builders.
-#
-
-# Builder for generating meta files (courtesy of Walter Landry).
-def create_meta(target, source, env):
-    output_file = file(str(target[0]),'wb')
-    output_file.write("#define XML_METADATA \"")
-    xml_file = file(str(source[0]))
-    xml_lines = xml_file.readlines()
-    for l in xml_lines:
-        output_file.write(l.replace('\"','\\\"')[:-1])
-    output_file.write("\"\n#define COMPONENT_NAME ")
-    for l in xml_lines:
-        start=l.find('<param name="Name">')
-        if start!=-1:
-            end=l.find('<',start+19)
-            if end==-1:
-                raise RunTimeError('Malformed XML file.  The file '
-                                   + str(source[0])
-                                   + ' does not close off <param name="Name"> on the same line.')
-            output_file.write(l[start+19:end])
-            output_file.write("\n")
-            break
-    output_file.write('''
-#define Stg_Component_Stringify( str ) #str
-
-/* Note: Two macros are used to resolve the the extra macro level */
-#define Stg_Component_Metadata_Create( name ) Stg_Component_Metadata_Create_Macro( name )
-#define Stg_Component_Metadata_Create_Macro( name ) \
-	const char* name ##_Meta = XML_METADATA; \
-	const char* name ##_Name = #name; \
-	const char* name ##_Version = VERSION; \
-	const char* name ##_Type_GetMetadata() { /* hack...won't be needed when hierarchy rollout is done */\
-		return name ##_Meta; \
-	} \
-	const char* name ##_GetMetadata() { \
-		return name ##_Meta; \
-	} \
-	const char* name ##_GetName() { \
-		return name ##_Name; \
-	} \
-	const char* name ##_GetVersion() { \
-		return name ##_Version; \
-	}
-
-#if defined(COMPONENT_NAME) && defined(VERSION) && defined(XML_METADATA)
-	Stg_Component_Metadata_Create( COMPONENT_NAME )
-#endif
-''')
-
-def gen_meta_suffix(env, sources):
-    return "-meta.c"
-
-Import('env')
-env['BUILDERS']['Meta']=Builder(action=create_meta,src_suffix="meta",
-                                suffix=gen_meta_suffix,single_source=True)
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/Node.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/Node.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,199 @@
+import os
+
+class Node(object):
+    def __init__(self, scons_env, scons_opts, required=False):
+        # Override to give a different name.
+        self.name = self.__module__.split('.')[-1]
+
+        # Option variables.
+        self.command_name = self.name.lower()
+        self.environ_name = self.name.upper()
+        self.option_map = {} # Maps command-line options to their environment alternatives.
+
+        # Override with a list of methods to run during configuration.
+        self.checks = []
+
+        # Will be set after configuration.
+        self.configured = False
+        self.result = False
+
+        # Private stuff.
+        self.env = scons_env
+        self.opts = scons_opts
+        self.required = required
+        self.deps = []
+
+        # Setup our option database.
+        self.setup_options()
+        self.opts.Update(self.env)
+
+    def setup_options(self):
+        """Setup all the options for this package."""
+        pass
+
+    def dependency(self, package_module, required=True, **kw):
+        """Add another package as a dependency of this package. If required is False, the
+        dependent package is not required, and thus will not cause this package to fail if
+        it cannot be found."""
+        if self.configured:
+            print 'Error: Cannot add a dependency during configuration.'
+            self.env.Exit()
+        pkg = self.env.Package(package_module, required, **kw)
+        if pkg not in [d[0] for d in self.deps]:
+            self.deps += [(pkg, required)]
+        return pkg
+
+    def setup(self):
+        """Anything that needs to be finalised before continuing with the configuration needs
+        to go here."""
+        pass
+
+    def configure(self, scons_ctx):
+        """Perform the configuration of this package."""
+        # Basic setup.
+        if self.configured:
+            return
+        self.ctx = scons_ctx
+        self.process_options()
+        self.configured = True
+
+        # Setup basic stuff.
+        old_state = self.process_dependencies()
+        self.ctx.Message('Configuring package %s ... ' % self.name)
+        self.ctx.Display('\n')
+        result = True
+        for pkg, req in self.deps: # Check we have all dependencies.
+            if req and not pkg.result:
+                self.ctx.Display('  Missing dependency: ' + pkg.name + '\n')
+                result = False
+
+        # Perform as many checks as we can without failing.
+        if result:
+            for check in self.checks:
+                result = check()
+                if not result:
+                    break
+
+        # Handle results.
+        self.restore_state(self.env, old_state)
+        self.result = result
+        self.ctx.Display('  ')
+        self.ctx.Result(result)
+
+        # If this was a critical fail, try and help the user.
+        if self.required and not result:
+            self.ctx.Display('\nThe required package ' + self.name + ' could not be found.\n')
+            self.ctx.Display('The printouts above should provide some information on what went\n')
+            self.ctx.Display('wrong. To see further details, please read the \'config.log\' file.\n')
+            if len(self.option_map.keys()):
+                self.ctx.Display('You can directly specify search parameters for this package via\n')
+                self.ctx.Display('the following command line options:\n\n')
+                for opt in self.option_map.iterkeys():
+                    self.ctx.Display('  ' + opt + '\n')
+                self.ctx.Display('\nRun \'scons help\' for more details on these options.\n\n')
+            self.env.Exit()
+
+    def enable(self, scons_env, old_state=None):
+        """Modify the SCons environment to have this package enabled. Begin by inserting
+        all options on this node into the environment."""
+        for pkg, req in self.deps: # Enable dependencies first.
+            if pkg.result:
+                pkg.enable(scons_env, old_state)
+        for opt in self.option_map.iterkeys(): # Now add options.
+            if opt in self.env._dict:
+                scons_env[opt] = self.env[opt]
+
+    def backup_variable(self, scons_env, var_name, old_state):
+        if old_state is None:
+            return
+        if var_name not in old_state:
+            if var_name in scons_env._dict:
+                old_state[var_name] = scons_env[var_name]
+            else:
+                old_state[var_name] = None
+
+    def restore_state(self, scons_env, old_state):
+        for var_name, state in old_state.iteritems():
+            if state is None:
+                del scons_env[var_name]
+            else:
+                scons_env[var_name] = state
+
+    def process_options(self):
+        """Do any initial option processing, including importing any values from
+        the environment and validating that all options are consistent."""
+        cmd_opts = False
+        for opt in self.option_map.iterkeys():
+            if opt in self.opts.args:
+                cmd_opts = True
+                break
+        if cmd_opts:
+            return
+        for cmd, env in self.option_map.iteritems():
+            if cmd not in self.opts.args and env in self.env['ENV']:
+                self.env[cmd] = self.env['ENV'][env]
+
+    def process_dependencies(self):
+        """Ensure all dependencies have been configured before this package."""
+        old_state = {}
+        for pkg, req in self.deps:
+            pkg.configure(self.ctx)
+            if pkg.result:
+                pkg.enable(self.env, old_state)
+        return old_state
+
+    def compile_source(self, source):
+        """At this point we know all our construction environment has been set up,
+        so we should be able to compile some source code."""
+        result = self.run_scons_cmd(self.ctx.TryCompile, source, '.c')
+        return [result[0], result[1]]
+
+    def link_source(self, source):
+        """At this point we know all our construction environment has been set up,
+        so we should be able to build and run the application."""
+        result = self.run_scons_cmd(self.ctx.TryLink, source, '.c')
+        return [result[0], result[1]]
+
+    def run_source(self, source):
+        """At this point we know all our construction environment has been set up,
+        so we should be able to build and run the application."""
+        result = self.run_scons_cmd(self.ctx.TryRun, source, '.c')
+        return [result[0][0], result[0][1], result[1]]
+
+    def run_scons_cmd(self, cmd, *args, **kw):
+        old_log = self.ctx.sconf.logstream
+        self.ctx.sconf.logstream = open('sconfig.log', 'w') # Capture the log.
+        res = cmd(*args, **kw) # Execute the command.
+        try:
+            self.ctx.sconf.logstream.close() # Make sure the file is closed.
+        finally:
+            pass
+        self.ctx.sconf.logstream = old_log # Replace the old log.
+
+        # Return results.
+        log_file = open('sconfig.log', 'r')
+        log = log_file.read()
+        log_file.close()
+        os.remove('sconfig.log')
+        old_log.write(log)
+        return [res, log]
+
+    def push_state(self, state, append=False):
+        old = {}
+        copy = dict(state)
+        for k, v in copy.iteritems():
+            if not v:
+                continue
+            if not isinstance(v, list):
+                copy[k] = [v]
+            else:
+                copy[k] = v
+            old[k] = self.env.get(k, [])
+        if append:
+            self.env.AppendUnique(**copy)
+        else:
+            self.env.PrependUnique(**copy)
+        return old
+
+    def pop_state(self, old):
+        self.env.Replace(**old)
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/Package.py
--- a/config/SConfig/Package.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/Package.py	Mon Apr 07 00:36:43 2008 +0000
@@ -2,373 +2,293 @@ import SCons.Script
 import SCons.Script
 import SConfig
 
-class Package(object):
-    def __init__(self, env, options=None, required=True):
-        # Construct this package's name.
-        self.name = self.__module__.split('.')[-1]
-        self.option_name = self.name.lower()
-        self.environ_name = self.name.upper()
-        self.command_options = {}
-        self.environ_options = {}
-
-        # Setup some system specific information.
-        self.system = platform.system()
-        if platform.architecture()[0].find('64') != -1:
-            self.bits = 64
-        else:
-            self.bits = 32
-
-        # Is this package essential?
-        self.required          = required
-
-        # Language options.
-        self.language          = 'C' # 'C' | 'CXX' | 'F77'
-        self.have_define       = ''
+class Package(SConfig.Node):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Node.__init__(self, scons_env, scons_opts, required)
+
+        # This will be set in the preprocessor.
+        self.have_define         = ''
 
         # Search options.
-        self.base_dirs         = [] #['']
-        self.base_patterns     = [] #['']
-        self.sub_dirs          = [] #[[[''], ['']]]
-        self.header_sub_dir    = ''
-
-        # Header options.
-        self.headers            = [[]] #[['']]
+        self.base_dirs           = [] #['']
+        self.base_patterns       = [] #['']
+        self.sub_dirs            = [] #[[[''], ['']]]
+        self.header_sub_dir      = ''
+        self.system_header_dirs  = []
+        self.system_library_dirs = []
+
+        # Which headers do we require?
+        self.headers             = [[]] #[['']]
 
         # Library options.
-        self.libraries         = [] #[['']]
-        self.require_shared    = False
-        self.use_rpath         = True
-        self.symbols           = [([], '')] #[([''], '')]
-        self.symbol_setup      = ''
-        self.symbol_teardown   = ''
-        self.symbol_prototypes = [] #['']
-        self.symbol_calls      = [] #['']
+        self.libraries           = [] #[['']]
+        self.extra_libraries     = [] #['']
+        self.shared_libraries    = [] # Only libraries listed here will be considered
+                                      # when checking for shared libraries.
+        self.require_shared      = False
+        self.symbols             = [([], '')] #[([''], '')]
+        self.symbol_setup        = ''
+        self.symbol_teardown     = ''
+        self.symbol_prototypes   = [] #['']
+        self.symbol_calls        = [] #['']
 
         # Framework options.
-        self.frameworks        = [] #[['']]
-
-        # Version checking options.
-        self.version           = [] #[['', 0]]
-
-        # A list of checks to perform for this package.
-        self.checks            = [self.find_package]
-
-        # Once configured, these values will be set.
-        self.configured = False
-        self.result = [0, '', '']
-        self.cpp_defines = []
+        self.frameworks          = [] #[['']]
+
+        # Will be set after configuration.
         self.base_dir = ''
         self.hdr_dirs = []
+        self.lib_dirs = []
         self.hdrs = []
-        self.lib_dirs = []
         self.libs = []
         self.have_shared = None
         self.fworks = []
-        self.state = {}
+        self.cpp_defines = []
 
         # Private stuff.
-        self.env = env
-        self.opts = options
-        self.deps = []
-
+        self.platform = self.dependency(SConfig.Platform, True) # Need this so we can get
+                                                                # access to information about
+                                                                # the platform we're running on.
+        self.checks = [self.find_package] # The basic package location check.
+
+        # Set everything up.
         self.setup_search_defaults()
-        self.setup_options()
+
+    def setup_options(self):
+        SConfig.Node.setup_options(self)
+        self.opts.AddOptions(
+            SCons.Script.BoolOption('with_' + self.command_name,
+                                    'Turn on/off package %s' % self.name, 1),
+            SCons.Script.PathOption(self.command_name + '_dir',
+                                    '%s installation path' % self.name,
+                                    None, SCons.Script.PathOption.PathIsDir),
+            SCons.Script.PathOption(self.command_name + '_inc_dir',
+                                    '%s header installation path' % self.name,
+                                    None, SCons.Script.PathOption.PathIsDir),
+            SCons.Script.PathOption(self.command_name + '_lib_dir',
+                                    '%s library installation path' % self.name,
+                                    None, SCons.Script.PathOption.PathIsDir),
+            (self.command_name + '_lib',
+             '%s libraries' % self.name,
+             None, None),
+            (self.command_name + '_framework',
+             '%s framework' % self.name,
+             None, None))
+        self.option_map = {'with_' + self.command_name: None,
+                           self.command_name + '_dir': self.environ_name + '_DIR'}
 
     def setup_search_defaults(self):
-        # Set common defaults of Darwin and Linux.
-        if self.system in ['Darwin', 'Linux']:
+        """Setup the usual search paths for packages depending on the kind of system
+        we're on."""
+        if self.platform.system in ['Darwin', '*ix']:
             self.base_dirs = ['/usr', '/usr/local']
             self.sub_dirs = [[['include'], ['lib']]]
-            if self.bits == 64:
+            if self.platform.bits == 64:
                 self.sub_dirs = [[['include'], ['lib64']],
                                  [['include'], [os.path.join('lib', '64')]]] + self.sub_dirs
 
         # Set Darwin specific defaults.
-        if self.system == 'Darwin':
+        if self.platform.system == 'Darwin':
             self.base_dirs += ['/sw']
 
         # Set Window specific defaults.
-        if self.system == 'Windows':
+        if self.platform.system == 'Windows':
             pass # TODO
 
-    def setup_options(self):
-        if not self.opts:
+        # Combine these guys to build default system paths. We need these to ensure specific
+        # include paths are used before generic ones.
+        for base_dir in ['/usr', '/sw']:
+            for hdr_dirs, lib_dirs in self.combine_sub_dirs(base_dir):
+                hdr_dirs = [os.path.join(base_dir, h) for h in hdr_dirs]
+                self.system_header_dirs += [h for h in hdr_dirs if h not in self.system_header_dirs]
+                lib_dirs = [os.path.join(base_dir, l) for l in lib_dirs]
+                self.system_library_dirs += [l for l in lib_dirs if l not in self.system_library_dirs]
+
+    def get_check_headers_fail_reason(self, fail_logs):
+        return ''
+
+    def get_check_symbols_fail_reason(self, fail_logs):
+        return ''
+
+    def configure(self, scons_ctx):
+        if not self.required and not self.env['with_' + self.command_name]:
             return
-        self.command_options = [self.option_name + 'Dir',
-                                self.option_name + 'IncDir',
-                                self.option_name + 'LibDir',
-                                self.option_name + 'Lib',
-                                self.option_name + 'Framework']
-        self.environ_options = {self.option_name + 'Dir': self.environ_name + '_DIR',
-                                self.option_name + 'IncDir': self.environ_name + '_INC_DIR',
-                                self.option_name + 'LibDir': self.environ_name + '_LIB_DIR',
-                                self.option_name + 'Lib': self.environ_name + '_LIB',
-                                self.option_name + 'Framework': self.environ_name + '_FRAMEWORK'}
-        self.opts.AddOptions(
-            SCons.Script.PathOption(self.option_name + 'Dir',
-                                    '%s installation path' % self.name,
-                                    None, SCons.Script.PathOption.PathIsDir),
-            SCons.Script.PathOption(self.option_name + 'IncDir',
-                                    '%s header installation path' % self.name,
-                                    None, SCons.Script.PathOption.PathIsDir),
-            SCons.Script.PathOption(self.option_name + 'LibDir',
-                                    '%s library installation path' % self.name,
-                                    None, SCons.Script.PathOption.PathIsDir),
-            (self.option_name + 'Lib',
-             '%s libraries' % self.name,
-             None, None),
-            (self.option_name + 'Framework',
-             '%s framework' % self.name,
-             None, None))
-
-    def get_headers_error_message(self, console):
-        return ''
-
-    def get_run_error_message(self, console):
-        return ''
-
-    def configure(self, configure_context):
-        """Perform the configuration of this package. Override this method to perform
-        custom configuration checks."""
-        # If we've already configured this package, just return.
-        if self.configured:
-            return
-
-        # Setup our configure context and environment.
-        self.ctx = configure_context
-        self.configured = True
-
-        # If we have shared libraries enabled, we must ensure the dynamic loader
-        # package is included.
+        SConfig.Node.configure(self, scons_ctx)
+
+    def setup(self):
+        SConfig.Node.setup(self)
         if self.require_shared:
-            self.pkg_dl = self.require(SConfig.packages.dl)
-
-        # Process dependencies first.
-        self.process_dependencies()
-
-        # Process options.
-        self.process_options()
-
-        # Perfrom actual configuration.
-        for check in self.checks:
-            result = check()
-            if not result[0]:
+            self.dependency(SConfig.packages.dl)
+
+    def find_package(self):
+        """Basic check routine for locating the package."""
+        result = False
+        self.ctx.Display('  Searching locations:\n')
+        for loc in self.generate_locations():
+            self.ctx.Display('    %s\n' % str(loc))
+            result = self.check_location(loc)
+            if result:
+                if self.have_define:
+                    self.cpp_defines += [self.have_define]
+                self.base_dir = loc[0]
+                self.hdr_dirs = loc[1]
+                self.lib_dirs = loc[2]
+                self.fworks = loc[3]
                 break
-
-        # Required?
-        if self.required and not result[0]:
-            self.ctx.Display('\nThe required package ' + self.name + ' could not be found.\n')
-            self.ctx.Display('The printouts above should provide some information on what went wrong,\n')
-            self.ctx.Display('To see further details, please read the \'config.log\' file.\n')
-            if len(self.command_options):
-                self.ctx.Display('You can directly specify search parameters for this package via\n')
-                self.ctx.Display('the following command line options:\n\n')
-                for opt in self.command_options:
-                    self.ctx.Display('  ' + opt + '\n')
-                self.ctx.Display('\nRun \'scons help\' for more details on these options.\n\n')
-            self.env.Exit()
-
-        # If we succeeded, store the resulting environment.
-        if result[0]:
-            if self.have_define:
-                self.cpp_defines += [self.have_define]
-            self.build_state()
-            self.push_state(self.state)
-
-        return result
-
-    def require(self, package_module):
-        pkg = self.env.Package(package_module, self.opts)
-        self.deps += [pkg]
-        return pkg
-
-    def process_dependencies(self):
-        """Ensure all dependencies have been configured before this package."""
-        for pkg in self.deps:
-            pkg.configure(self.ctx)
-
-    def process_options(self):
-        """Do any initial option processing, including importing any values from
-        the environment and validating that all options are consistent."""
-        cmd_opts = False
-        for opt in self.command_options:
-            if opt in self.opts.args:
-                cmd_opts = True
-                break
-        if cmd_opts:
-            return
-        for cmd, env in self.environ_options.iteritems():
-            if cmd not in self.opts.args and env in self.env['ENV']:
-                self.env[cmd] = self.env['ENV'][env]
-
-    def find_package(self):
-        # Search for package locations.
-        self.ctx.Message('Checking for package %s ... ' % self.name)
-        self.ctx.Display('\n   Searching locations:\n')
-        for loc in self.generate_locations():
-            result = self.check_location(loc)
-            self.ctx.Display('      %s\n' % str(loc))
-
-            # If we succeeded, back out here.
-            if result[0]:
-                break
-
-            # Display an error message.
-            if result[2]:
-                self.ctx.Display('         %s\n' % result[2])
-
-        # Display results.
-        self.ctx.Display('   ')
-        self.ctx.Result(result[0])
-
         return result
 
     def check_location(self, location):
         """Check if the currently selected location is a valid installation of the
         required package. At this stage we know that the paths given in the location
         actually exist."""
-        # Validate the headers, first.
-        result = self.validate_location(location)
-        if not result[0]:
-            return result
-
-        # Construct our path state.
-        path_state = self.build_header_state(location)
-        old = self.push_state(path_state)
+        old_state = self.enable_location_state(location)
 
         # Check for the headers.
-        result = self.check_headers(location)
-        if not result[0]:
-            self.pop_state(old)
-            return result
+        if not self.check_headers(location):
+            self.pop_state(old_state)
+            return False
 
         # Scan each set of libraries in turn.
-        libs = []
-        for libs in self.libraries:
-            result = self.check_libs(location, libs)
-            if result[0]:
-                break
-
-        # Store last known configuration.
-        self.store_result(result, location, libs)
-
-        # Roll-back on state.
-        self.pop_state(old)
-        return result
+        if not self.check_libraries(location):
+            self.pop_state(old_state)
+            return False
+
+        self.pop_state(old_state)
+        return True
 
     def check_headers(self, location):
         """Determine if the required headers are available with the current construction
         environment settings."""
+        fail_logs = []
         for hdrs in self.headers:
             src = self.get_header_source(hdrs)
-            result = self.run_scons_cmd(self.ctx.TryCompile, src, '.c')
+            result = self.compile_source(src)
             if result[0]:
                 self.hdrs = list(hdrs)
                 break
+            fail_logs += [result[1]]
         if not result[0]:
-            msg = self.get_headers_error_message(result[1])
+            msg = self.get_check_headers_fail_reason(fail_logs)
             if not msg:
-                msg = 'Failed to locate headers.'
-        else:
-            msg = ''
-        return [result[0], '', msg]
-
-    def check_libs(self, location, libs):
+                msg = 'Headers not found.'
+            self.ctx.Display('      ' + msg + '\n')
+        return result[0]
+
+    def check_libraries(self, location):
         """Check if the currently selected location is a valid installation of the
         required package. At this stage we know that the paths given in the location
         actually exist and we need to confirm that the libraries in 'libs' exist."""
-        # Validate the libraries.
-        result = self.validate_libraries(location, libs)
-        if not result[0]:
-            return result
-
-        # Construct the library state.
-        lib_state = self.build_lib_state(location, libs)
-        old = self.push_state(lib_state)
-
-        # Check that we can link against the libraries by trying to link against
-        # a particular set of symbols.
-        result = self.check_symbols()
-        if not result[0]:
-            if not result[2]:
-                result[2] = 'Failed to link against library(s).'
-            self.pop_state(old)
-            return result
-
-        # Check if we have shared libraries.
-        if self.require_shared:
-            result = self.check_shared(location, libs)
-            if not result[0] and not result[2]:
-                result[2] = 'No shared library(s) available.'
-
-        # Roll-back on our state.
-        self.pop_state(old)
-        return result
-
-    def check_symbols(self):
+        fail_reasons = []
+        no_shared = False
+        for libs in self.generate_libraries(location):
+            old_state = self.enable_library_state(location, libs)
+
+            # Check that we can link against the libraries by trying to link against
+            # a particular set of symbols.
+            result = self.check_symbols(location, libs)
+            if not result[0]:
+                fail_reasons += [result[1]]
+                self.pop_state(old_state)
+                continue
+
+            # Check if we have shared libraries.
+            if not self.require_shared or not libs:
+                self.libs = list(libs)
+                self.pop_state(old_state)
+                return True
+            elif self.check_shared(location, libs):
+                self.libs = list(libs)
+                self.pop_state(old_state)
+                return True
+            else:
+                no_shared = True
+
+        # Figure out what to report.
+        if no_shared:
+            reason = 'No shared libraries.'
+        else:
+            reason = ''
+            for reason in fail_reasons:
+                if reason:
+                    break
+            if not reason:
+                reason = 'Libraries not found.'
+        self.ctx.Display('      ' + reason + '\n')
+
+        self.pop_state(old_state)
+        return False
+
+    def check_symbols(self, location, libraries):
         """We have our paths and libraries setup, now we need to see if we can find
         one of the set of required symbols in the libraries."""
+        fail_logs = []
         for syms in self.symbols:
-            result = self.run_source(self.get_check_symbols_source(syms[0]))
+            result = self.link_source(self.get_check_symbols_source(syms[0]))
             if result[0]:
                 if syms[1]:
                     self.cpp_defines += [syms[1]] # Add the CPP defines.
                 break
-        return result
-
-    def check_shared(self, location, libs):
-        """Confirm that there are shared versions of this package's libraries available."""
-        if not self.pkg_dl.result[0]:
-            return [0, '', 'No dynamic loader found (libdl).']
-
-        # Build a binary to try and dynamically open the library.
+            fail_logs += [result[1]]
+        if not result[0]:
+            reason = self.get_check_symbols_fail_reason(fail_logs)
+        else:
+            reason = ''
+        return [result[0], reason]
+
+    def check_shared(self, location, libraries):
+        """Confirm that there are shared versions of this package's libraries available.
+        At this point we know we can link against the libraries."""
+        # Build a binary to try and dynamically open the libraries in order.
         result = [1, '', '']
-        for l in libs:
-            src = self.get_header_source()
-            src += '#include<dlfcn.h>\n'
-            src += """
+        src = self.get_header_source()
+        src += """
 int main(int argc, char* argv[]) {
-  void* lib;
-  lib = dlopen("%s", RTLD_LAZY);
-  return lib ? 0 : 1;
-}
-""" % self.env.subst('${SHLIBPREFIX}' + l + '${SHLIBSUFFIX}')
-            result = self.run_source(src)
-            if not result[0]:
-                break
-        return result
-
-    def run_source(self, source):
-        """At this point we know all our construction environment has been set up,
-        so we should be able to build and run the application."""
-        result = self.run_scons_cmd(self.ctx.TryRun, source, '.c')
-        msg = self.get_run_error_message(result[1])
-        return [result[0][0], result[0][1], msg]
-
-    def validate_location(self, location):
-        """Confirm that the location is okay, possibly modifying it in place if
-        there are additional locations to search."""
-        return [1, '', '']
-
-    def validate_libraries(self, location, libs):
-        """Confirm that the specified libraries are okay, possibly modifying in
-        place the list of libraries."""
-        return [1, '', '']
+  void* lib[%d];
+""" % len(libraries)
+        for l in libraries:
+            if self.shared_libraries and l not in self.shared_libraries:
+                continue
+            if l in self.extra_libraries:
+                continue
+            offs = ''
+            for p in self.generate_library_paths(location, l):
+                offs += '  '
+                if len(offs) > 2:
+                    src += '{\n'
+                src += '%slib[%d] = dlopen("%s", RTLD_NOW);\n' % (offs, libraries.index(l), p)
+                src += '%sif( !lib[%d] ) ' % (offs, libraries.index(l))
+            src += 'return 1;\n'
+            while len(offs) > 2:
+                offs = offs[:-2]
+                src += offs + '}\n'
+        src += '  return 0;\n}\n'
+        if not self.run_source(src)[0]:
+            return False
+        return True
+
+    def generate_library_paths(self, location, library):
+        lib_name = self.env.subst('${SHLIBPREFIX}' + library + '${SHLIBSUFFIX}')
+        if location[2]:
+            for d in location[2]:
+                path = os.path.join(location[0], d, lib_name)
+                yield os.path.abspath(path)
+        else:
+            yield lib_name
 
     def generate_locations(self):
         """Generate a set of potential package locations. Locations are of the form
         ['base_dir', ['header_dirs'], ['lib_dirs'], ['frameworks']]."""
         # If we've been given options directly specifying the location of this
         # package we need to use those in place of searching for locations.
-        base_dir = self.env.get(self.option_name + 'Dir', '')
-        inc_dir = self.env.get(self.option_name + 'IncDir', '')
-        lib_dir = self.env.get(self.option_name + 'LibDir', '')
-        fwork = self.env.get(self.option_name + 'Framework', '')
+        base_dir = self.env.get(self.command_name + '_dir', '')
+        inc_dir = self.env.get(self.command_name + '_inc_dir', '')
+        lib_dir = self.env.get(self.command_name + '_lib_dir', '')
+        fwork = self.env.get(self.command_name + '_framework', '')
         if inc_dir or lib_dir:
             if not (inc_dir and lib_dir):
                 print '   Error: must specify both of'
-                print '      ' + self.option_name + 'IncDir'
-                print '      ' + self.option_name + 'LibDir'
+                print '      ' + self.command_name + '_inc_dir'
+                print '      ' + self.command_name + '_lib_dir'
                 env.Exit()
             yield ['', [inc_dir], [lib_dir], [fwork]]
             return
@@ -452,91 +372,100 @@ int main(int argc, char* argv[]) {
             return sub_dir
         return os.path.join(base_dir, sub_dir)
 
-    def build_header_state(self, location):
-        """Build a construction state for including headers."""
-        state = {}
+    def generate_libraries(self, location):
+        if location[3]: # Try any frameworks by themselves first.
+            yield self.extra_libraries
+        for libs in self.libraries:
+            yield libs + self.extra_libraries
+
+    def enable_location_state(self, location):
+        """Modify our environment to include search paths for the current location."""
+        old_state = {}
         if location[1]:
-            state['CPPPATH'] = [self.join_sub_dir(location[0], l) for l in location[1]]
+            old_state['CPPPATH'] = self.env.get('CPPPATH', [])
+            self.env.PrependUnique(CPPPATH=[self.join_sub_dir(location[0], l) for l in location[1]])
+        if location[2]:
+            old_state['LIBPATH'] = self.env.get('LIBPATH', [])
+            old_state['RPATH'] = self.env.get('RPATH', [])
+            lib_paths = [self.join_sub_dir(location[0], l) for l in location[2]]
+            self.env.PrependUnique(LIBPATH=lib_paths)
+            self.env.PrependUnique(RPATH=[os.path.abspath(p) for p in lib_paths])
         if location[3]:
-            state['FRAMEWORKS'] = location[3]
-        return state
-
-    def build_lib_state(self, location, libs):
+            old_state['FRAMEWORKS'] = self.env.get('FRAMEWORKS', [])
+            self.env.PrependUnique(FRAMEWORKS=location[3])
+            if 'CPPPATH' not in old_state:
+                old_state['CPPPATH'] = self.env.get('CPPPATH', [])
+            for fw in location[3]: # Sort of a hack for Mac OS X.
+                path = '/System/Library/Frameworks/' + fw + '.framework/Headers'
+                self.env.PrependUnique(CPPPATH=[path])
+        return old_state
+
+    def enable_library_state(self, location, libs):
         """Take the current location and libraries and convert them into an SCons
         construction environment state dictionary."""
-        state = {}
-        if location[2]:
-            state['LIBPATH'] = [self.join_sub_dir(location[0], l) for l in location[2]]
-            if self.use_rpath:
-                state['RPATH'] = [os.path.abspath(p) for p in state['LIBPATH']]
-        if location[3]:
-            state['FRAMEWORKS'] = location[3]
+        old_state = {}
         if libs:
-            state['LIBS'] = libs
-        return state
-
-    def build_state(self):
-        self.state = {}
+            old_state['LIBS'] = self.env.get('LIBS', [])
+            self.env.PrependUnique(LIBS=libs)
+        return old_state
+
+    def enable(self, scons_env, old_state=None):
+        SConfig.Node.enable(self, scons_env, old_state)
         if self.cpp_defines:
-            self.state['CPPDEFINES'] = self.cpp_defines
+            self.backup_variable(scons_env, 'CPPDEFINES', old_state)
+            scons_env.AppendUnique(CPPDEFINES=self.cpp_defines)
+
         if self.hdr_dirs:
-            self.state['CPPPATH'] = [self.join_sub_dir(self.base_dir, d) \
-                                         for d in self.hdr_dirs]
+            self.backup_variable(scons_env, 'CPPPATH', old_state)
+            for d in self.hdr_dirs:
+                abs_dir = self.join_sub_dir(self.base_dir, d)
+                if abs_dir in self.system_header_dirs:
+                    scons_env.AppendUnique(CPPPATH=[abs_dir])
+                else:
+                    scons_env.PrependUnique(CPPPATH=[abs_dir])
+
         if self.fworks:
-            self.state['FRAMEWORKS'] = self.fworks
+            self.backup_variable(scons_env, 'FRAMEWORKS', old_state)
+            self.backup_variable(scons_env, 'CPPPATH', old_state)
+            scons_env.PrependUnique(FRAMEWORKS=self.fworks)
+            for fw in self.fworks: # Sort of a hack for Mac OS X.
+                path = '/System/Library/Frameworks/' + fw + '.framework/Headers'
+                self.env.PrependUnique(CPPPATH=[path])
+
         if self.lib_dirs:
-            self.state['LIBPATH'] = [self.join_sub_dir(self.base_dir, d) \
-                                         for d in self.lib_dirs]
-            if self.use_rpath:
-                self.state['RPATH'] = [os.path.abspath(p) for p in self.state['LIBPATH']]
+            self.backup_variable(scons_env, 'LIBPATH', old_state)
+            self.backup_variable(scons_env, 'RPATH', old_state)
+            for d in self.lib_dirs:
+                abs_dir = self.join_sub_dir(self.base_dir, d)
+                if abs_dir in self.system_library_dirs:
+                    scons_env.AppendUnique(LIBPATH=[abs_dir])
+                    scons_env.AppendUnique(RPATH=[os.path.abspath(abs_dir)])
+                else:
+                    scons_env.PrependUnique(LIBPATH=[abs_dir])
+                    scons_env.PrependUnique(RPATH=[os.path.abspath(abs_dir)])
+
         if self.libs:
-            self.state['LIBS'] = self.libs
-
-    def store_result(self, result, location, libs):
-        self.result = result
-        self.base_dir = location[0]
-        self.hdr_dirs = location[1]
-        self.lib_dirs = location[2]
-        self.libs = libs
-        if self.require_shared:
-            self.have_shared = True
-        else:
-            self.have_shared = None
-        self.fworks = location[3]
-
-    def push_state(self, state, append=False):
-        old = {}
-        copy = dict(state)
-        for k, v in copy.iteritems():
-            if not isinstance(v, list):
-                copy[k] = [v]
-            else:
-                copy[k] = v
-            old[k] = self.env.get(k, None)
-        if append:
-            self.env.AppendUnique(**copy)
-        else:
-            self.env.PrependUnique(**copy)
-        return old
-
-    def pop_state(self, old):
-        self.env.Replace(**old)
+            self.backup_variable(scons_env, 'LIBS', old_state)
+            scons_env.PrependUnique(LIBS=self.libs)
 
     def get_all_headers(self, headers):
-        if not self.result[0]:
+        if not self.result:
             return
+        for d, r in self.deps:
+            if hasattr(d, 'get_all_headers'):
+                d.get_all_headers(headers)
         headers += [h for h in self.hdrs if h not in headers]
-        for d in self.deps:
-            d.get_all_headers(headers)
 
     def get_header_source(self, headers=None):
         src = '#include<stdlib.h>\n#include<stdio.h>\n#include<string.h>\n'
+        hdrs = []
+        for d, r in self.deps:
+            if hasattr(d, 'get_all_headers'):
+                d.get_all_headers(hdrs)
         if headers is None:
-            hdrs = list(self.hdrs)
-        else:
-            hdrs = list(headers)
-        for d in self.deps:
-            d.get_all_headers(hdrs)
+            hdrs += list(self.hdrs)
+        else:
+            hdrs += list(headers)
         for h in hdrs:
             src += '#include<' + h + '>\n'
         return src
@@ -554,39 +483,3 @@ int main(int argc, char* argv[]) {
             src += self.symbol_teardown + '\n'
         src += 'return 0;\n}\n'
         return src
-
-    def run_scons_cmd(self, cmd, *args, **kw):
-        # Capture the log.
-        old_log = self.ctx.sconf.logstream
-        self.ctx.sconf.logstream = open('sconfig.log', 'w')
-
-        # Execute the command.
-        res = cmd(*args, **kw)
-
-        # Make sure the file is closed.
-        try:
-            self.ctx.sconf.logstream.close()
-        finally:
-            pass
-
-        # Replace the old log.
-        self.ctx.sconf.logstream = old_log
-
-        # Return results.
-        log_file = open('sconfig.log', 'r')
-        log = log_file.read()
-        log_file.close()
-        os.remove('sconfig.log')
-        old_log.write(log)
-        return (res, log)
-
-    def __str__(self):
-        str =  'Package name:  %s\n' % self.name
-        str += 'Found:         %s\n' % self.result[0]
-        str += 'Base path:     %s\n' % self.base_dir
-        str += 'Header paths:  %s\n' % self.hdr_dirs
-        str += 'Library paths: %s\n' % self.lib_dirs
-        str += 'Libraries:     %s\n' % self.libs
-        str += 'Have shared:   %s\n' % self.have_shared
-        str += 'Frameworks:    %s\n' % self.fworks
-        return str
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/Platform.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/Platform.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,67 @@
+import os, platform
+import SCons.Script
+import SConfig
+
+class Platform(SConfig.Node):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Node.__init__(self, scons_env, scons_opts, required)
+        self.checks = [self.print_results]
+
+        # Will be set after successful configuration.
+        self.system = ''
+        self.bits = 0
+
+        # We need to do these now.
+        self.check_system()
+        self.check_bits()
+        self.check_CC()
+
+    def setup_options(self):
+        self.opts.AddOptions(
+            SCons.Script.BoolOption('with_32bit', 'Generate 32bit code', 0),
+            SCons.Script.BoolOption('with_64bit', 'Generate 64bit code', 0),
+            )
+
+    def check_system(self):
+        self.system = platform.system()
+        if not self.system or self.system in ['Linux', 'Unix']:
+            self.system = '*ix'
+
+        # Need to modify building shared libraries when on Mac OS X.
+        if self.system == 'Darwin':
+            self.env.AppendUnique(SHLINKFLAGS=['-flat_namespace',
+                                          '-single_module',
+                                          '-undefined', 'suppress'])
+            import SCons.Util # And fix RPATHs.
+            self.env['LINKFLAGS'] = SCons.Util.CLVar('')
+            self.env['RPATHPREFIX'] = ''
+            self.env['RPATHSUFFIX'] = ''
+            self.env['_RPATH'] = ''
+
+            # Use 'install_name' instead.
+            self.env.Append(SHLINKFLAGS=['-install_name', '${_abspath(TARGET)}'])
+
+            self.env.AppendUnique(CONFIGVARS=['SHLINKFLAGS', 'LINKFLAGS',
+                                              'RPATHPREFIX', 'RPATHSUFFIX', '_RPATH'])
+
+    def check_bits(self):
+        if (platform.platform().find('x86_64') != -1 or \
+                platform.platform().find('ppc64') != -1 or \
+                platform.architecture()[0].find('64') != -1 or \
+                self.env['with_64bit']) and \
+                not self.env['with_32bit']:
+            self.bits = 64
+        else:
+            self.bits = 32
+
+    def check_CC(self):
+        if 'CC' in self.env['ENV']:
+            self.env['CC'] = self.env['ENV']['CC']
+            self.CC = self.env['CC']
+
+    def print_results(self):
+        self.ctx.Display("  Building on a %s platform\n" % self.system)
+        self.ctx.Display("  Building for %d bit architecture\n" % self.bits)
+        if hasattr(self, 'CC'):
+            self.ctx.Display("  Using environment specified C compiler: %s\n" % self.CC)
+        return True
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/Project.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/Project.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,63 @@
+import os
+import SCons.Script
+import SConfig
+
+class Project(SConfig.Node):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Node.__init__(self, scons_env, scons_opts, required)
+        self.checks += [self.check_libs, self.print_results]
+
+    def setup_options(self):
+        self.opts.AddOptions(
+            SCons.Script.BoolOption('with_debug',
+                                    'Generate debugging symbols', 1),
+            SCons.Script.BoolOption('static_libraries',
+                                    'Build static libraries', 1),
+            SCons.Script.BoolOption('shared_libraries',
+                                    'Build shared libraries', 1),
+            ('build_dir', 'Temporary build directory', 'build')
+            )
+
+    def check_libs(self):
+        if not self.env['static_libraries'] and not self.env['shared_libraries']:
+            self.ctx.Display("      Both static and shared libraries disabled!\n")
+            return False
+        return True
+
+    def print_results(self):
+        self.ctx.Display("  Static libraries: %s\n" % str(bool(self.env['static_libraries'])))
+        self.ctx.Display("  Shared libraries: %s\n" % str(bool(self.env['shared_libraries'])))
+        self.ctx.Display("  Using build directory: %s\n" % self.env['build_dir'])
+        self.ctx.Display("  Debugging symbols: %s\n" % str(bool(self.env['with_debug'])))
+        return True
+
+    def setup(self):
+        SConfig.Node.setup(self)
+        modified = []
+        if self.env['shared_libraries']:
+            for pkg in self.env.package_list:
+                if isinstance(pkg, SConfig.Package):
+                    pkg.require_shared = True
+                    modified += [pkg]
+        return modified
+
+    def enable(self, scons_env, old_state=None):
+        SConfig.Node.enable(self, scons_env, old_state)
+
+        # Setup debugging flags.
+        if self.env['with_debug']:
+            scons_env.MergeFlags('-g')
+
+        # Setup the include paths.
+        inc_dir = self.env.get_build_path('include')
+        self.backup_variable(scons_env, 'CPPPATH', old_state)
+        scons_env.PrependUnique(CPPPATH=[inc_dir])
+
+        # Setup LIB_DIR.
+        lib_dir = self.env.get_build_path('lib')
+        self.backup_variable(scons_env, 'LIBPATH', old_state)
+        scons_env.PrependUnique(LIBPATH=[lib_dir])
+
+        # Setup the RPATH.
+        self.backup_variable(scons_env, 'RPATH', old_state)
+        scons_env.PrependUnique(RPATH=[scons_env.Dir(lib_dir).abspath])
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/SConscript
--- a/config/SConfig/SConscript	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/SConscript	Mon Apr 07 00:36:43 2008 +0000
@@ -1,39 +1,90 @@ import os
-import os
+import os, sys, platform, pickle, shutil
+import glob as pyglob
+import SConfig
 from SCons.Script.SConscript import SConsEnvironment
 
 #
 # Setup the Package system.
 #
 
-def Package(env, pkg_module, options=None):
-    # Setup the SCons environment to hold packages if not already
-    # done.
+def Package(env, pkg_module, required=True, **kw):
+    """Create a new package to be configured."""
+    if not hasattr(env, 'package_options'):
+        env.package_options = Options()
     if not hasattr(env, 'packages'):
         env.packages = {}
         env.package_list = []
-
-    # If we already have this package we can return now.
-    if pkg_module in env.packages:
-        return
-
-    # Add an instance of this package.
-    env.packages[pkg_module] = pkg_module(env, options)
-    env.package_list += [env.packages[pkg_module]]
+    if not pkg_module in env.packages:
+        pkg = pkg_module(env, env.package_options, required)
+        for attr, val in kw.iteritems():
+            if not hasattr(pkg, attr):
+                print 'Package does not have attribute!'
+                sys.exit()
+            setattr(pkg, attr, val)
+        env.packages[pkg_module] = pkg
+        env.package_list += [pkg]
+    return env.packages[pkg_module]
 
 def CheckPackages(ctx, pkg_list):
     for pkg in pkg_list:
         pkg.configure(ctx)
 
-def setup_packages(env, options=None):
-    for pkg in env.package_list:
-        pkg.setup_dependencies()
-    if options:
-        options.Update(env)
-        options.Save('config.cache', env)
+def configure_packages(env):
+    # If we have 'help' given as a target, use that to generate help.
+    if 'help' in COMMAND_LINE_TARGETS:
+        env.Alias('help', '.')
+        print env.package_options.GenerateHelpText(env)
+        return
 
-def save_config(env, filename, vars):
+    # Get rid of the temporary directory to make sure we're building
+    # from scratch.
+    if os.path.exists('.sconsign.dblite'):
+        os.remove('.sconsign.dblite')
+
+    # Finish setting everything up.
+    pkgs_rem = list(env.package_list)
+    while len(pkgs_rem):
+        pkg = pkgs_rem.pop()
+        modified = pkg.setup()
+        if isinstance(modified, list):
+            pkgs_rem += [m for m in modified if m not in pkgs_rem]
+
+    # Update dependencies and requirements.
+    pkgs_rem = list(env.package_list)
+    while len(pkgs_rem):
+        pkg = pkgs_rem.pop()
+        if pkg.required:
+            for d, r in pkg.deps:
+                if r and not d.required:
+                    d.required = True
+                    pkgs_rem += [d]
+
+    # Call the packages checker.
+    sconf = Configure(pkg.env, custom_tests={'CheckPackages': CheckPackages})
+    sconf.CheckPackages(env.package_list)
+    sconf.Finish()
+
+    # Print out build message.
+    print '\n*****************************************'
+    print "* Now run 'scons' to build the project. *"
+    print '*****************************************\n'
+
+def save_config(env, filename='config.cfg'):
+    # Put the results on this environment.
+    for pkg in env.package_list: 
+        if pkg.result:
+            pkg.enable(env)
+
+    # Update config variables.
+    env.AppendUnique(CONFIGVARS=['CC', 'CFLAGS', 'CCFLAGS',
+                                 'CPPPATH', 'CPPDEFINES',
+                                 'LIBPATH', 'LIBS', 'RPATH',
+                                 'FRAMEWORKS'])
+    env.AppendUnique(CONFIGVARS=env.package_options.keys())
+
+    # Dump to file.
     d = {}
-    for a in vars:
+    for a in env['CONFIGVARS']:
         if a in env._dict:
             d[a] = env[a]
     f = file(filename, 'w')
@@ -41,12 +92,13 @@ def save_config(env, filename, vars):
     pickle.dump(d, f)
     f.close()
 
-def load_config(env, filename):
+def load_config(env, filename='config.cfg'):
     if not os.path.exists(filename):
-        print "\nError: project hasn't been configured!\n"
-        print '************************************************'
-        print "* Run 'scons config' to configure the project. *"
-        print '************************************************\n'
+        print "\nError: project hasn't been configured!"
+        print '*******************************************************'
+        print "* Run 'scons config' to configure the project.        *"
+        print "* Run 'scons help' to see what options are available. *"
+        print '*******************************************************'
         env.Exit()
     f = file(filename, 'r')
     import pickle
@@ -54,28 +106,81 @@ def load_config(env, filename):
     f.close()
     for k, v in d.iteritems():
         env[k] = v
-
-def configure_packages(env, options=None, output='config.cfg'):
-    sconf = Configure(env, custom_tests={'CheckPackages': CheckPackages})
-
-    # Set the configure object to all packages.
-    for pkg in env.package_list:
-        pkg.sconf = sconf
-
-    # Call the packages checker.
-    sconf.CheckPackages(env.package_list)
-
-    # Dump results to our output file.
-    vars = ['CFLAGS', 'CCFLAGS',
-            'CPPPATH', 'CPPDEFINES',
-            'LIBPATH', 'LIBS', 'RPATH',
-            'FRAMEWORKS']
-    if options:
-        vars += options.keys()
-    env.save_config(output, vars)
+    for script in env.get('CONFIGSCRIPTS', []):
+        env.SConscript(script, 'env')
+    if 'build_dir' in env._dict:
+        env.Default(env['build_dir'])
 
 SConsEnvironment.Package = Package
-SConsEnvironment.setup_packages = setup_packages
 SConsEnvironment.configure_packages = configure_packages
 SConsEnvironment.save_config = save_config
 SConsEnvironment.load_config = load_config
+
+#
+# Useful utilities.
+#
+
+def copy_file(env, dst, src):
+    dst = File(dst).abspath
+    if os.path.exists(dst):
+        return
+    dst_dir = os.path.dirname(dst)
+    if not os.path.exists(dst_dir):
+        os.makedirs(dst_dir)
+    shutil.copy(src, dst)
+
+def get_build_path(env, prefix):
+    if os.path.isabs(env['build_dir']):
+        bld_dir = env['build_dir']
+    else:
+        bld_dir = '#' + env['build_dir']
+    if prefix:
+        return os.path.join(bld_dir, prefix)
+    else:
+        return bld_dir
+
+def get_target_name(env, source, extension=''):
+    """Return the destination name for a source file with suffix 'suffix'. This
+    is useful for building files into the correct build path. Returns the full
+    path to the built source without extension."""
+    if extension:
+        src = source[:-len(extension)]
+    else:
+        src = source
+    return env.get_build_path(src)
+
+def glob(env, pattern):
+    if not os.path.isabs(pattern):
+        old = os.getcwd()
+        os.chdir(Dir('.').srcnode().abspath)
+        res = pyglob.glob(pattern)
+        os.chdir(old)
+    else:
+        res = pyglob.glob(pattern)
+    return res
+
+def path_exists(env, path):
+    if not os.path.isabs(path):
+        old = os.getcwd()
+        os.chdir(Dir('.').srcnode().abspath)
+        res = os.path.exists(path)
+        os.chdir(old)
+    else:
+        res = os.path.exists(path)
+    return res
+
+def strip_dir(env, path, subdir):
+    offs = path.find(os.path.sep + subdir + os.path.sep)
+    if offs != -1:
+        return path[:offs] + path[offs + len(subdir) + 1:]
+    offs = path.find(os.path.sep + subdir)
+    if offs != -1:
+        return path[:-(len(subdir) + 1)]
+    return path
+
+SConsEnvironment.strip_dir = strip_dir
+SConsEnvironment.copy_file = copy_file
+SConsEnvironment.get_build_path = get_build_path
+SConsEnvironment.get_target_name = get_target_name
+SConsEnvironment.glob = glob
+SConsEnvironment.path_exists = path_exists
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/__init__.py
--- a/config/SConfig/__init__.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/__init__.py	Mon Apr 07 00:36:43 2008 +0000
@@ -1,2 +1,5 @@ from Package import Package
+from Node import Node
 from Package import Package
+from Platform import Platform
+from Project import Project
 import packages
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/BlasLapack.py
--- a/config/SConfig/packages/BlasLapack.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/packages/BlasLapack.py	Mon Apr 07 00:36:43 2008 +0000
@@ -2,9 +2,9 @@ import SConfig
 import SConfig
 
 class BlasLapack(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.cmath = self.require(SConfig.packages.cmath)
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.cmath = self.dependency(SConfig.packages.cmath)
         self.libraries = [['blas', 'lapack'],
                           ['cblas', 'clapack'],
                           ['mkl', 'mkl_lapack']]
@@ -49,3 +49,26 @@ free(rightEigenVec);
 '''
         self.symbol_prototypes = ['void %s(char*,char*,int*,double*,int*,double*,double*,double*,int*,double*,int*,double*,int*,int*);']
         self.symbol_calls = ['%s(&jobVecLeft, &jobVecRight, &dim, arrayA, &dim, outputReal, outputImag, leftEigenVec, &leadDimVL, rightEigenVec, &leadDimVR, workSpace, &dimWorkSpace, &INFO );']
+
+    # Thanks to there not being a C version of Blas/Lapack on edda, we need
+    # to be able to search for that installation specifically.
+    def generate_locations(self):
+        lib_dir = ['/usr/local/IBM_compilers/xlf/9.1/lib64',
+                   '/opt/ibmcmp/lib64']
+        use_dir = True
+        for d in lib_dir:
+            if not os.path.exists(d):
+                use_dir = False
+                break
+        for loc in SConfig.Package.generate_locations(self):
+            yield loc
+            if use_dir:
+                yield [loc[0], loc[1], loc[2] + lib_dir, loc[3]]
+
+    def generate_libraries(self, location):
+        lib_dir = '/usr/local/IBM_compilers/xlf/9.1/lib64'
+        if lib_dir in location[2]:
+            yield ['blas', 'lapack', 'xlf90', 'xlfmath', 'xl']
+        else:
+            for libs in SConfig.Package.generate_libraries(self, location):
+                yield libs
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/CompilerFlags.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/CompilerFlags.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,61 @@
+import os, platform
+import SCons.Script
+import SConfig
+
+class CompilerFlags(SConfig.Node):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Node.__init__(self, scons_env, scons_opts, required)
+        self.checks = [self.check_bit_flags,
+                       self.check_architecture]
+
+    def setup_options(self):
+        SConfig.Node.setup_options(self)
+        self.opts.AddOptions(
+            SCons.Script.BoolOption('with_32bit', 'Generate 32bit code', 0),
+            SCons.Script.BoolOption('with_64bit', 'Generate 64bit code', 0)
+            )
+
+    def check_architecture(self):
+        if (platform.platform().find('x86_64') != -1 or \
+            platform.platform().find('ppc64') != -1 or \
+            platform.architecture()[0].find('64') != -1 or \
+            self.env['with_64bit']) and \
+            not self.env['with_32bit']:
+            self.bits = 64
+            if self.flag_64bit:
+                self.env.MergeFlags(self.flag_64bit)
+                if self.env.subst('$CC') == self.env.subst('$LINK'):
+                    self.env.AppendUnique(LINKFLAGS=[self.flag_64bit])
+        else:
+            self.bits = 32
+            if self.flag_32bit:
+                self.env.MergeFlags(self.flag_32bit)
+                if self.env.subst('$CC') == self.env.subst('$LINK'):
+                    self.env.AppendUnique(LINKFLAGS=[self.flag_32bit])
+        return True
+
+    def check_bit_flags(self):
+        if self.try_flag('-m32')[0]:
+            self.flag_32bit = '-m32'
+        elif self.try_flag('-q32')[0]:
+            self.flag_32bit = '-q32'
+        else:
+            self.flag_32bit = ''
+        if self.try_flag('-m64')[0]:
+            self.flag_64bit = '-m64'
+        elif self.try_flag('-q64')[0]:
+            self.flag_64bit = '-q64'
+        else:
+            self.flag_64bit = ''
+        return True
+
+    def try_flag(self, flag):
+        state = self.env.ParseFlags(flag)
+        old = self.push_state(state)
+        result = self.run_scons_cmd(self.ctx.TryCompile, '', '.c')
+        self.pop_state(old)
+        if result[0] and (result[1].find('not recognized') != -1 or
+                          result[1].find('not recognised') != -1 or
+                          result[1].find('unknown option') != -1):
+            result[0] = 0
+        return [result[0], result[1], '']
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/HDF5.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/HDF5.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,48 @@
+import os
+import SConfig
+
+class HDF5(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.require_parallel = False
+        self.headers = [["hdf5.h"]]
+        self.libraries = [["hdf5"]]
+
+    def setup(self):
+        SConfig.Package.setup(self)
+        if self.require_parallel:
+            self.dependency(SConfig.packages.MPI)
+            self.symbols = [(["H5Pset_dxpl_mpio", "H5Pset_fapl_mpio"], "")]
+            self.symbol_calls = ["%s( dxpl_props, H5FD_MPIO_COLLECTIVE );",
+                                 "%s( fapl_props, MPI_COMM_WORLD, MPI_INFO_NULL );"]
+            self.symbol_setup = """hid_t dxpl_props, fapl_props;
+MPI_Init( &argc, &argv );
+dxpl_props = H5Pcreate( H5P_DATASET_XFER );
+fapl_props = H5Pcreate( H5P_FILE_ACCESS );
+"""
+            self.symbol_teardown = """H5Pclose( dxpl_props );
+H5Pclose( fapl_props );
+MPI_Finalize();
+"""
+
+    def generate_locations(self):
+        for loc in SConfig.Package.generate_locations(self):
+            extra_libs = []
+            for lib_dir in loc[2]:
+                set_file = os.path.join(loc[0], lib_dir, "libhdf5.settings")
+                if os.path.exists(set_file):
+                    f = open(set_file, "r")
+                    for line in f.readlines():
+                        if line.find("Extra libraries") != -1:
+                            dict = self.env.ParseFlags(line.split(":")[1])
+                            extra_libs = dict.get('LIBS', [])
+            old_libs = self.extra_libraries
+            self.extra_libraries += extra_libs
+            yield loc
+            self.extra_libraries = old_libs
+
+    def get_check_symbols_fail_reason(self, fail_logs):
+        for log in fail_logs:
+            if log.find("_mpio'"):
+                return "Not a parallel HDF5 implementation."
+        return ''
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/MPI.py
--- a/config/SConfig/packages/MPI.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/packages/MPI.py	Mon Apr 07 00:36:43 2008 +0000
@@ -2,8 +2,9 @@ import SConfig
 import SConfig
 
 class MPI(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.dependency(SConfig.packages.CompilerFlags)
         self.base_patterns = ['mpich*', 'MPICH*']
         self.header_sub_dir = 'mpi'
         self.headers = [['mpi.h']]
@@ -11,14 +12,18 @@ class MPI(SConfig.Package):
                           ['mpich', 'pmpich'],
                           ['mpich', 'rt'],
                           ['mpich', 'pmpich', 'rt'],
-                          ['mpi']]
+                          ['mpi'],
+                          ['lam', 'mpi']]
+        self.shared_libraries = ['mpich', 'pmpich', 'mpi', 'lam']
         self.require_shared = True
-        self.use_rpath = True
+        self.symbols = [(['MPI_Init', 'MPI_Finalize'], '')]
+        self.symbol_calls = ['%s(&argc, &argv);', '%s();']
 
-    def validate_location(self, location):
-        for lib_dir in location[2]:
-            shared_dir = os.path.join(lib_dir, 'shared')
-            path = os.path.join(location[0], shared_dir)
-            if os.path.exists(path):
-                location[2] += [shared_dir]
-        return [1, '', '']
+    def generate_locations(self):
+        for loc in SConfig.Package.generate_locations(self):
+            for lib_dir in loc[2]:
+                shared_dir = os.path.join(lib_dir, 'shared')
+                path = os.path.join(loc[0], shared_dir)
+                if os.path.exists(path):
+                    loc[2] = [shared_dir] + loc[2]
+            yield loc
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/OSMesa.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/OSMesa.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,8 @@
+import os
+import SConfig
+
+class OSMesa(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.libraries = [['GL', 'GLU']]
+        self.have_define = 'HAVE_MESA'
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/OpenGL.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/OpenGL.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,11 @@
+import os
+import SConfig
+
+class OpenGL(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.header_sub_dir = 'GL'
+        self.headers = [['gl.h', 'glu.h']]
+        self.libraries = [['GL', 'GLU']]
+        self.frameworks = [['OpenGL']]
+        self.have_define = 'HAVE_GL'
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/PETSc.py
--- a/config/SConfig/packages/PETSc.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/packages/PETSc.py	Mon Apr 07 00:36:43 2008 +0000
@@ -1,10 +1,10 @@ import os
-import os
+import os, re
 import SConfig
 
 class PETSc(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.require(SConfig.packages.MPI)
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.dependency(SConfig.packages.MPI)
         self.base_patterns = ['petsc*', 'PETSC*', 'PETSc*']
         self.header_sub_dir = 'petsc'
         self.headers = [['petsc.h',
@@ -14,47 +14,48 @@ class PETSc(SConfig.Package):
                            'petscmat', 'petscvec',
                            'petscdm', 'petsc',]]
         self.require_shared = True
-        self.use_rpath = True
-        self.have_define = 'HAVE_PETSC'
+        self.symbols = [(['PetscInitialize', 'PetscFinalize'], '')]
+        self.symbol_calls = ['%s(&argc, &argv, NULL, NULL);', '%s();']
 
-        # Other stuff.
+        # Will be set after configuration.
         self.arch = ''
 
-    def validate_location(self, location):
-        # Must have a base directory.
-        if not location[0]:
-            return (1, '', '')
+    def generate_locations(self):
+        for loc in SConfig.Package.generate_locations(self):
+            if not loc[0]:
+                yield loc
+                continue
 
-        # Get the architecture.
-        arch = self.get_petsc_arch(location[0])
-        if not arch:
-            return (0, '', 'Could not read architecture from petscconf.')
-        self.arch = arch
+            arch = self.get_arch(loc[0])
+            if not arch:
+                yield loc
+                continue
+            self.arch = arch
 
-        # Add the bmake/arch include directory.
-        hdr_dir = os.path.join('bmake', arch)
-        if not os.path.exists(os.path.join(location[0], hdr_dir)):
-            return [0, '', 'No bmake/<arch> directory.']
-        if hdr_dir not in location[1]:
-            location[1] += [hdr_dir]
+            # Add the bmake/arch include directory.
+            hdr_dir = os.path.join('bmake', arch)
+            if not os.path.exists(os.path.join(loc[0], hdr_dir)):
+                continue
+            if hdr_dir not in loc[1]:
+                loc[1] += [hdr_dir]
 
-        # Add the lib/arch library directory.
-        if 'lib' in location[2]:
-            location[2].remove('lib')
-        lib_dir = os.path.join('lib', arch)
-        if not os.path.exists(os.path.join(location[0], lib_dir)):
-            return [0, '', 'No lib/<arch> directory.']
-        if lib_dir not in location[2]:
-            location[2] += [lib_dir]
+            # Add the lib/arch library directory.
+            if 'lib' in loc[2]:
+                loc[2].remove('lib')
+            lib_dir = os.path.join('lib', arch)
+            if not os.path.exists(os.path.join(loc[0], lib_dir)):
+                continue
+            if lib_dir not in loc[2]:
+                loc[2] += [lib_dir]
 
-        return [1, '', '']
+            # Parse extra libraries.
+            extra_lib_dirs, extra_libs = self.get_extra_libraries(loc[0])
+            if extra_lib_dirs: loc[2] += extra_lib_dirs
+            if extra_libs: self.extra_libraries += extra_libs
 
-    def get_headers_error_message(self, console):
-        if console.find('MPI_') != -1:
-            return 'Incompatible implementation of MPI.'
-        return ''
+            yield loc
 
-    def get_petsc_arch(self, base_dir):
+    def get_arch(self, base_dir):
         petscconf = os.path.join(base_dir, 'bmake',
                                  'petscconf')
         if not os.path.exists(petscconf):
@@ -63,3 +64,58 @@ class PETSc(SConfig.Package):
         arch = f.readline().split('=')[1][:-1]
         f.close()
         return arch
+
+    def get_extra_libraries(self, base_dir):
+        petscconf = os.path.join(base_dir, 'bmake', self.arch, 'petscconf')
+        if not os.path.exists(petscconf): return ([], [])
+        f = file(petscconf, 'r')
+        line_dict = {}
+        for line in f.readlines():
+            sides = line.split('=')
+            line_dict[sides[0].strip()] = sides[1].strip()
+        f.close()
+        if 'PACKAGES_LIBS' not in line_dict: return ([], [])
+        lib_string = line_dict['PACKAGES_LIBS']
+        lib_string = self.subst(lib_string, line_dict)
+
+        extra_lib_dirs = []
+        extra_libs = []
+        for string in lib_string.split(' '):
+            if string[:len(self.env['LIBLINKPREFIX'])] == self.env['LIBLINKPREFIX']:
+                extra_libs += [string[len(self.env['LIBLINKPREFIX']):]]
+            elif string[:len(self.env['LIBDIRPREFIX'])] == self.env['LIBDIRPREFIX']:
+                extra_lib_dirs += [string[len(self.env['LIBDIRPREFIX']):]]
+        return (extra_lib_dirs, extra_libs)
+
+    def subst(self, line, line_dict):
+        inp = [w.strip() for w in line.split()]
+        out = []
+        while len(inp):
+            w = inp[0]
+            inp = inp[1:]
+            if self.is_macro(w):
+                new_line = self.expand_macro(w, line_dict)
+                new_words = [nw.strip() for nw in new_line.split()]
+                inp = new_words + inp
+            else:
+                out += [w]
+        return ' '.join(out)
+
+    def expand_macro(self, macro, line_dict):
+        if macro[:2] == '${' and macro[-1:] == '}':
+            macro = macro[2:-1]
+        elif macro[0] == '$':
+            macro = macro[1:]
+        if macro not in line_dict: return ''
+        return line_dict[macro]
+
+    def is_macro(self, word):
+        if (word[:2] == '${' and word[-1:] == '}') or word[0] == '$':
+            return True
+        return False
+
+    def get_check_headers_fail_reason(self, fail_logs):
+        for log in fail_logs:
+            if log.find('MPI_') != -1:
+                return 'Selected MPI implementation incompatible.'
+        return ''
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/PETScExt.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/PETScExt.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,46 @@
+import os
+import SConfig
+
+class PETScExt(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.pkg_petsc = self.dependency(SConfig.packages.PETSc)
+        self.base_patterns = ['petscext*', 'PETSCEXT*', 'PETScExt*']
+        self.header_sub_dir = 'petsc'
+        self.headers = [['petscext.h',
+                         'petscext_vec.h', 'petscext_mat.h',
+                         'petscext_ksp.h', 'petscext_snes.h']]
+        self.libraries = [['petscext_snes', 'petscext_ksp', 'petscext_pc',
+                           'petscext_mat', 'petscext_vec',
+                           'petscext_utils']]
+        self.require_shared = True
+        self.use_rpath = True
+        self.have_define = 'HAVE_PETSCEXT'
+
+    def generate_locations(self):
+        for loc in SConfig.Package.generate_locations(self):
+            if not loc[0]:
+                yield loc
+                continue
+
+            # Just use whatever architecture PETSc uses.
+            arch = self.pkg_petsc.arch
+            self.arch = arch
+
+            # Add the bmake/arch include directory.
+            hdr_dir = os.path.join('bmake', arch)
+            if not os.path.exists(os.path.join(loc[0], hdr_dir)):
+                continue
+            if hdr_dir not in loc[1]:
+                loc[1] += [hdr_dir]
+
+            # Add the lib/arch library directory.
+            if 'lib' in loc[2]:
+                loc[2].remove('lib')
+            lib_dir = os.path.join('lib', arch)
+            if not os.path.exists(os.path.join(loc[0], lib_dir)):
+                continue
+            if lib_dir not in loc[2]:
+                loc[2] += [lib_dir]
+
+            yield loc
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/PICellerator.py
--- a/config/SConfig/packages/PICellerator.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/packages/PICellerator.py	Mon Apr 07 00:36:43 2008 +0000
@@ -2,11 +2,9 @@ import SConfig
 import SConfig
 
 class PICellerator(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.require(SConfig.packages.StGermain)
-        self.require(SConfig.packages.StgDomain)
-        self.require(SConfig.packages.StgFEM)
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.dependency(SConfig.packages.StgFEM)
         self.base_patterns = ['PICellerator*']
         self.headers = [[os.path.join('PICellerator', 'PICellerator.h')]]
         self.libraries = [['PICellerator']]
@@ -20,9 +18,3 @@ StGermain_Finalise();
 StGermain_Finalise();
 MPI_Finalize();'''
         self.symbol_calls = ['%s(&argc, &argv);', '%s();']
-        self.require_shared = True
-        self.use_rpath = True
-
-    def get_run_error_message(self, console):
-        if len(console):
-            return 'Incompatible libraries, check \'config.log\'.'
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/SDL.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/SDL.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,11 @@
+import os
+import SConfig
+
+class SDL(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.header_sub_dir = 'SDL'
+        self.headers = [['SDL.h'],
+                        ['SDL/SDL.h']] # For framework.
+        self.libraries = [['SDL']]
+        self.frameworks = [['SDL', 'Cocoa']]
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/SVNRevision.py
--- a/config/SConfig/packages/SVNRevision.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/packages/SVNRevision.py	Mon Apr 07 00:36:43 2008 +0000
@@ -1,25 +1,35 @@ import os
 import os
 import SConfig
 
-class SVNRevision(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
+class SVNRevision(SConfig.Node):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Node.__init__(self, scons_env, scons_opts, required)
         self.checks = [self.extract_revision]
         self.define_name = 'VERSION'
         self.checkout_path = os.getcwd()
 
+        # Will be set after configuration.
+        self.revision = 0
+
     def extract_revision(self):
-        print 'Extracting subversion revision number ... ',
         svn_path = os.path.join(self.checkout_path, '.svn', 'entries')
         if not os.path.exists(svn_path):
-            print '\n   Could not find .svn directory.'
-            return [0, '', '']
+            return [0, '', 'Could not find .svn directory']
         f = file(svn_path, 'r')
-        f.readline()
-        f.readline()
-        f.readline()
-        ver = self.env['ESCAPE']('"' + str(int(f.readline())) + '"')
+	all_lines = f.readlines()
         f.close()
-        self.cpp_defines += [(self.define_name, ver)]
-        print 'okay'
-        return [1, '', '']
+
+	for l in all_lines:
+            ind = l.rfind('revision=')
+            if ind != -1:
+                self.revision = int(l[ind + 10:l.rfind('"')])
+                return True
+
+        self.revision = int(all_lines[3])
+        return True
+
+    def enable(self, scons_env, old_state=None):
+        SConfig.Node.enable(self, scons_env, old_state)
+        self.backup_variable(scons_env, 'CPPDEFINES', old_state)
+        ver = scons_env['ESCAPE']('"' + str(self.revision) + '"')
+        scons_env.AppendUnique(CPPDEFINES=[(self.define_name, ver)])
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/StGermain.py
--- a/config/SConfig/packages/StGermain.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/packages/StGermain.py	Mon Apr 07 00:36:43 2008 +0000
@@ -2,11 +2,12 @@ import SConfig
 import SConfig
 
 class StGermain(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.require(SConfig.packages.cmath)
-        self.require(SConfig.packages.libXML2)
-        self.require(SConfig.packages.MPI)
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.dependency(SConfig.packages.cmath)
+        self.dependency(SConfig.packages.libXML2)
+        self.dependency(SConfig.packages.MPI)
+        self.dependency(SConfig.packages.SVNRevision)
         self.base_patterns = ['StGermain*']
         self.headers = [[os.path.join('StGermain', 'StGermain.h')]]
         self.libraries = [['StGermain']]
@@ -14,9 +15,22 @@ class StGermain(SConfig.Package):
         self.symbol_setup = 'MPI_Init(&argc, &argv);'
         self.symbol_teardown = 'MPI_Finalize();'
         self.symbol_calls = ['%s(&argc, &argv);', '%s();']
-        self.require_shared = True
-        self.use_rpath = True
 
-    def get_run_error_message(self, console):
-        if len(console):
-            return 'Incompatible libraries, check \'config.log\'.'
+    def enable(self, scons_env, old_state=None):
+        SConfig.Package.enable(self, scons_env, old_state)
+        if self.base_dir:
+            script = os.path.join(self.base_dir, 'script', 'pcu', 'scons.py')
+            if os.path.exists(script):
+                self.backup_variable(scons_env, 'CONFIGSCRIPTS', old_state)
+                scons_env.AppendUnique(CONFIGVARS=['CONFIGSCRIPTS'])
+                scons_env.AppendUnique(CONFIGSCRIPTS=[script])
+                env = scons_env
+                scons_env.SConscript(script, 'env')
+
+            script = os.path.join(self.base_dir, 'script', 'StGermain', 'scons.py')
+            if os.path.exists(script):
+                self.backup_variable(scons_env, 'CONFIGSCRIPTS', old_state)
+                scons_env.AppendUnique(CONFIGVARS=['CONFIGSCRIPTS'])
+                scons_env.AppendUnique(CONFIGSCRIPTS=[script])
+                env = scons_env
+                scons_env.SConscript(script, 'env')
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/StgDomain.py
--- a/config/SConfig/packages/StgDomain.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/packages/StgDomain.py	Mon Apr 07 00:36:43 2008 +0000
@@ -2,9 +2,11 @@ import SConfig
 import SConfig
 
 class StgDomain(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.require(SConfig.packages.StGermain)
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.dependency(SConfig.packages.StGermain)
+        self.dependency(SConfig.packages.BlasLapack)
+        self.dependency(SConfig.packages.HDF5, False)
         self.base_patterns = ['StgDomain*']
         self.headers = [[os.path.join('StgDomain', 'StgDomain.h')]]
         self.libraries = [['StgDomain']]
@@ -16,9 +18,3 @@ MPI_Finalize();
 MPI_Finalize();
 '''
         self.symbol_calls = ['%s(&argc, &argv);', '%s();']
-        self.require_shared = True
-        self.use_rpath = True
-
-    def get_run_error_message(self, console):
-        if len(console):
-            return 'Incompatible libraries, check \'config.log\'.'
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/StgFEM.py
--- a/config/SConfig/packages/StgFEM.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/packages/StgFEM.py	Mon Apr 07 00:36:43 2008 +0000
@@ -2,10 +2,11 @@ import SConfig
 import SConfig
 
 class StgFEM(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.require(SConfig.packages.StGermain)
-        self.require(SConfig.packages.StgDomain)
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.dependency(SConfig.packages.StgDomain)
+        petsc = self.dependency(SConfig.packages.PETSc)
+        petsc.have_define = 'HAVE_PETSC'
         self.base_patterns = ['StgFEM*']
         self.headers = [[os.path.join('StgFEM', 'StgFEM.h')]]
         self.libraries = [['StgFEM']]
@@ -17,9 +18,3 @@ StGermain_Finalise();
 StGermain_Finalise();
 MPI_Finalize();'''
         self.symbol_calls = ['%s(&argc, &argv);', '%s();']
-        self.require_shared = True
-        self.use_rpath = True
-
-    def get_run_error_message(self, console):
-        if len(console):
-            return 'Incompatible libraries, check \'config.log\'.'
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/X11.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/X11.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,12 @@
+import os
+import SConfig
+
+class X11(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.header_sub_dir = 'X11'
+        self.headers = [['Xlib.h']]
+        self.libraries = [['X11', 'Xmu']]
+        self.symbols = [(['XOpenDisplay'], '')]
+        self.symbol_setup = 'void* display;'
+        self.symbol_calls = ['display = %s(NULL);']
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/__init__.py
--- a/config/SConfig/packages/__init__.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/packages/__init__.py	Mon Apr 07 00:36:43 2008 +0000
@@ -1,6 +1,8 @@ from libXML2 import libXML2
+from CompilerFlags import CompilerFlags
 from libXML2 import libXML2
 from MPI import MPI
 from PETSc import PETSc
+from PETScExt import PETScExt
 from cmath import cmath
 from SVNRevision import SVNRevision
 from BlasLapack import BlasLapack
@@ -10,3 +12,13 @@ from PICellerator import PICellerator
 from PICellerator import PICellerator
 from dl import dl
 from OpenGL import OpenGL
+from OSMesa import OSMesa
+from SDL import SDL
+from libPNG import libPNG
+from libJPEG import libJPEG
+from libTIFF import libTIFF
+from libFAME import libFAME
+from libavcodec import libavcodec
+from HDF5 import HDF5
+from X11 import X11
+from pcu import pcu
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/cmath.py
--- a/config/SConfig/packages/cmath.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/packages/cmath.py	Mon Apr 07 00:36:43 2008 +0000
@@ -2,6 +2,7 @@ import SConfig
 import SConfig
 
 class cmath(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.dependency(SConfig.packages.CompilerFlags)
         self.libraries = [['m']]
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/dl.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/dl.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,12 @@
+import os
+import SConfig
+
+class dl(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.dependency(SConfig.packages.CompilerFlags)
+        self.headers = [['dlfcn.h']]
+        self.libraries = [['dl']]
+
+    def setup(self):
+        SConfig.Node.setup(self)
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/libFAME.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/libFAME.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,9 @@
+import os
+import SConfig
+
+class libFAME(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.headers = [['fame.h']]
+        self.libraries = [['fame']]
+        self.have_define = 'HAVE_FAME'
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/libJPEG.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/libJPEG.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,9 @@
+import os
+import SConfig
+
+class libJPEG(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.headers = [['jpeglib.h']]
+        self.libraries = [['jpeg']]
+        self.have_define = 'HAVE_JPEG'
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/libPNG.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/libPNG.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,9 @@
+import os
+import SConfig
+
+class libPNG(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.headers = [['png.h']]
+        self.libraries = [['png']]
+        self.have_define = 'HAVE_PNG'
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/libTIFF.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/libTIFF.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,9 @@
+import os
+import SConfig
+
+class libTIFF(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.headers = [['tiff.h']]
+        self.libraries = [['tiff']]
+        self.have_define = 'HAVE_TIFF'
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/libXML2.py
--- a/config/SConfig/packages/libXML2.py	Thu Apr 03 07:05:15 2008 +0000
+++ b/config/SConfig/packages/libXML2.py	Mon Apr 07 00:36:43 2008 +0000
@@ -2,8 +2,9 @@ import SConfig
 import SConfig
 
 class libXML2(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.dependency(SConfig.packages.CompilerFlags)
         self.header_sub_dir = 'libxml2'
         self.headers = [[os.path.join('libxml', 'parser.h')]]
         self.libraries = [['xml2']]
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/libavcodec.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/libavcodec.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,10 @@
+import os
+import SConfig
+
+class libavcodec(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.header_sub_dir = 'ffmpeg'
+        self.headers = [['avcodec.h']]
+        self.libraries = [['avcodec']]
+        self.have_define = 'HAVE_AVCODEC'
diff -r 085c968bf217 -r a8dba1da20c0 config/SConfig/packages/pcu.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/packages/pcu.py	Mon Apr 07 00:36:43 2008 +0000
@@ -0,0 +1,29 @@
+import os
+import SConfig
+
+class pcu(SConfig.Package):
+    def __init__(self, scons_env, scons_opts, required=False):
+        SConfig.Package.__init__(self, scons_env, scons_opts, required)
+        self.dependency(SConfig.packages.MPI)
+        self.headers = [[os.path.join('pcu', 'pcu.h')]]
+        self.libraries = [['pcu']]
+        self.checks += [self.check_scons_script]
+
+        self.scons_script = ''
+
+    def check_scons_script(self):
+        if self.base_dir:
+            script = os.path.join(self.base_dir, 'script', 'pcu', 'scons.py')
+            if os.path.exists(script):
+                self.scons_script = script
+                self.ctx.Display('      Found SCons builder script.\n')
+        return True
+
+    def enable(self, scons_env, old_state=None):
+        SConfig.Package.enable(self, scons_env, old_state)
+        if self.scons_script:
+            self.backup_variable(scons_env, 'CONFIGSCRIPTS', old_state)
+            scons_env.AppendUnique(CONFIGVARS=['CONFIGSCRIPTS'])
+            scons_env.AppendUnique(CONFIGSCRIPTS=[self.scons_script])
+            env = scons_env
+            scons_env.SConscript(self.scons_script, 'env')
diff -r 085c968bf217 -r a8dba1da20c0 config/packages/StgDomain.py
--- a/config/packages/StgDomain.py	Thu Apr 03 07:05:15 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-import os
-import SConfig
-import SCons.Script
-
-class StgDomain(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.checks = [self.setup_environment]
-        self.dependencies = [SConfig.packages.cmath,
-                             SConfig.packages.libXML2,
-                             SConfig.packages.MPI,
-                             SConfig.packages.SVNRevision,
-                             SConfig.packages.BlasLapack,
-                             SConfig.packages.StGermain]
-        if self.opts:
-            self.opts.AddOptions(
-                SCons.Script.BoolOption('debug',
-                                        'Enable debugging', 1),
-                SCons.Script.BoolOption('staticLibraries',
-                                        'Build static libraries only', 0),
-                ('buildPath', 'Temporary build path', 'build'))
-
-    def setup_environment(self):
-        # Setup the build path.
-        if not os.path.isabs(self.env['buildPath']):
-            self.env['buildPath'] = '#' + self.env['buildPath']
-
-        # Setup LIB_DIR.
-        lib_dir = os.path.join(self.env['buildPath'], 'lib')
-        abs_lib_dir = self.env.Dir(lib_dir).abspath
-        self.env.AppendUnique(CPPDEFINES=[('LIB_DIR',
-                                           self.env['ESCAPE']('"' + abs_lib_dir + '"'))])
-        self.env.PrependUnique(LIBPATH=[lib_dir])
-
-        # Setup the RPATH.
-        self.env.PrependUnique(RPATH=[self.env.Dir(abs_lib_dir).abspath])
-
-        # Setup the module extension.
-        ext = self.env['ESCAPE']('"' + self.env['SHLIBSUFFIX'][1:] + '"')
-        self.env.Append(CPPDEFINES=[('MODULE_EXT', ext)])
-
-        # Setup the include paths.
-        inc_path = os.path.join(self.env['buildPath'], 'include')
-        self.env.AppendUnique(CPPPATH=[inc_path])
-        self.env.AppendUnique(CPPPATH=[os.path.join(inc_path, 'StgDomain')])
-
-        # Setup debugging.
-        if self.env['debug']:
-            self.env.MergeFlags('-g')
-
-        # Setup 64 bit builds.
-        if platform.architecture()[0].find('64') != -1:
-            self.env.MergeFlags('-m64')
-
-        return [1, '', '']
diff -r 085c968bf217 -r a8dba1da20c0 config/packages/__init__.py
--- a/config/packages/__init__.py	Thu Apr 03 07:05:15 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-from StgDomain import StgDomain



More information about the CIG-COMMITS mailing list