[cig-commits] commit: Big cleanup on the build system including the

Mercurial hg at geodynamics.org
Mon Nov 24 11:30:54 PST 2008


changeset:   85:9830278ecde3
user:        LukeHodkinson
date:        Mon Apr 07 00:37:45 2008 +0000
files:       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/PICellerator.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 53cc6c038671 -r 9830278ecde3 SConscript
--- a/SConscript	Fri Mar 28 06:41:03 2008 +0000
+++ b/SConscript	Mon Apr 07 00:37:45 2008 +0000
@@ -2,36 +2,73 @@ Import('env')
 Import('env')
 
 env = env.Copy()
-env.AppendUnique(CPPPATH=[os.path.join(env['buildPath'], # Add PICellerator include path.
-                                       'include',
-                                       'PICellerator')])
-env.project_name = 'PICellerator' # Need a project name.
-env.clear_all() # ... so that our structures are ready.
+env.AppendUnique(CPPPATH=[env.get_build_path('include/PICellerator')])
 
-env.build_directory('Voronoi')
-env.build_directory('PopulationControl')
-env.build_directory('Weights')
-env.build_directory('MaterialPoints')
-env.build_directory('Utils')
+# Collect our inputs from the directory structure.
+bases = ['Voronoi', 'PopulationControl', 'Weights', 'MaterialPoints', 'Utils']
+src_objs = []
+suite_hdrs = []
+suite_objs = []
+for base in bases:
+    env.build_files(env.glob(base + '/src/*.def'), 'include/PICellerator/' + base)
+    env.build_headers(env.glob(base + '/src/*.h'), 'include/PICellerator/' + base)
+    src_objs += env.build_sources(env.glob(base + '/src/*.c'), 'PICellerator/' + base)
+    src_objs += env.build_metas(env.glob(base + '/src/*.meta'), 'PICellerator/' + base)
+    suite_hdrs += env.glob(base + '/tests/*Suite.h')
+    suite_objs += env.build_sources(env.glob(base + '/tests/*Suite.c'), 'PICellerator/' + base)
 
-env.build_headers(env.glob('libPICellerator/src/*.h'), 'PICellerator')
-env.build_objects(env.glob('libPICellerator/src/*.c'), 'libPICellerator')
-env.build_metadata(env.glob('libPICellerator/src/*.meta'), 'libPICellerator')
+env.build_headers(env.glob('libPICellerator/src/*.h'), 'include/PICellerator')
+src_objs += env.build_sources(env.glob('libPICellerator/src/*.c'), 'PICellerator/libPICellerator')
+src_objs += env.build_sources(env.glob('libPICellerator/src/*.meta'), 'PICellerator/libPICellerator')
 
-env.build_library(env.get_hnodes(env.SharedObject), 'PICellerator')
+# Build library.
+if env['static_libraries']:
+    env.Library(env.get_build_path('lib/PICellerator'), src_objs)
+if env['shared_libraries']:
+    env.SharedLibrary(env.get_build_path('lib/PICellerator'), src_objs)
 
-env.build_objects(env.glob('libPICellerator/Toolbox/*.c'), 'Toolbox')
-env.build_metadata(env.glob('libPICellerator/Toolbox/*.meta'), 'Toolbox')
-env.build_library(env.get_hnodes(env.SharedObject, 'Toolbox'),
-                  'PICellerator_Toolboxmodule', ['PICellerator'],
-                  True)
+# Build toolbox.
+if env['shared_libraries']:
+    objs = env.build_sources(env.glob('libPICellerator/Toolbox/*.c'),
+                             'PICellerator/libPICellerator/Toolbox')
+    objs += env.build_metas(env.glob('libPICellerator/Toolbox/*.meta'),
+                            'PICellerator/libPICellerator/Toolbox')
+    env.SharedLibrary(env.get_target_name('lib/PICellerator_Toolboxmodule'), objs,
+                      SHLIBPREFIX='',
+                      LIBPREFIXES=[env['LIBPREFIXES']] + [''],
+                      LIBS=['PICellerator'] + env.get('LIBS', []))
 
