SCons: finish reworking buildsystem to rely on custom builders.

All target paths and install targets now defined automatically,
most of the buildscript just using plain sourcefile names
This commit is contained in:
Fischlurch 2011-01-30 22:12:55 +01:00
parent 9cb03c7015
commit d9f90c2c04
4 changed files with 108 additions and 70 deletions

View file

@ -22,35 +22,39 @@
#####################################################################
# NOTE: scons -h for help.
# Read more about the SCons build system at: http://www.scons.org
# Basically, this script just /defines/ the components and how they
# fit together. SCons will derive the necessary build steps.
#-----------------------------------Configuration
TARGDIR = 'target'
VERSION = '0.1+pre.01'
TOOLDIR = './admin/scons'
TOOLDIR = './admin/scons' # SCons plugins
SCRIPTDIR = './admin'
OPTCACHE = 'optcache'
CUSTOPTFILE = 'custom-options'
# these are accessible via env.path.xxxx
srcIcon = 'icons'
srcConf = 'data/config'
buildExe = '#$TARGDIR'
buildLib = '#$TARGDIR/modules'
buildPlug = '#$TARGDIR/modules'
buildIcon = '#$TARGDIR/icons'
buildUIRes = '#$TARGDIR/'
buildConf = '#$TARGDIR/config'
installExe = '#$DESTDIR/lib/lumiera'
installLib = '#$DESTDIR/lib/lumiera/modules'
installPlug = '#$DESTDIR/lib/lumiera/modules'
installIcon = '#$DESTDIR/share/lumiera/icons'
installConf = '#$DESTDIR/share/lumiera/config'
installUIRes = '#$DESTDIR/share/lumiera/'
installConf = '#$DESTDIR/lib/lumiera/config'
localDefinitions = locals()
#-----------------------------------Configuration
# NOTE: scons -h for help.
# Read more about the SCons build system at: http://www.scons.org
# Basically, this script just /defines/ the components and how they
# fit together. SCons will derive the necessary build steps.
import os
@ -76,7 +80,7 @@ def setupBasicEnvironment(localDefinitions):
vars = defineCmdlineVariables()
env = LumieraEnvironment(variables=vars
,toolpath = [TOOLDIR]
,pathConfig = extract_localPathDefs(localDefinitions)
,pathConfig = extract_localPathDefs(localDefinitions) # e.g. buildExe -> env.path.buildExe
,TARGDIR = TARGDIR
,DESTDIR = '$INSTALLDIR/$PREFIX'
,VERSION = VERSION
@ -239,10 +243,10 @@ def configurePlatform(env):
conf.env.mergeConf('nobugmt')
if not conf.CheckCXXHeader('tr1/memory'):
problems.append('We rely on the std::tr1 proposed standard extension for shared_ptr.')
problems.append('We rely on the std::tr1 standard C++ extension for shared_ptr.')
if not conf.CheckCXXHeader('boost/config.hpp'):
problems.append('We need the C++ boost-lib.')
problems.append('We need the C++ boost-libraries.')
else:
if not conf.CheckCXXHeader('boost/shared_ptr.hpp'):
problems.append('We need boost::shared_ptr (shared_ptr.hpp).')
@ -264,16 +268,16 @@ def configurePlatform(env):
conf.env.mergeConf('gavl')
if not conf.CheckPkgConfig('gtkmm-2.4', 2.8):
problems.append('Unable to configure GTK--, exiting.')
problems.append('Unable to configure GTK--')
if not conf.CheckPkgConfig('glibmm-2.4', '2.16'):
problems.append('Unable to configure Lib glib--, exiting.')
problems.append('Unable to configure Lib glib--')
if not conf.CheckPkgConfig('gthread-2.0', '2.12.4'):
problems.append('Need gthread support lib for glib-- based thread handling.')
if not conf.CheckPkgConfig('cairomm-1.0', 0.6):
problems.append('Unable to configure Cairo--, exiting.')
problems.append('Unable to configure Cairo--')
verGDL = '2.27.1'
if not conf.CheckPkgConfig('gdl-lum', verGDL, alias='gdl'):
@ -309,7 +313,7 @@ def configurePlatform(env):
def definePackagingTargets(env, artifacts):
def defineSetupTargets(env, artifacts):
""" build operations and targets to be done /before/ compiling.
things like creating a source tarball or preparing a version header.
"""
@ -339,20 +343,19 @@ def defineBuildTargets(env, artifacts):
artifacts['corelib'] = core
artifacts['support'] = lLib
artifacts['lumiera'] = env.Program('lumiera', ['src/lumiera/main.cpp'], LIBS=core, install=True)
artifacts['lumiera'] = ( env.Program('lumiera', ['src/lumiera/main.cpp'], LIBS=core, install=True)
+ env.ConfigData(env.path.srcConf+'dummy_lumiera.ini')
)
# building Lumiera Plugins
envPlu = env.Clone()
envPlu.Append(CPPDEFINES='LUMIERA_PLUGIN')
artifacts['plugins'] = [] # currently none
# render and install Icons
vector_icon_dir = env.path.srcIcon+'svg'
prerendered_icon_dir = env.path.srcIcon+'prerendered'
artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])]
+ [env.IconCopy(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])]
artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])]
+ [env.IconResource(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])]
)
##TODO make that into a resource builder
# the Lumiera GTK GUI
envGtk = env.Clone()
@ -362,14 +365,13 @@ def defineBuildTargets(env, artifacts):
objgui = srcSubtree(envGtk,'src/gui')
guimodule = envGtk.LumieraPlugin('gtk_gui', objgui, install=True)
artifacts['gui'] = ( guimodule
+ env.Install('$TARGDIR', env.Glob('src/gui/*.rc'))
+ [env.GuiResource(f) for f in env.Glob('src/gui/*.rc')]
+ artifacts['icons']
)
artifacts['guimodule'] = guimodule ###TODO better organisation of GUI components
# call subdir SConscript(s) for independent components
SConscript(dirs=['src/tool'], exports='env artifacts core')
SConscript(dirs=['tests'], exports='env envPlu artifacts core')
SConscript(dirs=['src/tool'], exports='env artifacts core')
SConscript(dirs=['tests'], exports='env artifacts core')
@ -377,8 +379,11 @@ def definePostBuildTargets(env, artifacts):
""" define further actions after the core build (e.g. Documentaion).
define alias targets to trigger the installing.
"""
build = env.Alias('build', artifacts['lumiera']+artifacts['gui']+artifacts['plugins']+artifacts['tools'])
env.Default('build')
build = env.Alias('build', ( artifacts['lumiera']
+ artifacts['plugins']
+ artifacts['tools']
+ artifacts['gui']
))
# additional files to be cleaned when cleaning 'build'
env.Clean ('build', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log' ])
env.Clean ('build', [ 'src/pre.gch' ])
@ -387,7 +392,9 @@ def definePostBuildTargets(env, artifacts):
env.Alias ('doc', doxydoc)
env.Clean ('doc', doxydoc + ['doc/devel/,doxylog','doc/devel/warnings.txt'])
allbu = env.Alias('all', build+artifacts['testsuite']+doxydoc)
env.Alias ('all', build+artifacts['testsuite']+doxydoc)
env.Default('build')
# SCons default target
def defineInstallTargets(env, artifacts):
@ -396,8 +403,6 @@ def defineInstallTargets(env, artifacts):
for all executables automatically. see LumieraEnvironment.py
"""
env.SymLink('$DESTDIR/bin/lumiera',env.path.installExe+'lumiera','../lib/lumiera/lumiera')
env.Install(dir = env.path.installConf, source=env.path.srcConf+'dummy_lumiera.ini') ### TODO should become a resource builder
# env.Install(dir = '$DESTDIR/share/doc/lumiera$VERSION/devel', source=artifacts['doxydoc'])
env.Alias('install', '$DESTDIR')
@ -424,7 +429,7 @@ artifacts = {}
# 'plugins' : plugin shared lib
# 'tools' : small tool applications (e.g mpegtoc)
definePackagingTargets(env, artifacts)
defineSetupTargets(env, artifacts)
defineBuildTargets(env, artifacts)
definePostBuildTargets(env, artifacts)
defineInstallTargets(env, artifacts)

View file

@ -99,7 +99,7 @@ def findSrcTrees(location, patterns=SRCPATTERNS):
After having initially expanded the given location with #globRootdirs, each
directory is examined depth first, until encountering a directory containing
source files, which then yields a result. Especially, this can be used to traverse
an organisational directory structure and find out all possible source trees of
an organisational directory structure and find out all possible source trees
to be built into packages, plugins, individual tool executables etc.
@return: the relative path names of all source root dirs found (generator function).
"""
@ -138,12 +138,19 @@ def filterNodes(nlist, removeName=None):
def getDirname(dir):
""" extract directory name without leading path """
def getDirname(dir, basePrefix=None):
""" extract directory name without leading path,
or without the explicitly given basePrefix
"""
dir = os.path.realpath(dir)
if not os.path.isdir(dir):
dir,_ = os.path.split(dir)
_, name = os.path.split(dir)
if basePrefix:
basePrefix = os.path.realpath(basePrefix)
if str(dir).startswith(basePrefix):
name = str(dir)[len(basePrefix):]
else:
_, name = os.path.split(dir)
return name

View file

@ -46,7 +46,7 @@ class LumieraEnvironment(Environment):
self.Tool("BuilderDoxygen")
self.Tool("ToolDistCC")
self.Tool("ToolCCache")
RegisterIcon_Builder(self)
register_LumieraResourceBuilder(self)
register_LumieraCustomBuilders(self)
def Configure (self, *args, **kw):
@ -89,25 +89,6 @@ class LumieraEnvironment(Environment):
if alias:
self.libInfo[alias] = libInfo
return libInfo
def SymLink(self, target, source, linktext=None):
""" use python to create a symlink
"""
def makeLink(target,source,env):
if linktext:
dest = linktext
else:
dest = str(source[0])
link = str(target[0])
os.symlink(dest, link)
def reportLink(target,source,env):
dest = str(source[0])
link = str(target[0])
return "Install link %s -> %s" % (link,dest)
action = Action(makeLink,reportLink)
self.Command (target,source, action)
@ -136,7 +117,7 @@ class LumieraConfigContext(ConfigBase):
####### Lumiera custom tools and builders #####################################
def RegisterIcon_Builder(env):
def register_LumieraResourceBuilder(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.
@ -147,21 +128,39 @@ def RegisterIcon_Builder(env):
def invokeRenderer(target, source, env):
source = str(source[0])
targetdir = env.subst("$TARGDIR")
targetdir = env.subst(env.path.buildIcon)
if targetdir.startswith('#'): targetdir = targetdir[1:]
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]))
targetdir = env.path.buildIcon
targetfiles = renderer.getTargetNames(source) # parse SVG
return (["$TARGDIR/%s" % name for name in targetfiles], source)
return ([targetdir+name for name in targetfiles], source)
def IconCopy(env, source):
"""Copy icon to corresponding icon dir. """
subdir = getDirname(source)
return env.Install("$TARGDIR/%s" % subdir, source)
def IconResource(env, source):
"""Copy icon pixmap to corresponding icon dir. """
subdir = getDirname(str(source))
toBuild = env.path.buildIcon+subdir
toInstall = env.path.installIcon+subdir
env.Install (toInstall, source)
return env.Install(toBuild, source)
def GuiResource(env, source):
subdir = getDirname(str(source))
toBuild = env.path.buildUIRes+subdir
toInstall = env.path.installUIRes+subdir
env.Install (toInstall, source)
return env.Install(toBuild, source)
def ConfigData(env, source):
subdir = getDirname(str(source), env.path.srcConf) # removes source location path prefix
toBuild = env.path.buildConf+subdir
toInstall = env.path.installConf+subdir
env.Install (toInstall, source)
return env.Install(toBuild, source)
buildIcon = env.Builder( action = Action(invokeRenderer, "rendering Icon: $SOURCE --> $TARGETS")
@ -169,7 +168,9 @@ def RegisterIcon_Builder(env):
, emitter = createIconTargets
)
env.Append(BUILDERS = {'IconRender' : buildIcon})
env.AddMethod(IconCopy)
env.AddMethod(IconResource)
env.AddMethod(GuiResource)
env.AddMethod(ConfigData)
@ -191,9 +192,9 @@ class WrappedStandardExeBuilder(SCons.Util.Proxy):
Automatically define installation targets for build results.
@note only returning the build targets, not the install targets
"""
customisedEnv = self.getCustomEnvironment(env, target=target, **kw) # defined in subclasses
customisedEnv = self.getCustomEnvironment(env, target=target, **kw) # defined in subclasses
buildTarget = self.buildLocation(customisedEnv, target)
buildTarget = self.invokeOriginalBuilder (customisedEnv, buildTarget, source, **kw)
buildTarget = self.invokeOriginalBuilder(customisedEnv, buildTarget, source, **kw)
self.installTarget(customisedEnv, buildTarget, **kw)
return buildTarget
@ -297,6 +298,9 @@ class LumieraPluginBuilder(LumieraModuleBuilder):
def register_LumieraCustomBuilders (lumiEnv):
""" install the customised builder versions tightly integrated with our buildsystem.
Especially, these builders automatically add the build and installation locations
@ -311,3 +315,27 @@ def register_LumieraCustomBuilders (lumiEnv):
lumiEnv['BUILDERS']['SharedLibrary'] = libraryBuilder
lumiEnv['BUILDERS']['LoadableModule'] = smoduleBuilder
lumiEnv['BUILDERS']['LumieraPlugin'] = lpluginBuilder
def SymLink(env, target, source, linktext=None):
""" use python to create a symlink
"""
def makeLink(target,source,env):
if linktext:
dest = linktext
else:
dest = str(source[0])
link = str(target[0])
os.symlink(dest, link)
if linktext: srcSpec=linktext
else: srcSpec='$SOURCE'
action = Action(makeLink, "Install link: $TARGET -> "+srcSpec)
env.Command (target,source, action)
# adding SymLink direclty as method on the environment object
# Probably that should better be a real builder, but I couldn't figure out
# how to get the linktext through literally, which is necessary for relative links.
# Judging from the sourcecode of SCons.Builder.BuilderBase, there seems to be no way
# to set the executor_kw, which are passed through to the action object.
lumiEnv.AddMethod(SymLink)

View file

@ -12,13 +12,11 @@ from Buildhelper import scanSubtree
from Buildhelper import globRootdirs
from Buildhelper import createPlugins
Import('env','envPlu','artifacts','core')
Import('env','artifacts','core')
# temp fix to add test.h -- wouldn't it be better to put this header be into src/lib ?
env = env.Clone()
env.Append(CPPPATH='#/.') # add Rootdir to Includepath, so test/test.h is found
envPlu = envPlu.Clone()
envPlu.Append(CPPPATH='#/.')
# temp fix-------------
def testExecutable(env,tree, exeName=None, obj=None):
@ -59,7 +57,7 @@ moduledirs = globRootdirs('*')
artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] # was: ['lib','components']
+ [ testCollection(env, dir) for dir in moduledirs if not dir in specials]
+ createPlugins(envPlu, 'plugin')
+ createPlugins(env, 'plugin')
+ env.File(glob('*.tests')) # depending on the test definition files for test.sh
)