LUMIERA.clone/SConstruct
Ichthyostega 944b7c4dd4 preliminary fix for the SCons build for Debian/testing
WARNING: breakes build on Debian/stable
Explanation: I tried to provide a backported implementtation of
features introduced with SCons 1.0 (until we can require SCons 1.0 officially)
Unfortionately, some internal APIs changed quite large in 0.97
Have to build in some conditional code, so it works with SCons 0.96 again)
2008-08-20 15:50:17 +01:00

390 lines
14 KiB
Python

# -*- python -*-
##
## SConstruct - SCons based build-sytem for Lumiera
##
# 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.
#####################################################################
import sys
sys.path.append("./admin/scons")
import os
from Buildhelper import *
from LumieraEnvironment import *
#-----------------------------------Configuration
OPTIONSCACHEFILE = 'optcache'
CUSTOPTIONSFILE = 'custom-options'
SRCDIR = 'src'
BINDIR = 'bin'
TESTDIR = 'tests'
ICONDIR = 'icons'
VERSION = '0.1+pre.01'
SVGRENDERER = 'admin/render-icon'
#-----------------------------------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.
#####################################################################
def setupBasicEnvironment():
""" define cmdline options, build type decisions
"""
EnsurePythonVersion(2,3)
EnsureSConsVersion(0,96,90)
opts = defineCmdlineOptions()
env = LumieraEnvironment(options=opts)
env.Append ( CCCOM=' -std=gnu99') # workaround for a bug: CCCOM currently doesn't honor CFLAGS, only CCFLAGS
env.Replace( VERSION=VERSION
, SRCDIR=SRCDIR
, BINDIR=BINDIR
, ICONDIR=ICONDIR
, 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 ' # -fdiagnostics-show-option
)
RegisterIcon_Builder(env,SVGRENDERER)
RegisterPrecompiledHeader_Builder(env)
handleNoBugSwitches(env)
env.Append(CPPDEFINES = '_GNU_SOURCE')
appendCppDefine(env,'DEBUG','DEBUG', 'NDEBUG')
appendCppDefine(env,'OPENGL','USE_OPENGL')
appendVal(env,'ARCHFLAGS', 'CCFLAGS') # for both C and C++
appendVal(env,'OPTIMIZE', 'CCFLAGS', val=' -O3')
appendVal(env,'DEBUG', 'CCFLAGS', val=' -ggdb')
prepareOptionsHelp(opts,env)
opts.Save(OPTIONSCACHEFILE, env)
return env
def appendCppDefine(env,var,cppVar, elseVal=''):
if env[var]:
env.Append(CPPDEFINES = cppVar )
elif elseVal:
env.Append(CPPDEFINES = elseVal)
def appendVal(env,var,targetVar,val=None):
if env[var]:
env.Append( **{targetVar: val or env[var]})
def handleNoBugSwitches(env):
""" set the build level for NoBug.
Release builds imply no DEBUG
wheras ALPHA and BETA require DEBUG
"""
level = env['BUILDLEVEL']
if level in ['ALPHA', 'BETA']:
if not env['DEBUG']:
print 'Warning: NoBug ALPHA or BETA builds requires DEBUG=yes, switching DEBUG on!'
env.Replace( DEBUG = 1 )
env.Append(CPPDEFINES = 'EBUG_'+level)
elif level == 'RELEASE':
env.Replace( DEBUG = 0 )
def defineCmdlineOptions():
""" current options will be persisted in a options cache file.
you may define custom options in a separate file.
Commandline will override both.
"""
opts = Options([OPTIONSCACHEFILE, CUSTOPTIONSFILE])
opts.AddOptions(
('ARCHFLAGS', 'Set architecture-specific compilation flags (passed literally to gcc)','')
,EnumOption('BUILDLEVEL', 'NoBug build level for debugging', 'ALPHA',
allowed_values=('ALPHA', 'BETA', 'RELEASE'))
,BoolOption('DEBUG', 'Build with debugging information and no optimizations', False)
,BoolOption('OPTIMIZE', 'Build with strong optimization (-O3)', False)
,BoolOption('OPENGL', 'Include support for OpenGL preview rendering', False)
# ,EnumOption('DIST_TARGET', 'Build target architecture', 'auto',
# allowed_values=('auto', 'i386', 'i686', 'x86_64' ), ignorecase=2)
,PathOption('DESTDIR', 'Installation dir prefix', '/usr/local')
,PathOption('SRCTAR', 'Create source tarball prior to compiling', '..', PathOption.PathAccept)
,PathOption('DOCTAR', 'Create tarball with dev documentaionl', '..', PathOption.PathAccept)
)
return opts
def prepareOptionsHelp(opts,env):
prelude = """
USAGE: scons [-c] [OPTS] [key=val [key=val...]] [TARGETS]
Build and optionally install Lumiera.
Without specifying any target, just the (re)build target will run.
Add -c to the commandline to clean up anything a given target would produce
Special Targets:
build : just compile and link
testcode: additionally compile the Testsuite
check : build and run the Testsuite
doc : generate documetation (Doxygen)
install : install created artifacts at PREFIX
src.tar : create source tarball
doc.tar : create developer doc tarball
tar : create all tarballs
Configuration Options:
"""
Help(prelude + opts.GenerateHelpText(env))
def configurePlatform(env):
""" locate required libs.
setup platform specific options.
Abort build in case of failure.
"""
conf = env.Configure()
# run all configuration checks in the given env
# Perform checks for prerequisites --------------------------------------------
if not conf.TryAction('pkg-config --version > $TARGET')[0]:
print 'We need pkg-config for including library configurations, exiting.'
Exit(1)
if not conf.CheckLibWithHeader('m', 'math.h','C'):
print 'Did not find math.h / libm, exiting.'
Exit(1)
if not conf.CheckLibWithHeader('dl', 'dlfcn.h', 'C'):
print 'Functions for runtime dynamic loading not available, exiting.'
Exit(1)
if not conf.CheckLibWithHeader('nobugmt', 'nobug.h', 'C'):
print 'Did not find NoBug [http://www.pipapo.org/pipawiki/NoBug], exiting.'
Exit(1)
if not conf.CheckLibWithHeader('pthread', 'pthread.h', 'C'):
print 'Did not find the pthread lib or pthread.h, exiting.'
else:
conf.env.Append(CPPFLAGS = ' -DHAVE_PTHREAD')
conf.env.Append(CCFLAGS = ' -pthread')
if conf.CheckCHeader('execinfo.h'):
conf.env.Append(CPPFLAGS = ' -DHAS_EXECINFO_H')
if conf.CheckCHeader('valgrind/valgrind.h'):
conf.env.Append(CPPFLAGS = ' -DHAS_VALGRIND_VALGIND_H')
if not conf.CheckCXXHeader('tr1/memory'):
print 'We rely on the std::tr1 proposed standard extension for shared_ptr.'
Exit(1)
if not conf.CheckCXXHeader('boost/config.hpp'):
print 'We need the C++ boost-lib.'
Exit(1)
else:
if not conf.CheckCXXHeader('boost/shared_ptr.hpp'):
print 'We need boost::shared_ptr (shared_ptr.hpp).'
Exit(1)
if not conf.CheckLibWithHeader('boost_program_options-mt','boost/program_options.hpp','C++'):
print 'We need boost::program_options (including binary lib for linking).'
Exit(1)
if not conf.CheckLibWithHeader('boost_regex-mt','boost/regex.hpp','C++'):
print 'We need the boost regular expression lib (incl. binary lib for linking).'
Exit(1)
# if not conf.CheckLibWithHeader('gavl', ['gavlconfig.h', 'gavl/gavl.h'], 'C'):
if not conf.CheckPkgConfig('gavl', 1.0):
print 'Did not find Gmerlin Audio Video Lib [http://gmerlin.sourceforge.net/gavl.html], exiting.'
Exit(1)
else:
conf.env.mergeConf('gavl')
if not conf.CheckPkgConfig('gtkmm-2.4', 2.8):
print 'Unable to configure GTK--, exiting.'
Exit(1)
if not conf.CheckPkgConfig('glibmm-2.4', '2.16'):
print 'Unable to configure Lib glib--, exiting.'
Exit(1)
if not conf.CheckPkgConfig('cairomm-1.0', 0.6):
print 'Unable to configure Cairo--, exiting.'
Exit(1)
if not conf.CheckPkgConfig('gdl-1.0', '0.6.1'):
print 'Unable to configure the GNOME DevTool Library, exiting.'
Exit(1)
if not conf.CheckPkgConfig('librsvg-2.0', '2.18.1'):
print 'Need rsvg Library for rendering icons.'
Exit(1)
if not conf.CheckPkgConfig('xv'): Exit(1)
# if not conf.CheckPkgConfig('xext'): Exit(1)
# if not conf.CheckPkgConfig('sm'): Exit(1)
#
# obviously not needed?
print "** Gathered Library Info: %s" % conf.env.libInfo.keys()
# create new env containing the finished configuration
return conf.Finish()
def definePackagingTargets(env, artifacts):
""" build operations and targets to be done /before/ compiling.
things like creating a source tarball or preparing a version header.
"""
t = Tarball(env,location='$SRCTAR',dirs='$SRCDIR')
artifacts['src.tar'] = t
env.Alias('src.tar', t)
env.Alias('tar', t)
t = Tarball(env,location='$DOCTAR',suffix='-doc',dirs='admin doc wiki uml tests')
artifacts['doc.tar'] = t
env.Alias('doc.tar', t)
env.Alias('tar', t)
def defineBuildTargets(env, artifacts):
""" define the source file/dirs comprising each artifact to be built.
setup sub-environments with special build options if necessary.
We use a custom function to declare a whole tree of srcfiles.
"""
objback = srcSubtree(env,'$SRCDIR/backend')
objproc = srcSubtree(env,'$SRCDIR/proc')
objlib = ( srcSubtree(env,'$SRCDIR/common')
+ srcSubtree(env,'$SRCDIR/lib')
)
objplug = srcSubtree(env,'$SRCDIR/plugin', isShared=True)
core = ( env.StaticLibrary('$BINDIR/lumiback.la', objback)
+ env.StaticLibrary('$BINDIR/lumiproc.la', objproc)
+ env.StaticLibrary('$BINDIR/lumi.la', objlib)
)
# use PCH to speed up building
# precomp = ( env.PrecompiledHeader('$SRCDIR/pre')
# + env.PrecompiledHeader('$SRCDIR/pre_a')
# )
# env.Depends(objproc, precomp)
# env.Depends(objlib, precomp)
artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/main.cpp']+ core )
artifacts['plugins'] = env.SharedLibrary('$BINDIR/lumiera-plugin', objplug)
# the Lumiera GTK GUI
envgtk = env.Clone().mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','librsvg-2.0','xv','xext','sm'])
objgui = srcSubtree(envgtk,'$SRCDIR/gui')
# render and install Icons
vector_icon_dir = env.subst('$ICONDIR/svg')
prerendered_icon_dir = env.subst('$ICONDIR/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['lumigui'] = ( envgtk.Program('$BINDIR/lumigui', objgui + core)
+ env.Install('$BINDIR', env.Glob('$SRCDIR/gui/*.rc'))
+ artifacts['icons']
)
# call subdir SConscript(s) for independent components
SConscript(dirs=[SRCDIR+'/tool'], exports='env artifacts core')
SConscript(dirs=['admin'], exports='env envgtk artifacts core')
SConscript(dirs=[TESTDIR], exports='env artifacts core')
def definePostBuildTargets(env, artifacts):
""" define further actions after the core build (e.g. Documentaion).
define alias targets to trigger the installing.
"""
ib = env.Alias('install-bin', '$DESTDIR/bin')
il = env.Alias('install-lib', '$DESTDIR/lib')
env.Alias('install', [ib, il])
build = env.Alias('build', artifacts['lumiera']+artifacts['lumigui']+artifacts['plugins']+artifacts['tools'])
allbu = env.Alias('allbuild', build+artifacts['testsuite'])
env.Default('build')
# additional files to be cleaned when cleaning 'build'
env.Clean ('build', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log' ])
env.Clean ('build', [ '$SRCDIR/pre.gch' ])
# Doxygen documentation
# Note: at the moment we only depend on Doxyfile
# obviousely, we should depend on all sourcefiles
# real Doxygen builder for scons is under developement for 0.97
# so for the moment I prefere not to bother
doxyfile = File('doc/devel/Doxyfile')
env.NoClean(doxyfile)
doxydoc = artifacts['doxydoc'] = [ Dir('doc/devel/html'), Dir('doc/devel/latex') ]
env.Command(doxydoc, doxyfile, "doxygen Doxyfile 2>&1 |tee ,doxylog", chdir='doc/devel')
env.Clean ('doc/devel', doxydoc + ['doc/devel/,doxylog'])
def defineInstallTargets(env, artifacts):
""" define some artifacts to be installed into target locations.
"""
env.Install(dir = '$DESTDIR/bin', source=artifacts['lumiera'])
env.Install(dir = '$DESTDIR/lib', source=artifacts['plugins'])
env.Install(dir = '$DESTDIR/bin', source=artifacts['tools'])
env.Install(dir = '$DESTDIR/share/doc/lumiera$VERSION/devel', source=artifacts['doxydoc'])
#####################################################################
### === MAIN === ####################################################
env = setupBasicEnvironment()
if not (isCleanupOperation(env) or isHelpRequest()):
env = configurePlatform(env)
artifacts = {}
# the various things we build.
# Each entry actually is a SCons-Node list.
# Passing these entries to other builders defines dependencies.
# 'lumiera' : the App
# 'plugins' : plugin shared lib
# 'tools' : small tool applications (e.g mpegtoc)
# 'src,tar' : source tree as tarball (without doc)
# 'doc.tar' : uml model, wiki, dev docu (no src)
definePackagingTargets(env, artifacts)
defineBuildTargets(env, artifacts)
definePostBuildTargets(env, artifacts)
defineInstallTargets(env, artifacts)