-env.build_tests(env.glob('libPICellerator/tests/test*.c'),
-                'PICellerator', libs='PICellerator')
+# Build plugins.
+if env['shared_libraries']:
+    plgn_bases = ['CalculateParticleDisplacement', 'MaterialCentroid']
+    for base in plgn_bases:
+        env.build_headers(env.glob('plugins/' + base + '/*.h'), 'include/PICellerator/' + base.split('/')[-1])
+        objs = env.build_sources(env.glob('plugins/' + base + '/*.c'), 'PICellerator/' + base)
+        name = 'PICellerator_' + base.split('/')[-1] + 'module'
+        env.SharedLibrary(env.get_build_path('lib/' + name), objs,
+                          SHLIBPREFIX='',
+                          LIBPREFIXES=[env['LIBPREFIXES']] + [''],
+                          LIBS=['PICellerator'] + env.get('LIBS', []))
 
-env.build_plugin('plugins/CalculateParticleDisplacement',
-                 'CalculateParticleDisplacement')
-env.build_plugin('plugins/Output/MaterialCentroid',
-                 'Output/MaterialCentroid')
+# Build unit test runner.
+env['PCURUNNERINIT'] = ''
+env['PCURUNNERSETUP'] = """StGermain_Init( &argc, &argv );
+   StgDomain_Init( &argc, &argv );
+   StgFEM_Init( &argc, &argv );
+   PICellerator_Init( &argc, &argv );"""
+env['PCURUNNERTEARDOWN'] = """PICellerator_Finalise();
+   StgFEM_Finalise();
+   StgDomain_Finalise();
+   StGermain_Finalise();"""
+runner_src = env.PCUSuiteRunner(env.get_build_path('PICellerator/testPICellerator.c'), suite_hdrs)
+runner_obj = env.SharedObject(runner_src)
+env.Program(env.get_build_path('bin/testPICellerator'),
+            runner_obj + suite_objs,
+            LIBS=['PICellerator', 'pcu'] + env.get('LIBS', []))
 
-env.build_xmls(env.glob('Apps/src/*.xml'), 'StGermain/PICellerator')
+# Copy over XML files.
+xml_bases = ['']
+for base in xml_bases:
+    dst = env.get_build_path('lib/StGermain/PICellerator/' + base)
+    for file in env.glob('Apps/src/' + base + '/*.xml'):
+        env.Install(dst, file)
diff -r 53cc6c038671 -r 9830278ecde3 SConstruct
--- a/SConstruct	Fri Mar 28 06:41:03 2008 +0000
+++ b/SConstruct	Mon Apr 07 00:37:45 2008 +0000
@@ -1,36 +1,43 @@ 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.PICellerator, 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.StgFEM)
+    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()
+    env.Append(CPPDEFINES=['HAVE_SCONS']) # Needed for old VMake.
+
+    #
+    # INSERT TARGETS HERE.
+    #
 
     SConscript('SConscript', exports='env')
diff -r 53cc6c038671 -r 9830278ecde3 StgSCons
--- a/StgSCons	Fri Mar 28 06:41:03 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 53cc6c038671 -r 9830278ecde3 config/SConfig/Node.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/Node.py	Mon Apr 07 00:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/Package.py
--- a/config/SConfig/Package.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/Package.py	Mon Apr 07 00:37:45 2008 +0000
@@ -1,316 +1,294 @@ import os, platform, glob
 import os, platform, glob
 import SCons.Script
-
-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()
-
-        # 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
-
-        # Dependency list.
-        self.dependencies      = [] #[<module>]
-
-        # Language options.
-        self.language          = 'C' # 'C' | 'CXX' | 'F77'
-        self.have_define       = ''
+import SConfig
+
+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.dependency_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         = False
-        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.libs = []
         self.have_shared = None
         self.fworks = []
-        self.state = {}
+        self.cpp_defines = []
 
         # Private stuff.
