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:
parent
9cb03c7015
commit
d9f90c2c04
4 changed files with 108 additions and 70 deletions
67
SConstruct
67
SConstruct
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue