2008-07-11 05:35:48 +02:00
|
|
|
# -*- python -*-
|
|
|
|
|
##
|
|
|
|
|
## LumieraEnvironment.py - custom SCons Environment
|
|
|
|
|
##
|
|
|
|
|
|
|
|
|
|
# Copyright (C) Lumiera.org
|
|
|
|
|
# 2008, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
|
#
|
|
|
|
|
# This program is free software; you can redistribute it and/or
|
|
|
|
|
# modify it under the terms of the GNU General Public License as
|
|
|
|
|
# published by the Free Software Foundation; either version 2 of
|
|
|
|
|
# the License, or (at your option) any later version.
|
|
|
|
|
#
|
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
|
#
|
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
#####################################################################
|
|
|
|
|
|
|
|
|
|
|
2011-01-29 16:45:22 +01:00
|
|
|
from os import path
|
|
|
|
|
|
2008-08-21 01:24:46 +02:00
|
|
|
import SCons.SConf
|
2012-01-10 05:52:00 +01:00
|
|
|
from SCons.Action import Action
|
2008-07-11 05:35:48 +02:00
|
|
|
from SCons.Environment import Environment
|
|
|
|
|
|
|
|
|
|
from Buildhelper import *
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LumieraEnvironment(Environment):
|
|
|
|
|
""" Custom SCons build environment for Lumiera
|
|
|
|
|
This allows us to carry structured config data without
|
|
|
|
|
using global vars. Idea inspired by Ardour.
|
|
|
|
|
"""
|
2012-01-10 05:09:32 +01:00
|
|
|
def __init__(self, buildSetup, buildVars, **kw):
|
|
|
|
|
kw.update(VERSION = buildSetup.VERSION
|
|
|
|
|
,TARGDIR = buildSetup.TARGDIR
|
|
|
|
|
,DESTDIR = '$INSTALLDIR/$PREFIX'
|
|
|
|
|
,toolpath = [buildSetup.TOOLDIR ]
|
|
|
|
|
,variables = buildVars
|
|
|
|
|
)
|
|
|
|
|
Environment.__init__ (self, **kw)
|
|
|
|
|
self.path = Record (extract_localPathDefs(buildSetup)) # e.g. buildExe -> env.path.buildExe
|
2008-07-11 05:35:48 +02:00
|
|
|
self.libInfo = {}
|
2011-01-30 15:27:21 +01:00
|
|
|
self.Tool("BuilderGCH")
|
2011-01-30 18:56:51 +01:00
|
|
|
self.Tool("BuilderDoxygen")
|
2011-01-30 15:27:21 +01:00
|
|
|
self.Tool("ToolDistCC")
|
|
|
|
|
self.Tool("ToolCCache")
|
2011-01-30 22:12:55 +01:00
|
|
|
register_LumieraResourceBuilder(self)
|
2011-01-30 16:47:03 +01:00
|
|
|
register_LumieraCustomBuilders(self)
|
2008-07-11 05:35:48 +02:00
|
|
|
|
2012-01-10 05:09:32 +01:00
|
|
|
|
2008-07-11 05:35:48 +02:00
|
|
|
def Configure (self, *args, **kw):
|
|
|
|
|
kw['env'] = self
|
|
|
|
|
return apply(LumieraConfigContext, args, kw)
|
|
|
|
|
|
|
|
|
|
def mergeConf (self,other):
|
|
|
|
|
""" extract the library/compiler flags from other Environment.
|
|
|
|
|
Optionally accepts a list or just sting(s) representing keys
|
|
|
|
|
in our own libInfo Dictionary
|
|
|
|
|
"""
|
|
|
|
|
if isinstance(other, list):
|
|
|
|
|
for elm in other:
|
|
|
|
|
self.mergeConf(elm)
|
|
|
|
|
elif isinstance(other, str):
|
|
|
|
|
if other in self.libInfo:
|
|
|
|
|
self.mergeConf(self.libInfo[other])
|
|
|
|
|
else:
|
|
|
|
|
self.Append (LIBS = other.get ('LIBS',[]))
|
|
|
|
|
self.Append (LIBPATH = other.get ('LIBPATH', []))
|
|
|
|
|
self.Append (CPPPATH = other.get('CPPPATH', []))
|
|
|
|
|
self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
|
|
|
|
|
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
|
|
|
2009-04-20 01:58:34 +02:00
|
|
|
def addLibInfo (self, libID, minVersion=0, alias=None):
|
2008-07-11 05:35:48 +02:00
|
|
|
""" use pkg-config to create an Environment describing the lib.
|
|
|
|
|
Don't add this defs to the current Environment, rather store
|
|
|
|
|
them in the libInfo Dictionary.
|
|
|
|
|
"""
|
|
|
|
|
minVersion = str(minVersion)
|
|
|
|
|
if 0 != os.system('pkg-config --print-errors --exists "%s >= %s"' % (libID,minVersion)):
|
|
|
|
|
print "Problems configuring the Library %s (>= %s)" % (libID,minVersion)
|
|
|
|
|
return False
|
|
|
|
|
|
2011-01-30 15:27:21 +01:00
|
|
|
self.libInfo[libID] = libInfo = Environment()
|
2010-01-17 00:42:07 +01:00
|
|
|
libInfo["ENV"]["PKG_CONFIG_PATH"] = os.environ.get("PKG_CONFIG_PATH")
|
2008-07-11 05:35:48 +02:00
|
|
|
libInfo.ParseConfig ('pkg-config --cflags --libs '+ libID )
|
2009-04-20 01:58:34 +02:00
|
|
|
if alias:
|
|
|
|
|
self.libInfo[alias] = libInfo
|
2008-07-11 05:35:48 +02:00
|
|
|
return libInfo
|
2010-05-21 01:59:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# extending the 'Configure' functionality of SCons,
|
|
|
|
|
# especially for library dependency checking
|
|
|
|
|
ConfigBase = SCons.SConf.SConfBase
|
2008-08-21 01:24:46 +02:00
|
|
|
|
2008-07-11 05:35:48 +02:00
|
|
|
|
|
|
|
|
|
2008-08-21 01:24:46 +02:00
|
|
|
class LumieraConfigContext(ConfigBase):
|
2008-07-11 05:35:48 +02:00
|
|
|
""" Extends the SCons Configure context with some convenience methods
|
|
|
|
|
"""
|
|
|
|
|
def __init__(self, *args,**kw):
|
2008-08-21 01:24:46 +02:00
|
|
|
ConfigBase.__init__(self,*args,**kw)
|
2008-07-11 05:35:48 +02:00
|
|
|
|
2009-04-20 01:58:34 +02:00
|
|
|
def CheckPkgConfig (self, libID, minVersion=0, alias=None):
|
2008-07-11 05:35:48 +02:00
|
|
|
print "Checking for library configuration: %s " % libID
|
|
|
|
|
# self.Message(self,"Checking for library configuration: %s " % libID)
|
2009-04-20 01:58:34 +02:00
|
|
|
return self.env.addLibInfo (libID, minVersion, alias)
|
2008-07-11 05:35:48 +02:00
|
|
|
|
|
|
|
|
|
2011-01-29 23:09:02 +01:00
|
|
|
|
2011-01-30 18:56:51 +01:00
|
|
|
###############################################################################
|
|
|
|
|
####### Lumiera custom tools and builders #####################################
|
2011-01-29 23:09:02 +01:00
|
|
|
|
|
|
|
|
|
2011-01-30 22:12:55 +01:00
|
|
|
def register_LumieraResourceBuilder(env):
|
2011-01-29 23:09:02 +01:00
|
|
|
""" 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.
|
|
|
|
|
"""
|
|
|
|
|
|
2012-01-10 04:02:29 +01:00
|
|
|
import IconSvgRenderer as renderer # load Joel's python script for invoking the rsvg-convert (SVG render)
|
2011-01-30 15:27:21 +01:00
|
|
|
renderer.rsvgPath = env.subst("$TARGDIR/rsvg-convert")
|
2011-01-29 23:09:02 +01:00
|
|
|
|
|
|
|
|
def invokeRenderer(target, source, env):
|
|
|
|
|
source = str(source[0])
|
2011-01-30 22:12:55 +01:00
|
|
|
targetdir = env.subst(env.path.buildIcon)
|
|
|
|
|
if targetdir.startswith('#'): targetdir = targetdir[1:]
|
2011-01-29 23:09:02 +01:00
|
|
|
renderer.main([source,targetdir])
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
def createIconTargets(target,source,env):
|
|
|
|
|
""" parse the SVG to get the target file names """
|
|
|
|
|
source = str(source[0])
|
2011-01-30 22:12:55 +01:00
|
|
|
targetdir = env.path.buildIcon
|
2011-01-29 23:09:02 +01:00
|
|
|
targetfiles = renderer.getTargetNames(source) # parse SVG
|
2011-02-07 11:35:44 +01:00
|
|
|
|
|
|
|
|
# additionally create an installation task for each Icon to be generated
|
|
|
|
|
installLocation = env.path.installIcon
|
|
|
|
|
generateTargets = []
|
|
|
|
|
for icon in targetfiles:
|
|
|
|
|
icon = targetdir+icon
|
|
|
|
|
subdir = getDirname(str(icon))
|
|
|
|
|
env.Install (installLocation+subdir, icon)
|
|
|
|
|
generateTargets.append(icon)
|
|
|
|
|
|
|
|
|
|
return (generateTargets, source)
|
2011-01-30 22:12:55 +01:00
|
|
|
|
|
|
|
|
def IconResource(env, source):
|
2012-01-10 05:52:00 +01:00
|
|
|
"""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)
|
2011-01-29 23:09:02 +01:00
|
|
|
|
2011-01-30 22:12:55 +01:00
|
|
|
def GuiResource(env, source):
|
2012-01-10 05:52:00 +01:00
|
|
|
subdir = getDirname(str(source))
|
|
|
|
|
toBuild = env.path.buildUIRes+subdir
|
|
|
|
|
toInstall = env.path.installUIRes+subdir
|
|
|
|
|
env.Install (toInstall, source)
|
|
|
|
|
return env.Install(toBuild, source)
|
2011-01-30 22:12:55 +01:00
|
|
|
|
2012-01-10 08:06:09 +01:00
|
|
|
def ConfigData(env, prefix, source, targetDir=None):
|
2012-01-10 05:52:00 +01:00
|
|
|
""" install (copy) configuration- and metadata.
|
|
|
|
|
target dir is either the install location configured (in SConstruct),
|
|
|
|
|
or an explicitly given absolute or relative path segment, which might refer
|
|
|
|
|
to the location of the executable through the $ORIGIN token
|
|
|
|
|
"""
|
2012-01-10 08:06:09 +01:00
|
|
|
source = path.join(prefix,str(source))
|
|
|
|
|
subdir = getDirname(source, prefix) # removes source location path prefix
|
2012-01-10 05:52:00 +01:00
|
|
|
if targetDir:
|
|
|
|
|
if path.isabs(targetDir):
|
|
|
|
|
toBuild = toInstall = path.join(targetDir,subdir)
|
|
|
|
|
else:
|
|
|
|
|
if targetDir.startswith('$ORIGIN'):
|
|
|
|
|
targetDir = targetDir[len('$ORIGIN'):]
|
|
|
|
|
toBuild = path.join(env.path.buildExe, targetDir, subdir)
|
|
|
|
|
toInstall = path.join(env.path.installExe, targetDir, subdir)
|
|
|
|
|
else:
|
|
|
|
|
toBuild = path.join(env.path.buildConf, targetDir, subdir)
|
|
|
|
|
toInstall = path.join(env.path.installConf, targetDir, subdir)
|
|
|
|
|
else:
|
|
|
|
|
toBuild = path.join(env.path.buildConf,subdir)
|
|
|
|
|
toInstall = path.join(env.path.installConf,subdir)
|
|
|
|
|
env.Install (toInstall, source)
|
|
|
|
|
return env.Install(toBuild, source)
|
2011-01-29 23:09:02 +01:00
|
|
|
|
2011-01-30 18:56:51 +01:00
|
|
|
|
2011-01-29 23:09:02 +01:00
|
|
|
buildIcon = env.Builder( action = Action(invokeRenderer, "rendering Icon: $SOURCE --> $TARGETS")
|
|
|
|
|
, single_source = True
|
2011-01-30 18:56:51 +01:00
|
|
|
, emitter = createIconTargets
|
2011-01-29 23:09:02 +01:00
|
|
|
)
|
2011-01-30 18:56:51 +01:00
|
|
|
env.Append(BUILDERS = {'IconRender' : buildIcon})
|
2011-01-30 22:12:55 +01:00
|
|
|
env.AddMethod(IconResource)
|
|
|
|
|
env.AddMethod(GuiResource)
|
|
|
|
|
env.AddMethod(ConfigData)
|
2011-01-29 23:09:02 +01:00
|
|
|
|
2011-01-30 16:47:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WrappedStandardExeBuilder(SCons.Util.Proxy):
|
|
|
|
|
""" Helper to add customisations and default configurations to SCons standard builders.
|
|
|
|
|
The original builder object is wrapped and most calls are simply forwarded to this
|
2011-12-03 05:46:36 +01:00
|
|
|
wrapped object by Python magic. But some calls are intercepted in order to inject
|
|
|
|
|
suitable default configuration based on the project setup.
|
2011-01-30 16:47:03 +01:00
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def __init__(self, originalBuilder):
|
|
|
|
|
SCons.Util.Proxy.__init__ (self, originalBuilder)
|
|
|
|
|
|
2011-02-06 15:12:13 +01:00
|
|
|
def __nonzero__(self): return True
|
|
|
|
|
|
2011-01-30 16:47:03 +01:00
|
|
|
def __call__(self, env, target=None, source=None, **kw):
|
|
|
|
|
""" when the builder gets invoked from the SConscript...
|
|
|
|
|
create a clone environment for specific configuration
|
2011-01-30 19:43:51 +01:00
|
|
|
and then pass on the call to the wrapped original builder.
|
|
|
|
|
Automatically define installation targets for build results.
|
|
|
|
|
@note only returning the build targets, not the install targets
|
2011-01-30 16:47:03 +01:00
|
|
|
"""
|
2011-01-30 22:12:55 +01:00
|
|
|
customisedEnv = self.getCustomEnvironment(env, target=target, **kw) # defined in subclasses
|
2011-01-30 18:56:51 +01:00
|
|
|
buildTarget = self.buildLocation(customisedEnv, target)
|
2011-01-30 22:12:55 +01:00
|
|
|
buildTarget = self.invokeOriginalBuilder(customisedEnv, buildTarget, source, **kw)
|
2011-01-30 19:43:51 +01:00
|
|
|
self.installTarget(customisedEnv, buildTarget, **kw)
|
|
|
|
|
return buildTarget
|
2011-01-30 18:56:51 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def invokeOriginalBuilder(self, env, target, source, **kw):
|
|
|
|
|
return self.get().__call__ (env, target, source, **kw)
|
|
|
|
|
|
|
|
|
|
def buildLocation(self, env, target):
|
|
|
|
|
""" prefix project output directory """
|
|
|
|
|
prefix = self.getBuildDestination(env)
|
|
|
|
|
return list(prefix+str(name) for name in target)
|
|
|
|
|
|
|
|
|
|
def installTarget(self, env, buildTarget, **kw):
|
|
|
|
|
""" create an additional installation target
|
|
|
|
|
for the generated executable artifact
|
|
|
|
|
"""
|
|
|
|
|
indeedInstall = lambda p: p and p.get('install')
|
|
|
|
|
|
|
|
|
|
if indeedInstall(kw):
|
|
|
|
|
return env.Install (dir = self.getInstallDestination(env), source=buildTarget)
|
|
|
|
|
else:
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
2011-01-30 16:47:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class LumieraExeBuilder(WrappedStandardExeBuilder):
|
|
|
|
|
|
|
|
|
|
def getCustomEnvironment(self, lumiEnv, **kw):
|
|
|
|
|
""" augments the built-in Program() builder to add a fixed rpath based on $ORIGIN
|
|
|
|
|
That is: after searching LD_LIBRARY_PATH, but before the standard linker search,
|
|
|
|
|
the directory relative to the position of the executable ($ORIGIN) is searched.
|
|
|
|
|
This search path is active not only for the executable, but for all libraries
|
|
|
|
|
it is linked with.
|
|
|
|
|
@note: enabling the new ELF dynamic tags. This causes a DT_RUNPATH to be set,
|
|
|
|
|
which results in LD_LIBRARY_PATH being searched *before* the RPATH
|
|
|
|
|
"""
|
|
|
|
|
custEnv = lumiEnv.Clone()
|
2011-01-30 19:20:02 +01:00
|
|
|
custEnv.Append( LINKFLAGS = "-Wl,-rpath=\\$$ORIGIN/modules,--enable-new-dtags" )
|
2015-08-10 04:44:33 +02:00
|
|
|
custEnv.Append( LINKFLAGS = "-Wl,-rpath-link=target/modules" ) ### Workaround for bug in binutils > 2.23 /////TICKET #965
|
2013-11-02 23:54:45 +01:00
|
|
|
if 'addLibs' in kw:
|
|
|
|
|
custEnv.Append(LIBS = kw['addLibs'])
|
2011-01-30 16:47:03 +01:00
|
|
|
return custEnv
|
2011-01-30 18:56:51 +01:00
|
|
|
|
|
|
|
|
def getBuildDestination(self, lumiEnv): return lumiEnv.path.buildExe
|
|
|
|
|
def getInstallDestination(self, lumiEnv): return lumiEnv.path.installExe
|
|
|
|
|
|
|
|
|
|
|
2011-01-30 16:47:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class LumieraModuleBuilder(WrappedStandardExeBuilder):
|
|
|
|
|
|
|
|
|
|
def getCustomEnvironment(self, lumiEnv, target, **kw):
|
|
|
|
|
""" augments the built-in SharedLibrary() builder to add some tweaks missing in SCons 1.0,
|
fix for resolution of transitive dependencies between "Lumiera modules"
This is a somewhat intricate problem. As long as we linked with --no-as-needed,
these problems could not manifest themselves, since all dependencies are spotted
correctly by SCons and thus added as direct children of the executable.
But when we switch to --as-needed linking, the linker will omit some of
the dependencies given from the build system, when the code to be linked
doesn't call directly into these dependencies. But of course dynamic modules
may depend on each other, and indeed, the Lumiera libs do so. Thus
the linker may omit the dependency to liblumierasupport, and just add
a dependency to, say liblumierabackend. But the backend in turn
depends on the support library.
Now the problem is, that when resolving several steps deep into such
a dependency chain, our special relative path resolution scheme fails.
The fix is to give each lumiera module itself another relative path
resolution spec, which overrides at that point the root spec given
for the executable. Thus, we define
- for the executable: "search at $ORIGIN/modules"
- for the modules: "search at $ORIGIN/../modules"
This accounts for the fact, that a module, which is the Origin
for a transitive resolution step, already sits in a subdirectory
below the executable; thus step one level up and devle down into
the hard wired modules directory. Alternatively, we could also
use just "search at $ORIGIN" (i.e. in the same directory).
But assuming that in future we'll roll several core plugins,
which also count as "Lumiera modules", the scheme defined here
is more flexible, since it allows to place those core plugins
into sibling directories.
2014-10-01 00:21:47 +02:00
|
|
|
like setting a SONAME proper instead of just passing the relative pathname to the linker.
|
|
|
|
|
Besides, we override the library search path to allow for transitive dependencies between
|
|
|
|
|
Lumiera modules; modules are assumed to reside in a subdirectory below the executable.
|
2011-01-30 16:47:03 +01:00
|
|
|
"""
|
|
|
|
|
custEnv = lumiEnv.Clone()
|
|
|
|
|
custEnv.Append(LINKFLAGS = "-Wl,-soname="+self.defineSoname(target,**kw))
|
fix for resolution of transitive dependencies between "Lumiera modules"
This is a somewhat intricate problem. As long as we linked with --no-as-needed,
these problems could not manifest themselves, since all dependencies are spotted
correctly by SCons and thus added as direct children of the executable.
But when we switch to --as-needed linking, the linker will omit some of
the dependencies given from the build system, when the code to be linked
doesn't call directly into these dependencies. But of course dynamic modules
may depend on each other, and indeed, the Lumiera libs do so. Thus
the linker may omit the dependency to liblumierasupport, and just add
a dependency to, say liblumierabackend. But the backend in turn
depends on the support library.
Now the problem is, that when resolving several steps deep into such
a dependency chain, our special relative path resolution scheme fails.
The fix is to give each lumiera module itself another relative path
resolution spec, which overrides at that point the root spec given
for the executable. Thus, we define
- for the executable: "search at $ORIGIN/modules"
- for the modules: "search at $ORIGIN/../modules"
This accounts for the fact, that a module, which is the Origin
for a transitive resolution step, already sits in a subdirectory
below the executable; thus step one level up and devle down into
the hard wired modules directory. Alternatively, we could also
use just "search at $ORIGIN" (i.e. in the same directory).
But assuming that in future we'll roll several core plugins,
which also count as "Lumiera modules", the scheme defined here
is more flexible, since it allows to place those core plugins
into sibling directories.
2014-10-01 00:21:47 +02:00
|
|
|
custEnv.Append( LINKFLAGS = "-Wl,-rpath=\\$$ORIGIN/../modules,--enable-new-dtags" )
|
2013-11-02 23:54:45 +01:00
|
|
|
if 'addLibs' in kw:
|
|
|
|
|
custEnv.Append(LIBS = kw['addLibs'])
|
2011-01-30 16:47:03 +01:00
|
|
|
return custEnv
|
|
|
|
|
|
2011-01-30 18:56:51 +01:00
|
|
|
def getBuildDestination(self, lumiEnv): return lumiEnv.path.buildLib
|
|
|
|
|
def getInstallDestination(self, lumiEnv): return lumiEnv.path.installLib
|
|
|
|
|
|
2011-01-30 16:47:03 +01:00
|
|
|
|
|
|
|
|
def defineSoname (self, target, **kw):
|
|
|
|
|
""" internal helper to extract or guess
|
|
|
|
|
a suitable library SONAME, either using an
|
|
|
|
|
explicit spec, falling back on the lib filename
|
|
|
|
|
"""
|
|
|
|
|
if 'soname' in kw:
|
2011-12-03 05:46:36 +01:00
|
|
|
soname = self.subst(kw['soname']) # explicitly defined by user
|
2011-01-30 16:47:03 +01:00
|
|
|
else: # else: use the library filename as DT_SONAME
|
|
|
|
|
if SCons.Util.is_String(target):
|
|
|
|
|
pathname = target.strip()
|
|
|
|
|
elif 1 == len(target):
|
|
|
|
|
pathname = str(target[0]).strip()
|
|
|
|
|
else:
|
|
|
|
|
raise SyntaxError("Lumiera Library builder requires exactly one target spec. Found target="+str(target))
|
|
|
|
|
|
|
|
|
|
assert pathname
|
|
|
|
|
(dirprefix, libname) = path.split(pathname)
|
|
|
|
|
if not libname:
|
|
|
|
|
raise ValueError("Library name missing. Only got a directory: "+pathname)
|
|
|
|
|
|
|
|
|
|
soname = "${SHLIBPREFIX}%s$SHLIBSUFFIX" % libname
|
|
|
|
|
|
|
|
|
|
assert soname
|
|
|
|
|
return soname
|
|
|
|
|
|
|
|
|
|
|
2011-01-30 18:56:51 +01:00
|
|
|
|
|
|
|
|
class LumieraPluginBuilder(LumieraModuleBuilder):
|
|
|
|
|
|
|
|
|
|
def getCustomEnvironment(self, lumiEnv, target, **kw):
|
|
|
|
|
""" in addition to the ModuleBuilder, define the Lumiera plugin suffix
|
|
|
|
|
"""
|
|
|
|
|
custEnv = LumieraModuleBuilder.getCustomEnvironment(self, lumiEnv, target, **kw)
|
|
|
|
|
custEnv.Append (CPPDEFINES='LUMIERA_PLUGIN')
|
|
|
|
|
custEnv.Replace(SHLIBPREFIX='', SHLIBSUFFIX='.lum')
|
|
|
|
|
return custEnv
|
|
|
|
|
|
|
|
|
|
def getBuildDestination(self, lumiEnv): return lumiEnv.path.buildPlug
|
|
|
|
|
def getInstallDestination(self, lumiEnv): return lumiEnv.path.installPlug
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-30 22:12:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-01-30 16:47:03 +01:00
|
|
|
def register_LumieraCustomBuilders (lumiEnv):
|
2011-12-03 05:46:36 +01:00
|
|
|
""" install the customised builder versions tightly integrated with our build system.
|
2011-01-30 16:47:03 +01:00
|
|
|
Especially, these builders automatically add the build and installation locations
|
|
|
|
|
and set the RPATH and SONAME in a way to allow a relocatable Lumiera directory structure
|
|
|
|
|
"""
|
2011-01-30 18:56:51 +01:00
|
|
|
programBuilder = LumieraExeBuilder (lumiEnv['BUILDERS']['Program'])
|
|
|
|
|
libraryBuilder = LumieraModuleBuilder (lumiEnv['BUILDERS']['SharedLibrary'])
|
|
|
|
|
smoduleBuilder = LumieraModuleBuilder (lumiEnv['BUILDERS']['LoadableModule'])
|
|
|
|
|
lpluginBuilder = LumieraPluginBuilder (lumiEnv['BUILDERS']['LoadableModule'])
|
2011-01-30 16:47:03 +01:00
|
|
|
|
2011-01-30 18:56:51 +01:00
|
|
|
lumiEnv['BUILDERS']['Program'] = programBuilder
|
|
|
|
|
lumiEnv['BUILDERS']['SharedLibrary'] = libraryBuilder
|
|
|
|
|
lumiEnv['BUILDERS']['LoadableModule'] = smoduleBuilder
|
2011-01-30 17:00:15 +01:00
|
|
|
lumiEnv['BUILDERS']['LumieraPlugin'] = lpluginBuilder
|
2011-01-30 22:12:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
2011-12-03 05:46:36 +01:00
|
|
|
# adding SymLink directly as method on the environment object
|
2011-01-30 22:12:55 +01:00
|
|
|
# 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)
|