-        self.sconf = None
-        self.env = env
-        self.opts = options
+        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()
+
+    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.header_sub_dir:
-                self.sub_dirs += [[[os.path.join('include', self.header_sub_dir)], ['lib']]]
-            if self.bits == 64:
-                if self.header_sub_dir:
-                    self.sub_dirs = [[[os.path.join('include', self.header_sub_dir)],
-                                      ['lib64']],
-                                     [[os.path.join('include', self.header_sub_dir)],
-                                      [os.path.join('lib', '64')]]] + self.sub_dirs
+            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.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
-
-        # Process dependencies first.
-        self.process_dependencies()
-
-        # Perfrom actual configuration.
-        for check in self.checks:
-            result = check()
-            if not result[0]:
+        SConfig.Node.configure(self, scons_ctx)
+
+    def setup(self):
+        SConfig.Node.setup(self)
+        if self.require_shared:
+            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.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 setup_dependencies(self):
-        # If the package doesn't yet exist, create it.
-        for pkg_module in self.dependencies:
-            if pkg_module not in self.env.packages:
-                self.env.Package(pkg_module, self.opts)
-
-    def process_dependencies(self):
-        """Ensure all dependencies have been configured before this package."""
-        for pkg_module in self.dependencies:
-            # Configure the dependency now.
-            pkg = self.env.packages[pkg_module]
-            pkg.sconf = self.sconf
-            pkg.configure(self.ctx)
-
-    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."""
-        src = self.get_header_source()
-        result = self.run_scons_cmd(self.ctx.TryCompile, src, '.c')
-        msg = self.get_headers_error_message(result[1])
-        if not msg:
-            msg = 'Failed to locate headers.'
-        return [result[0], '', msg]
-
-    def check_libs(self, location, libs):
+        fail_logs = []
+        for hdrs in self.headers:
+            src = self.get_header_source(hdrs)
+            result = self.compile_source(src)
+            if result[0]:
+                self.hdrs = list(hdrs)
+                break
+            fail_logs += [result[1]]
+        if not result[0]:
+            msg = self.get_check_headers_fail_reason(fail_logs)
+            if not msg:
+                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."""
-        # TODO
-        return [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')
-        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, '', '']
+            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, '', '']
+        src = self.get_header_source()
+        src += """
+int main(int argc, char* argv[]) {
+  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
@@ -346,6 +324,8 @@ class Package(object):
                 if os.path.exists(dir) and os.path.isdir(dir):
                     for hdr, lib in self.combine_sub_dirs(dir):
                         yield [dir, list(hdr), list(lib), list(fw)]
+                        for sub in self.combine_header_sub_dir(dir, hdr):
+                            yield [dir, list(sub), list(lib), list(fw)]
 
     def combine_sub_dirs(self, base_dir):
         """Take a base directory and combine it with the set of header and library
@@ -377,84 +357,116 @@ class Package(object):
 
             yield (hdr_dirs, lib_dirs)
 
+    def combine_header_sub_dir(self, base_dir, hdr_dirs):
+        if not self.header_sub_dir or not hdr_dirs:
+            return
+        cand = [os.path.join(h, self.header_sub_dir) for h in hdr_dirs if h]
+        for d in cand:
+            path = os.path.join(base_dir, d)
+            if not (os.path.exists(path) and os.path.isdir(path)):
+                return
+        yield cand
+
     def join_sub_dir(self, base_dir, sub_dir):
         if os.path.isabs(sub_dir):
             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)
-
-    def get_header_source(self):
+            self.backup_variable(scons_env, 'LIBS', old_state)
+            scons_env.PrependUnique(LIBS=self.libs)
+
+    def get_all_headers(self, headers):
+        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]
+
+    def get_header_source(self, headers=None):
         src = '#include<stdlib.h>\n#include<stdio.h>\n#include<string.h>\n'
-        for h in self.dependency_headers + self.headers:
+        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 h in hdrs:
             src += '#include<' + h + '>\n'
         return src
 
