From 014c22b40aad03af017c2b7eca41acd98cb74f3a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 30 Jan 2011 15:27:21 +0100 Subject: [PATCH] SCons: rework build directory configuration. All customisations to LuimieraEnvironment --- SConstruct | 60 +++++++++++++++----------- admin/scons/BuilderDoxygen.py | 4 +- admin/scons/Buildhelper.py | 72 ++++++++++++++++--------------- admin/scons/LumieraEnvironment.py | 19 +++++--- src/tool/SConscript | 8 ++-- tests/SConscript | 10 ++--- 6 files changed, 94 insertions(+), 79 deletions(-) diff --git a/SConstruct b/SConstruct index 3711f489e..8cf377233 100644 --- a/SConstruct +++ b/SConstruct @@ -23,17 +23,29 @@ #-----------------------------------Configuration -OPTIONSCACHEFILE = 'optcache' -CUSTOPTIONSFILE = 'custom-options' +TARGDIR = 'target' +VERSION = '0.1+pre.01' +TOOLDIR = './admin/scons' +SCRIPTDIR = './admin' +OPTCACHE = 'optcache' +CUSTOPTFILE = 'custom-options' +####### SRCDIR = 'src' -TARDIR = 'target' -LIBDIR = 'target/modules' -MODULES = 'modules' TESTDIR = 'tests' ICONDIR = 'icons' -VERSION = '0.1+pre.01' -TOOLDIR = './admin/scons' -SCRIPTDIR = './admin' +MODULES = 'modules' +LIBDIR = 'target/modules' +####### +buildExe = '#$TARGDIR' +buildLib = '#$TARGDIR/modules' +buildIcon = '#$TARGDIR/icons' +buildConf = '#$TARGDIR/config' +installExe = '#$DESTDIR/lib/lumiera' +installLib = '#$DESTDIR/lib/lumiera/modules' +installIcon = '#$DESTDIR/share/lumiera/icons' +installConf = '#$DESTDIR/share/lumiera/config' + +localDefinitions = locals() #-----------------------------------Configuration # NOTE: scons -h for help. @@ -55,10 +67,10 @@ from LumieraEnvironment import * ##################################################################### -def setupBasicEnvironment(): +def setupBasicEnvironment(localDefinitions): """ define cmdline options, build type decisions """ - EnsurePythonVersion(2,3) + EnsurePythonVersion(2,4) EnsureSConsVersion(1,0) Decider('MD5-timestamp') # detect changed files by timestamp, then do a MD5 @@ -66,21 +78,19 @@ def setupBasicEnvironment(): vars = defineCmdlineVariables() env = LumieraEnvironment(variables=vars ,toolpath = [TOOLDIR] - ,tools = ["default", "BuilderGCH", "BuilderDoxygen"] - ) - env.Tool("ToolDistCC") - env.Tool("ToolCCache") + ,pathConfig = extract_localPathDefs(localDefinitions) + ,TARGDIR = TARGDIR + ,DESTDIR = '$INSTALLDIR/$PREFIX' + ,VERSION = VERSION + ) handleVerboseMessages(env) env.Append ( CCCOM=' -std=gnu99') env.Append ( SHCCCOM=' -std=gnu99') # workaround for a bug: CCCOM currently doesn't honour CFLAGS, only CCFLAGS - env.Replace( VERSION=VERSION - , SRCDIR=SRCDIR - , TARDIR=TARDIR + env.Replace( SRCDIR=SRCDIR , LIBDIR=LIBDIR , MODULES=MODULES , ICONDIR=ICONDIR - , DESTDIR=env.subst('$INSTALLDIR/$PREFIX') , CPPPATH=["#"+SRCDIR] # used to find includes, "#" means always absolute to build-root , CPPDEFINES=['-DLUMIERA_VERSION='+VERSION ] # note: it's a list to append further defines , CCFLAGS='-Wall -Wextra ' @@ -102,7 +112,7 @@ def setupBasicEnvironment(): ,'LUMIERA_CONFIG_PATH=\\"$DESTDIR/share/lumiera/:.\\"') prepareOptionsHelp(vars,env) - vars.Save(OPTIONSCACHEFILE, env) + vars.Save(OPTCACHE, env) return env def appendCppDefine(env,var,cppVar, elseVal=''): @@ -148,7 +158,7 @@ def defineCmdlineVariables(): you may define custom variable settings in a separate file. Commandline will override both. """ - vars = Variables([OPTIONSCACHEFILE, CUSTOPTIONSFILE]) + vars = Variables([OPTCACHE, CUSTOPTFILE]) vars.AddVariables( ('ARCHFLAGS', 'Set architecture-specific compilation flags (passed literally to gcc)','') ,('CC', 'Set the C compiler to use.', 'gcc') @@ -311,7 +321,7 @@ def definePackagingTargets(env, artifacts): """ build operations and targets to be done /before/ compiling. things like creating a source tarball or preparing a version header. """ - pass + pass ## currently none @@ -337,7 +347,7 @@ def defineBuildTargets(env, artifacts): artifacts['corelib'] = core artifacts['support'] = lLib - artifacts['lumiera'] = env.LumieraExe('$TARDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) + artifacts['lumiera'] = env.LumieraExe('$TARGDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) # building Lumiera Plugins envPlu = env.Clone() @@ -360,7 +370,7 @@ def defineBuildTargets(env, artifacts): objgui = srcSubtree(envGtk,'$SRCDIR/gui') guimodule = envGtk.LoadableModule('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') artifacts['gui'] = ( guimodule - + env.Install('$TARDIR', env.Glob('$SRCDIR/gui/*.rc')) + + env.Install('$TARGDIR', env.Glob('$SRCDIR/gui/*.rc')) + artifacts['icons'] ) artifacts['guimodule'] = guimodule ###TODO better organisation of GUI components @@ -405,7 +415,6 @@ def defineInstallTargets(env, artifacts): env.Install(dir = modDir, source=artifacts['guimodule']) lumi = env.Install(dir = lumDir, source=artifacts['lumiera']) tool = env.Install(dir = lumDir, source=artifacts['tools']) - print "Aufruf LINK DESTDIR=" + env.get('DESTDIR') env.SymLink(binDir+"lumiera",lumi,"../lib/lumiera/lumiera") env.Install(dir = shaDir, source="data/config/dummy_lumiera.ini") ### TODO should become a resource builder @@ -419,8 +428,7 @@ def defineInstallTargets(env, artifacts): ### === MAIN === #################################################### - -env = setupBasicEnvironment() +env = setupBasicEnvironment(localDefinitions) if not (isCleanupOperation(env) or isHelpRequest()): env = configurePlatform(env) diff --git a/admin/scons/BuilderDoxygen.py b/admin/scons/BuilderDoxygen.py index a397ef32e..7c9514f2c 100644 --- a/admin/scons/BuilderDoxygen.py +++ b/admin/scons/BuilderDoxygen.py @@ -217,8 +217,8 @@ def generate(env): 'Doxygen': doxyfile_builder, }) - env.AppendUnique( - DOXYGEN = 'doxygen', + env.Replace( + DOXYGEN = 'doxygen' ) diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index 8e7356271..387e0fccb 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -28,6 +28,7 @@ import fnmatch import re import tarfile +from SCons import Util from SCons.Action import Action @@ -151,7 +152,7 @@ def createPlugins(env, dir): """ investigate the given source directory to identify all contained source trees. @return: a list of build nodes defining a plugin for each of these source trees. """ - return [env.LumieraPlugin( '#$TARDIR/$MODULES/%s' % getDirname(tree) + return [env.LumieraPlugin( '#$TARGDIR/$MODULES/%s' % getDirname(tree) , srcSubtree(env, tree) , SHLIBPREFIX='', SHLIBSUFFIX='.lum' ) @@ -196,38 +197,39 @@ def checkCommandOption(env, optID, val=None, cmdName=None): -def RegisterIcon_Builder(env): - """ Registers Custom Builders for generating and installing Icons. - Additionally you need to build the tool (rsvg-convert.c) - used to generate png from the svg source using librsvg. - """ - - import render_icon as renderer # load Joel's python script for invoking the rsvg-convert (SVG render) - renderer.rsvgPath = env.subst("$TARDIR/rsvg-convert") - - def invokeRenderer(target, source, env): - source = str(source[0]) - targetdir = env.subst("$TARDIR") - renderer.main([source,targetdir]) - return 0 - - def createIconTargets(target,source,env): - """ parse the SVG to get the target file names """ - source = str(source[0]) - targetdir = os.path.basename(str(target[0])) - targetfiles = renderer.getTargetNames(source) # parse SVG - return (["$TARDIR/%s" % name for name in targetfiles], source) - - def IconCopy(env, source): - """Copy icon to corresponding icon dir. """ - subdir = getDirname(source) - return env.Install("$TARDIR/%s" % subdir, source) - - - buildIcon = env.Builder( action = Action(invokeRenderer, "rendering Icon: $SOURCE --> $TARGETS") - , single_source = True - , emitter = createIconTargets - ) - env.Append(BUILDERS = {'IconRender' : buildIcon}) - env.AddMethod(IconCopy) +class Record(dict): + """ a set of properties with map style access. + Record is a dictionary, but the elements can be accessed + conveniently as if they where object fields + """ + def __init__(self, defaults=None, **props): + if defaults: + defaults.update(props) + props = defaults + dict.__init__(self,props) + + def __getattr__(self,key): + if key=='__get__' or key=='__set__': + raise AttributeError + return self.setdefault(key) + + def __setattr__(self,key,val): + self[key] = val + + +def extract_localPathDefs (localDefs): + """ extracts the directory configuration values. + For sake of simplicity, paths and directories are defined + immediately as global variables in the SConstruct. This helper + extracts from the given dict the variables matching some magical + pattern and returns them wrapped into a Record for convenient access + """ + def relevantPathDefs (mapping): + for (k,v) in mapping.items(): + if k.startswith('build') or k.startswith('install') and Util.is_String(v): + v = v.strip() + if not v.endswith('/'): v += '/' + yield (k,v) + + return dict(relevantPathDefs(localDefs)) diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index a1e050156..fa1320451 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -38,9 +38,14 @@ class LumieraEnvironment(Environment): This allows us to carry structured config data without using global vars. Idea inspired by Ardour. """ - def __init__(self,*args,**kw): - Environment.__init__ (self,*args,**kw) + def __init__(self, pathConfig, **kw): + Environment.__init__ (self,**kw) + self.path = Record (pathConfig) self.libInfo = {} + self.Tool("BuilderGCH") + self.Tool("BuilderDoxygen") + self.Tool("ToolDistCC") + self.Tool("ToolCCache") RegisterIcon_Builder(self) def Configure (self, *args, **kw): @@ -77,7 +82,7 @@ class LumieraEnvironment(Environment): print "Problems configuring the Library %s (>= %s)" % (libID,minVersion) return False - self.libInfo[libID] = libInfo = LumieraEnvironment() + self.libInfo[libID] = libInfo = Environment() libInfo["ENV"]["PKG_CONFIG_PATH"] = os.environ.get("PKG_CONFIG_PATH") libInfo.ParseConfig ('pkg-config --cflags --libs '+ libID ) if alias: @@ -196,11 +201,11 @@ def RegisterIcon_Builder(env): """ import render_icon as renderer # load Joel's python script for invoking the rsvg-convert (SVG render) - renderer.rsvgPath = env.subst("$TARDIR/rsvg-convert") + renderer.rsvgPath = env.subst("$TARGDIR/rsvg-convert") def invokeRenderer(target, source, env): source = str(source[0]) - targetdir = env.subst("$TARDIR") + targetdir = env.subst("$TARGDIR") renderer.main([source,targetdir]) return 0 @@ -209,12 +214,12 @@ def RegisterIcon_Builder(env): source = str(source[0]) targetdir = os.path.basename(str(target[0])) targetfiles = renderer.getTargetNames(source) # parse SVG - return (["$TARDIR/%s" % name for name in targetfiles], source) + return (["$TARGDIR/%s" % name for name in targetfiles], source) def IconCopy(env, source): """Copy icon to corresponding icon dir. """ subdir = getDirname(source) - return env.Install("$TARDIR/%s" % subdir, source) + return env.Install("$TARGDIR/%s" % subdir, source) buildIcon = env.Builder( action = Action(invokeRenderer, "rendering Icon: $SOURCE --> $TARGETS") diff --git a/src/tool/SConscript b/src/tool/SConscript index 725248ca8..bab7e6497 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -12,12 +12,12 @@ envSvg.mergeConf(['librsvg-2.0']) envSvg.Append(LIBS=support_lib) -luidgen = env.LumieraExe('#$TARDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs -rsvg = envSvg.LumieraExe('#$TARDIR/rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) +luidgen = env.LumieraExe('#$TARGDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs +rsvg = envSvg.LumieraExe('#$TARGDIR/rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) # build additional test and administrative tools.... -artifacts['tools'] = [ env.LumieraExe('#$TARDIR/hello-world','hello.c') #### hello world (checks C build) - + env.LumieraExe('#$TARDIR/try', 'try.cpp') #### to try out some feature... +artifacts['tools'] = [ env.LumieraExe('#$TARGDIR/hello-world','hello.c') #### hello world (checks C build) + + env.LumieraExe('#$TARGDIR/try', 'try.cpp') #### to try out some feature... # + luidgen + rsvg ] diff --git a/tests/SConscript b/tests/SConscript index b9e204676..a3c4d8a82 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -35,7 +35,7 @@ def testExecutable(env,tree, exeName=None, obj=None): obj = srcSubtree(env,tree, isShared=False) # use all sourcefiles found in subtree if not exeName: exeName = 'test-%s' % tree - return env.LumieraExe('#$TARDIR/'+exeName, obj + core) + return env.LumieraExe('#$TARGDIR/'+exeName, obj + core) def testCollection(env,dir): @@ -44,7 +44,7 @@ def testCollection(env,dir): """ srcpatt = ['test-*.c'] exeName = lambda p: path.basename(path.splitext(p)[0]) - buildIt = lambda p: env.LumieraExe("#$TARDIR/"+exeName(p), [p] + core) + buildIt = lambda p: env.LumieraExe("#$TARGDIR/"+exeName(p), [p] + core) return [buildIt(f) for f in scanSubtree(dir,srcpatt)] @@ -67,7 +67,7 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] # for creating a Valgrind-Suppression file -vgsuppr = env.LumieraExe('#$TARDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms +vgsuppr = env.LumieraExe('#$TARGDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms artifacts['tools'] += [vgsuppr] Depends(ts,vgsuppr) @@ -103,10 +103,10 @@ if testsuites: testEnv['ENV']['TEST_CONF'] = env.File("test.conf").abspath -testDir = env.Dir('#$TARDIR') +testDir = env.Dir('#$TARGDIR') runTest = env.File("test.sh").abspath -runTs = testEnv.Command('#$TARDIR/,testlog', ts, runTest, chdir=testDir) +runTs = testEnv.Command('#$TARGDIR/,testlog', ts, runTest, chdir=testDir)