@@ -471,39 +483,3 @@ class Package(object):
             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 53cc6c038671 -r 9830278ecde3 config/SConfig/Platform.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/Platform.py	Mon Apr 07 00:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/Project.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config/SConfig/Project.py	Mon Apr 07 00:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/SConscript
--- a/config/SConfig/SConscript	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/SConscript	Mon Apr 07 00:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/__init__.py
--- a/config/SConfig/__init__.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/__init__.py	Mon Apr 07 00:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/packages/BlasLapack.py
--- a/config/SConfig/packages/BlasLapack.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/packages/BlasLapack.py	Mon Apr 07 00:37:45 2008 +0000
@@ -2,10 +2,9 @@ import SConfig
 import SConfig
 
 class BlasLapack(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.setup_search_defaults()
-        self.setup_options()
+    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']]
@@ -50,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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/packages/MPI.py
--- a/config/SConfig/packages/MPI.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/packages/MPI.py	Mon Apr 07 00:37:45 2008 +0000
@@ -2,17 +2,28 @@ 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.setup_search_defaults()
-        self.setup_options()
-        self.base_patterns = ['mpich*', 'MPICH*']
-        self.headers = ['mpi.h']
+        self.headers = [['mpi.h']]
         self.libraries = [['mpich'],
                           ['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 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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/packages/PETSc.py
--- a/config/SConfig/packages/PETSc.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/packages/PETSc.py	Mon Apr 07 00:37:45 2008 +0000
@@ -1,62 +1,61 @@ import os
-import os
+import os, re
 import SConfig
 
 class PETSc(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.MPI)
+        self.base_patterns = ['petsc*', 'PETSC*', 'PETSc*']
         self.header_sub_dir = 'petsc'
-        self.setup_search_defaults()
-        self.setup_options()
-        self.dependencies = [SConfig.packages.MPI]
-        self.base_patterns = ['petsc*', 'PETSC*', 'PETSc*']
-        self.headers = ['petsc.h',
-                        'petscvec.h', 'petscmat.h',
-                        'petscksp.h', 'petscsnes.h']
-        self.libraries = [['petsc', 'petscdm',
-                           'petscvec', 'petscmat',
-                           'petscksp', 'petscsnes']]
+        self.headers = [['petsc.h',
+                         'petscvec.h', 'petscmat.h',
+                         'petscksp.h', 'petscsnes.h']]
+        self.libraries = [['petscsnes', 'petscksp',
+                           '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):
@@ -65,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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/packages/PICellerator.py
--- a/config/SConfig/packages/PICellerator.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/packages/PICellerator.py	Mon Apr 07 00:37:45 2008 +0000
@@ -2,16 +2,11 @@ import SConfig
 import SConfig
 
 class PICellerator(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.setup_search_defaults()
-        self.setup_options()
-        self.dependencies = [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.StgFEM)
         self.base_patterns = ['PICellerator*']
-        self.headers = [os.path.join('PICellerator', 'PICellerator.h')]
-        self.dependency_headers = [os.path.join('StGermain', 'StGermain.h'),
-                                   os.path.join('StgDomain', 'StgDomain.h'),
-                                   os.path.join('StgFEM', 'StgFEM.h')]
+        self.headers = [[os.path.join('PICellerator', 'PICellerator.h')]]
         self.libraries = [['PICellerator']]
         self.symbols = [(['PICellerator_Init', 'PICellerator_Finalise'], '')]
         self.symbol_setup = '''MPI_Init(&argc, &argv);
@@ -23,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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/packages/SVNRevision.py
--- a/config/SConfig/packages/SVNRevision.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/packages/SVNRevision.py	Mon Apr 07 00:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/packages/StGermain.py
--- a/config/SConfig/packages/StGermain.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/packages/StGermain.py	Mon Apr 07 00:37:45 2008 +0000
@@ -2,23 +2,35 @@ import SConfig
 import SConfig
 
 class StGermain(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.setup_search_defaults()
-        self.setup_options()
-        self.dependencies = [SConfig.packages.cmath,
-                             SConfig.packages.libXML2,
-                             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.headers = [[os.path.join('StGermain', 'StGermain.h')]]
         self.libraries = [['StGermain']]
         self.symbols = [(['StGermain_Init', 'StGermain_Finalise'], '')]
         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 53cc6c038671 -r 9830278ecde3 config/SConfig/packages/StgDomain.py
--- a/config/SConfig/packages/StgDomain.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/packages/StgDomain.py	Mon Apr 07 00:37:45 2008 +0000
@@ -2,14 +2,13 @@ import SConfig
 import SConfig
 
 class StgDomain(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.setup_search_defaults()
-        self.setup_options()
-        self.dependencies = [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.dependency_headers = [os.path.join('StGermain', 'StGermain.h')]
+        self.headers = [[os.path.join('StgDomain', 'StgDomain.h')]]
         self.libraries = [['StgDomain']]
         self.symbols = [(['StgDomain_Init', 'StgDomain_Finalise'], '')]
         self.symbol_setup = '''MPI_Init(&argc, &argv);
@@ -19,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 53cc6c038671 -r 9830278ecde3 config/SConfig/packages/StgFEM.py
--- a/config/SConfig/packages/StgFEM.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/packages/StgFEM.py	Mon Apr 07 00:37:45 2008 +0000
@@ -2,15 +2,13 @@ import SConfig
 import SConfig
 
 class StgFEM(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.setup_search_defaults()
-        self.setup_options()
-        self.dependencies = [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.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.dependency_headers = [os.path.join('StGermain', 'StGermain.h'),
-                                   os.path.join('StgDomain', 'StgDomain.h')]
+        self.headers = [[os.path.join('StgFEM', 'StgFEM.h')]]
         self.libraries = [['StgFEM']]
         self.symbols = [(['StgFEM_Init', 'StgFEM_Finalise'], '')]
         self.symbol_setup = '''MPI_Init(&argc, &argv);
@@ -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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/packages/__init__.py
--- a/config/SConfig/packages/__init__.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/packages/__init__.py	Mon Apr 07 00:37:45 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
@@ -8,3 +10,15 @@ from StgDomain import StgDomain
 from StgDomain import StgDomain
 from StgFEM import StgFEM
 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 53cc6c038671 -r 9830278ecde3 config/SConfig/packages/cmath.py
--- a/config/SConfig/packages/cmath.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/packages/cmath.py	Mon Apr 07 00:37:45 2008 +0000
@@ -2,7 +2,7 @@ import SConfig
 import SConfig
 
 class cmath(SConfig.Package):
-    def __init__(self, env, options):
-        SConfig.Package.__init__(self, env, options)
-        self.setup_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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 config/SConfig/packages/libXML2.py
--- a/config/SConfig/packages/libXML2.py	Fri Mar 28 06:41:03 2008 +0000
+++ b/config/SConfig/packages/libXML2.py	Mon Apr 07 00:37:45 2008 +0000
@@ -2,10 +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.setup_search_defaults()
-        self.setup_options()
-        self.headers = [os.path.join('libxml', 'parser.h')]
+        self.headers = [[os.path.join('libxml', 'parser.h')]]
         self.libraries = [['xml2']]
diff -r 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 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:37:45 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 53cc6c038671 -r 9830278ecde3 config/packages/PICellerator.py
--- a/config/packages/PICellerator.py	Fri Mar 28 06:41:03 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-import os
-import SConfig
-import SCons.Script
-
-class PICellerator(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.PETSc,
-                             SConfig.packages.StGermain,
-                             SConfig.packages.StgDomain,
-                             SConfig.packages.StgFEM]
-        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, 'PICellerator')])
-
-        # 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 53cc6c038671 -r 9830278ecde3 config/packages/__init__.py
--- a/config/packages/__init__.py	Fri Mar 28 06:41:03 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-from PICellerator import PICellerator



More information about the CIG-COMMITS mailing list