Merge Buildsystem adaptations for installing Lumiera

- use custom builders
- clean up specification of target paths
- generated executable is fully relocatable
- read a bootstrap INI instead of compiled in searchpath
This commit is contained in:
Fischlurch 2011-02-05 15:54:24 +01:00
commit ad246ad31d
23 changed files with 1141 additions and 409 deletions

4
.gitignore vendored
View file

@ -10,7 +10,7 @@
optcache optcache
Makefile.in Makefile.in
build/* build/*
bin/* target/*
autom4te.cache/* autom4te.cache/*
scripts/* scripts/*
configure configure
@ -18,7 +18,7 @@ config.log
aclocal.m4 aclocal.m4
autom4te.cache autom4te.cache
semantic.cache semantic.cache
tests/,*
wiki/backups/* wiki/backups/*
doc/devel/draw/*.png
doc/devel/uml/fig128309.png doc/devel/uml/fig128309.png
m4/* m4/*

168
AUTHORS
View file

@ -1,58 +1,134 @@
Lumiera Authors and Credits
===========================
Version: 0.pre.0.1
Date: 2/2011
Cinelerra(2) Authors
====================
hv=Jack Crossfire <broadcast@earthling.net> '`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
j6t=Johannes Sixt <johannes.sixt@telecom.at> Architecture and Design,
minmax=Andraz Tori <Andraz.tori1@guest.arnes.si> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
herman=Herman Robak <herman@skolelinux.no> graphical user interface, JOEL HOLDSWORTH
baver=Richard Baverstock <baver@thebeever.com> , CLAY BARNES
pere=Petter Reinholdtsen <pere@hungry.com> processing layer , HERMANN VOSSELER
tfheen=Tollef Fog Heen <tollef@add.no> backend , CHRISTIAN THÄTER
andreask=Andreas Kielb <andreaskielb@web.de> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
theraz=Tyler Geddes <tgeddes@wgeddes.com>
dyce=Gergely Erdelyi <dyce@rovidzar.hu>
dreamlx=David Arendt <admin@prnet.org>
ga=Gustavo Iniguez <ga@kutxa.homeunix.org>
memenk=Michael Eric Menk <meklev@osys.grm.hia.no>
benjif=Benjamin Flaming <cinelerra@solobanjo.com>
cobra=Kevin Brosius <cobra@compuserve.com>
taraba=Mark Taraba <m_taraba@yahoo.com>
nate=Nathan Kurz <nate@verse.com>
mammique=Camille Harang <mammique@garbure.org>
kbielefe=Karl Bielefeldt <uhauufo02@sneakemail.com>
alexf=Alex Ferrer <alex@ftconsult.com>
pmdumuid=Pierre Dumuid <pierre.dumuid@adelaide.edu.au>
giskard=Riccardo Setti <giskard@autistici.org>
jstewart=Joe Stewart <jstewart@lurhq.com>
doudou=Sylvain Joyeux <doudou@melix.net>
rafael2k=Rafael Diniz <rafael@riseup.net>
nicolasm=Nicolas Maufrais <e.conti@gmx.net>
Involved in Lumiera development '`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=============================== Programming,
cehteh=Christian Thaeter <ct@pipapo.org> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ichthyo=Hermann Vosseler <Ichthyostega@web.de> rendering engine, HERMANN VOSSELER
plouj=Michael Ploujnikov <ploujj@gmail.com> backend, CHRISTIAN THÄTER
GTK-GUI, JOEL HOLDSWORTH
, STEFAN KANGAS
library, HERMANN VOSSELER
, CHRISTIAN THÄTER
, ANTON YAKOVLEV
, SIMEON VÖLKEL
testsuite, CHRISTIAN THÄTER
, NICHOLAS SINNOTT-ARMSTRONG
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Programming Documentation,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
, MICHAEL PLOUJNIKOV
, ODIN HØRTHE OMDAL
, SIMON LARCHER
, SIMEON VÖLKEL
, MANO STIENEN
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Used Software and Libraries,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
boost libraries,
gavl libraries,
gtk+ toolkit,
lua,
nobug,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Builddrone,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
idea and implementation, CHRISTIAN THÄTER
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//'`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ,Testing
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ,
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Workflow design,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
concept , NIKOLA DUPER
, BRIAN RYTEL
, MIKE PROVOST
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Server Administration,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
, CHRISTIAN THÄTER
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Cinelerra
---------
Lumiera is an offspring of the Cinelerra video editor. +
It started out as a partial rewrite of Cinelerra in 2007
and turned into a complete rewrite and redesign in Spring 2008
'`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Lumiera project feels especially obliged to,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Cinelerra's original Author, ADAM WILLIAMS / aka. "Jack Crossfire" / aka "HV"
Cinelerra-CV , all the numerous contributors
, of the "Community Version"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
_______________________________________________________________
Further Credits Further Credits
---------------
Parts of the Proc-Layer Implementation are heavily inspired by Parts of the Proc-Layer Implementation are heavily inspired by
The Loki Library
Copyright (c) 2001 by Andrei Alexandrescu
Loki is governed by a MIT-License. .The Loki Library
See: http://loki-lib.sourceforge.net [quote]
and the book: __________________________________________________________________________
Alexandrescu, Andrei. Copyright (c) 2001 by *Andrei Alexandrescu* +
"Modern C++ Design: Generic Programming and Design
Patterns Applied". Copyright (c) 2001. Addison-Wesley. .Loki Copyright Notice
ISBN 0201704315 * Loki is governed by a MIT-License. See: http://loki-lib.sourceforge.net
* Permission to use, copy, modify, distribute and sell this software for any
Loki Copyright Notice:
Permission to use, copy, modify, distribute and sell this software for any
purpose is hereby granted without fee, provided that the above copyright purpose is hereby granted without fee, provided that the above copyright
notice appear in all copies and that both that copyright notice and this notice appear in all copies and that both that copyright notice and this
permission notice appear in supporting documentation. permission notice appear in supporting documentation.
The author makes no representations about the suitability of this software The author makes no representations about the suitability of this software
for any purpose. It is provided "as is" without express or implied warranty. for any purpose. It is provided "as is" without express or implied warranty.
.the ``Loki Book''
[verse]
Alexandrescu, Andrei.
"Modern C++ Design: Generic Programming and Design Patterns Applied".
Copyright (c) 2001. Addison-Wesley.
ISBN 0201704315
_____________________________________________________________________________

244
INSTALL
View file

@ -1,50 +1,82 @@
Running / Installing Lumiera Prototype Running / Installing Lumiera Prototype
====================================== ======================================
Date: 2/2011
From: Lumiera uses a fairly standard build system. There are no special quirks.
http://www.pipapo.org/pipawiki/Lumiera/NewbiesTutorials The build system will tell you about missing library dependencies. You can
build, run the +check+ target for the Testsuite and finally install (as root).
But you don't need to install, because the generated +target+ folder is set up
to be fully relocatable. You can invoke the executables right away, or copy the
whole +target+ folder structure at any location you like. The executables
will always use the direcly accompanying libraries in the +modules+ subdirectory.
The following text is taken from our
link:http://www.pipapo.org/pipawiki/Lumiera/NewbiesTutorials[Newbies Tutorial]
to help beginners getting started with Lumiera development.
Newbies Tutorials Building Lumiera from source
----------------------------
Currently, after building the application, you can try out the Lumiera GUI
and you can run the testsuite.
This page contains some tutorials for beginners that want to help to the For building Lumiera, besides the GNU C/C++ compiler (Version 4.X), you'll need:
developers of Lumiera.
Trying the Lumiera GUI from Joel * http://git-scm.com/[git]
* http://www.gnu.org/software/libtool/[libtool]
* http://www.boost.org/[Boost libraries]
* http://gmerlin.sourceforge.net/[GAVL library]
* *NoBug* (see below)
You need to have: TIP: Generally speaking, when you want to build software, you need the _development_ version
of the packages, containing the headers and pre-built libraries to link against. Usually,
these packages are named `-devel` or `-dev`
* libboost .Notes for Ubuntu:
* libtool
* git
* libgavl
* nobug(see below)
For Ubuntu Hardy also: On Hardy you need also:
* libglade2-dev * libglade2-dev
* libgdl-1-dev * libgtkmm-2.4-dev
* libgtkmm-2.4-dev * libxv-dev
* libxv-dev
Optionally, you may also want to install: For most Debian based systems, e.g. Ubuntu Intrepid and Jaunty, you can install these dependencies with:
* gtk2-engines ------------------------------------------------------------
sudo apt-get install build-essential autoconf libboost-dev libboost-program-options-dev libboost-regex-dev \
libtool libgavl-dev libglade2-dev libgdl-1-dev libgtkmm-2.4-dev libxv-dev scons valgrind librsvg2-dev git-core
------------------------------------------------------------
also check http://gnuradio.org/trac/wiki/UbuntuInstall#InstallationOptions to
see that all your installations options are met.
Installing nobug from git Build directory
~~~~~~~~~~~~~~~
You need a directory for checking out the sources and running the build. This could be a temp directory,
or some "workspace" directory below your home directory. We'll call it _workspace directory_ from now on.
Create a temp directory where you can have the sourcecode of the libraries you Lumiera specific libraries
will use as well as lumieras branches you want to try. Example ~/temp. cd to ~~~~~~~~~~~~~~~~~~~~~~~~~~
that directory and run: Now that you have your basic build system setup, Lumiera needs a few more special support libraries.
Currently you need to build those from source and install them, so the Lumiera build process can
pick them up.
WARNING: Note that the following procedures will try to install files into your base system below `/usr/local`.
To do so, you'll need administrative permissions for the machine you're working on. These additions might interfere
with other libraries installed by your package manager (if you get into trouble updating your system later on,
sometimes you need to remove these manually built librararies).
Installing NoBug
^^^^^^^^^^^^^^^^
*NoBug* is an instrumentation and diagnostics library. +
Go into the mentioned _workspace direcory_ (maybe create a new directory). First, let's get the NoBug source code:
------------------------------------------------------------
git clone git://git.pipapo.org/nobug git clone git://git.pipapo.org/nobug
------------------------------------------------------------
This will create a (sub)directory called nobug with sourcecode in your current directory. +
Compile NoBug with the following commands
This will create a directory called nobug with sourcecode in your current ------------------------------------------------------------
directory.
cd nobug cd nobug
autoreconf -i autoreconf -i
mkdir build mkdir build
@ -52,11 +84,78 @@ cd build
../configure ../configure
make make
make install make install
------------------------------------------------------------
Getting the Lumiera source code Installing GDL
^^^^^^^^^^^^^^
The *GNOME Docking library* is generally available through your package manager, but
we contributed some improvements, which are only available in the very recent development
versions of GDL. Thus, for now we created a special package, which doesn't interfere with
an existing (older) installation of GDL.
In the temp directory Ubuntu 9.04 note: intltool-update is not patched, you must add /usr/share/intltool-debian/ to get the gdl-package to configure correctly (JSC).
------------------------------------------------------------
git clone git://git.lumiera.org/gdl-package
cd gdl-package
./configure
make
sudo make install
------------------------------------------------------------
For more detailed instructions on how to build gdl (also how to build it into a debian package) see
http://lists.lumiera.org/pipermail/lumiera/2009-April/000891.html[this message on the Lumiera Mailinglist].
check library linkage
^^^^^^^^^^^^^^^^^^^^^
The compile will warn you to add various directories to /etc/ld.so.conf and then run ldconfig. This
will allow your dynamic liker to pick up the newly built libraries later when you try to start Lumiera.
If you don't want to reconfigure your system and add `/usr/local/lib` to the mentioned linker configuration,
you may alternatively just add the directories to your LD_LIBRARY_PATH environment variable.
Either way, check that all libraries are accessible and ok:
------------------------------------------------------------
sudo ldconfig -v | grep 'gdl-lum\|nobug'
------------------------------------------------------------
and you should get a list of the libraries, part of which should look like this:
------------------------------------------------------------
libnobug.so.0 -> /usr/local/lib/libnobug.so.0.0.0
libnobugmt.so.0 -> /usr/local/lib/libnobugmt.so.0.0.0
libgdl-lum.so.0 -> /usr/local/lib/libgdl-lum.so.0.0.0
------------------------------------------------------------
or similar. If any if this libs are not listed, investigate why before continuing.
Building Lumiera
~~~~~~~~~~~~~~~~
Lumiera has two maintained (and equivalent) build systems: *scons* and *autotools*. You can pick the one you
feel more comfortable with.
When trying to build a development version of Lumiera, it might well be that at times one of the builds doesn't work temporarily. It is always a good idea to check the current build stats from our *builddrone*, which automatically builds the latest version from master repository. +
Please have a look at this http://lumiera.org/builddrone/table.html[current build stats]-page.
Next, after having built and installed the prerequisite libraries, go into the _workspace directory_ to retrieve the Lumiera source code and build it.
* to retrieve the sourcecode with git and then build with *scons*:
+
(see available build options by issuing `scons -h` )
+
-----------------
git clone git://git.lumiera.org/LUMIERA
cd LUMIERA
scons
-----------------
+
* alternatively, if you prefer building with *autotools*:
+
-----------------
git clone git://git.lumiera.org/LUMIERA git clone git://git.lumiera.org/LUMIERA
cd LUMIERA cd LUMIERA
autoreconf -fi autoreconf -fi
@ -64,40 +163,75 @@ mkdir build
cd build cd build
../configure ../configure
make make
-----------------
maybe run the testsuite by maybe build and run the testsuite by issuing `scons check` or `make check`
make check This will take some time.
This will take some time. After it has finished:
./lumiera Invoking Lumiera
~~~~~~~~~~~~~~~~
NOTE: Currently *only the SCons build creates a relocatable package which can
also be installed*.
After the build has finished successfully, you should be able to start Lumiera.
Currently, this will bring up the GUI, without any further functionality
The +target+ directory generated by the SCons build is fully relocatable -- you can
invoke the executables found there right away and you can copy it at any location you
want, provided you keep the relative location of the contained sub-folders intact.
If you want to include the Lumiera executable into the search path, then just use
a symlink, don't _copy_ the isolated +lumiera+ executable into some +bin+ directory.
Thus
-------------------
target/lumiera
-------------------
should bring up something like (screenshot from 1/2009):
image:http://www.pipapo.org/pipawiki/Lumiera/GuiBrainstorming?action=AttachFile&do=get&target=screenshot090124-resources.jpg[]
_(for autotools build: issue `./lumiera` from within the `build` subdirectory)_
Installing Lumiera
~~~~~~~~~~~~~~~~~~
As of 2/2011, please use the SCons build for that.
Letting aside the fact that you can't do anything useful with the Lumiera in the current stage of development --
you have multiple options for installing Lumiera
* just copy the taget folder somewhere and create a symlink to the +lumiera+ exe
* invoke +scons install INSTALLDIR=... PREFIX=...+
* as root, invoke +scons instal+ to place files at the standard locations below +/usr/local+
* if you're on Debian, you can pull a debian package from +git://git.lumiera.org/lumiera/debian+
This is a source package, you can either use +dpkg_buildpackage+ or +git-buildpackage+ and
then install the generated binary deb with +dpkg -i+
[NewbiesTut]
Contributing Contributing
------------
Nothing is easier, follow the basic instructions at http://www.kernel.org/pub/ Nothing is easier, follow the http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html[the basic instructions],
software/scm/git/docs/gittutorial.html, notably the notably the following parts:
------------------------------------------------------------
$ git config --global user.name "Your Name Comes Here" $ git config --global user.name "Your Name Comes Here"
$ git config --global user.email you@yourdomain.example.com $ git config --global user.email you@yourdomain.example.com
------------------------------------------------------------
parts.
Then you are ready to go, you can edit and commit the lumiera code locally in Then you are ready to go, you can edit and commit the lumiera code locally in your cloned repository. Please do small commits which fix/improve only one single thing and use meaningful commit messages.
your cloned repository. Please do small commits which fix/improve only one
single thing and use meaningful commit messages. Check that you didn't broke Check that you didn't break anything, by running the testsuite (see above)
anything
Finally you can push your changes to the lumiera server to the 'mob' repository:
* by running 'make check'.
------------------------------------------------------------
Finally you can push your changes to the lumiera server to the 'mob' $ git push git://git.lumiera.org/lumiera/mob master:refs/heads/YOURNAME
repository: ------------------------------------------------------------
This creates a new branch 'YOURNAME' on the mob repository. Then you notify the other devs on the mailinglist and they may merge your code into the mainline.
$ git push git://git.lumiera.org/lumiera/mob master:refs/heads/YOURNAME
This creates a new branch 'YOURNAME' on the mob repository. Then you notify the
other devs on the mailinglist and they may merge your code into the mainline.

86
README
View file

@ -1,45 +1,73 @@
====================================
Lumiera -- the video NLE for Linux Lumiera -- the video NLE for Linux
==================================== ====================================
Lumiera is a nonlinear video editing and compositing tool. *************************************************************
It understands some of the common multimedia formats Lumiera is a nonlinear video editing and compositing tool.
(quicktime, avi, ogg) and audio/video compression It understands some of the common multimedia formats
codecs (divx, xvid, mpeg1/2/4, ...). (quicktime, avi, ogg) and audio/video compression
codecs (divx, xvid, mpeg1/2/4, ...)
It features non-destructive editing, compositing tools, It features non-destructive editing, compositing tools,
a selection of effects plugins, processing in RGB, YUV a selection of effects plugins, processing in RGB, YUV
and RGB-float colormodels and the ability to mix media and RGB-float colormodels and the ability to mix media
with differing sizes and framerates. with differing sizes and framerates.
For more information about Lumiera visit http://lumiera.org/ More Informations at http://lumiera.org/[Lumiera.org]
For more information about Cinelerra visit http://cinelerra.org/ ****************************************************************
Lumiera pre-Alpha Versions
--------------------------
---------------------------- **This source tree doesn't yet contain a working video editing application** +
"Lumiera" prototype code Rather, it contains the framework and technology core of the envisioned Application ``Lumiera''.
----------------------------
**This source tree doesn't yet contain a working video editing application** As of _7/2007_::
Rather, it contains the initial framework and core modules of the lower and we start here with the backend and render engine modules
middle layer of the envisioned new Application "Lumiera".
As of 7/2007, we start here with some backend and render engine modules
together with some unit tests. You should find a wiki with detailed together with some unit tests. You should find a wiki with detailed
design considerations and developer documentation and a UML model design considerations and developer documentation and a UML model
(usable with BOUML 2.29) in the sibling directories. (usable with BOUML 2.29) in the sibling directories.
As of 2/2008 the project has been separated completely from its As of _2/2008_::
ancestor "Cinelerra". The Community, which is largely identical to the the project has been separated completely from his ancestor ``Cinelerra''
Cinelerra-CV community, chose the new project name "Lumiera". The The Community, which is largely identical to the Cinelerra-CV community, choose the
basic project infrastructure is up and running, and work on the new new project name ``Lumiera''. The basic project infrastructure is up and running,
codebase is going on continuously. We can show nothing but a running and work on the new codebase is going on continuosely. We can show nothing but
test suite for now. a running test suite for some time to come.
As of _1/2011_::
the project has created and documented a fairly consistent design,
partially already coded up -- starting from the technical foundations and working up.
The code base is approaching 100k LOC. Roughly half of this is testcode.
The Application can be installed and started to bring up an GTK GUI outline,
but the GUI is very preliminary and not connected to core functionality.
The video processing pipeline is still not complete.
See the http://issues.lumiera.org/roadmap[Project roadmap]
Build Requirements
------------------
---------------------------- For building Lumiera, you'll need:
Installation
---------------------------- - GNU C/C++ compiler (Version > 4.3)
- Git Version management system
- http://www.boost.org/[Boost libraries]
- http://gmerlin.sourceforge.net/[GAVL library]
- http://lumiera.org/nobug_manual.html[NoBug library]
- GTK\--
- Cairo and Glade libraries
- X libraries
- http://scons.org[SCons] or Autotools build system
See the online documentation at http://lumiera.org/Lumiera/NewbiesTutorials
or the local Copy of this page in the file INSTALL
Debian Package
--------------
[verse]
Hermann Vosseler (aka Ichthyo) maintains a *Debian* packaging of the source tree,
which can be pulled from +git://git.lumiera.org/lumiera/debian+
It can be built by +git-buildpackage+
See INSTALL file

View file

@ -22,26 +22,40 @@
##################################################################### #####################################################################
#-----------------------------------Configuration
OPTIONSCACHEFILE = 'optcache'
CUSTOPTIONSFILE = 'custom-options'
SRCDIR = 'src'
BINDIR = 'bin'
LIBDIR = '.libs'
PLUGDIR = '.libs'
TESTDIR = 'tests'
ICONDIR = 'icons'
VERSION = '0.1+pre.01'
TOOLDIR = './admin/scons'
SCRIPTDIR = './admin'
#-----------------------------------Configuration
# NOTE: scons -h for help. # NOTE: scons -h for help.
# Read more about the SCons build system at: http://www.scons.org # Read more about the SCons build system at: http://www.scons.org
# Basically, this script just /defines/ the components and how they # Basically, this script just /defines/ the components and how they
# fit together. SCons will derive the necessary build steps. # fit together. SCons will derive the necessary build steps.
#-----------------------------------Configuration
TARGDIR = 'target'
VERSION = '0.pre.01'
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'
installUIRes = '#$DESTDIR/share/lumiera/'
installConf = '#$DESTDIR/lib/lumiera/config'
localDefinitions = locals()
#-----------------------------------Configuration
import os import os
import sys import sys
@ -55,10 +69,10 @@ from LumieraEnvironment import *
##################################################################### #####################################################################
def setupBasicEnvironment(): def setupBasicEnvironment(localDefinitions):
""" define cmdline options, build type decisions """ define cmdline options, build type decisions
""" """
EnsurePythonVersion(2,3) EnsurePythonVersion(2,4)
EnsureSConsVersion(1,0) EnsureSConsVersion(1,0)
Decider('MD5-timestamp') # detect changed files by timestamp, then do a MD5 Decider('MD5-timestamp') # detect changed files by timestamp, then do a MD5
@ -66,26 +80,20 @@ def setupBasicEnvironment():
vars = defineCmdlineVariables() vars = defineCmdlineVariables()
env = LumieraEnvironment(variables=vars env = LumieraEnvironment(variables=vars
,toolpath = [TOOLDIR] ,toolpath = [TOOLDIR]
,tools = ["default", "BuilderGCH", "BuilderDoxygen"] ,pathConfig = extract_localPathDefs(localDefinitions) # e.g. buildExe -> env.path.buildExe
) ,TARGDIR = TARGDIR
env.Tool("ToolDistCC") ,DESTDIR = '$INSTALLDIR/$PREFIX'
env.Tool("ToolCCache") ,VERSION = VERSION
)
handleVerboseMessages(env) handleVerboseMessages(env)
env.Append ( CCCOM=' -std=gnu99') env.Append ( CCCOM=' -std=gnu99')
env.Append ( SHCCCOM=' -std=gnu99') # workaround for a bug: CCCOM currently doesn't honour CFLAGS, only CCFLAGS env.Append ( SHCCCOM=' -std=gnu99') # workaround for a bug: CCCOM currently doesn't honour CFLAGS, only CCFLAGS
env.Replace( VERSION=VERSION env.Replace( CPPPATH =["#src"] # used to find includes, "#" means always absolute to build-root
, SRCDIR=SRCDIR
, BINDIR=BINDIR
, LIBDIR=LIBDIR
, PLUGDIR=PLUGDIR
, 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 , CPPDEFINES=['-DLUMIERA_VERSION='+VERSION ] # note: it's a list to append further defines
, CCFLAGS='-Wall -Wextra ' , CCFLAGS='-Wall -Wextra '
, CFLAGS='-std=gnu99' , CFLAGS='-std=gnu99'
) )
RegisterIcon_Builder(env)
handleNoBugSwitches(env) handleNoBugSwitches(env)
env.Append(CPPDEFINES = '_GNU_SOURCE') env.Append(CPPDEFINES = '_GNU_SOURCE')
@ -96,13 +104,13 @@ def setupBasicEnvironment():
appendVal(env,'DEBUG', 'CCFLAGS', val=' -ggdb') appendVal(env,'DEBUG', 'CCFLAGS', val=' -ggdb')
# setup search path for Lumiera plugins # setup search path for Lumiera plugins
appendCppDefine(env,'PKGLIBDIR','LUMIERA_PLUGIN_PATH=\\"$PKGLIBDIR/:./.libs\\"' appendCppDefine(env,'PKGLIBDIR','LUMIERA_PLUGIN_PATH=\\"$PKGLIBDIR/:ORIGIN/modules\\"'
,'LUMIERA_PLUGIN_PATH=\\"$DESTDIR/lib/lumiera/:./.libs\\"') ,'LUMIERA_PLUGIN_PATH=\\"ORIGIN/modules\\"')
appendCppDefine(env,'PKGDATADIR','LUMIERA_CONFIG_PATH=\\"$PKGLIBDIR/:.\\"' appendCppDefine(env,'PKGDATADIR','LUMIERA_CONFIG_PATH=\\"$PKGLIBDIR/:.\\"'
,'LUMIERA_CONFIG_PATH=\\"$DESTDIR/share/lumiera/:.\\"') ,'LUMIERA_CONFIG_PATH=\\"$DESTDIR/share/lumiera/:.\\"')
prepareOptionsHelp(vars,env) prepareOptionsHelp(vars,env)
vars.Save(OPTIONSCACHEFILE, env) vars.Save(OPTCACHE, env)
return env return env
def appendCppDefine(env,var,cppVar, elseVal=''): def appendCppDefine(env,var,cppVar, elseVal=''):
@ -148,7 +156,7 @@ def defineCmdlineVariables():
you may define custom variable settings in a separate file. you may define custom variable settings in a separate file.
Commandline will override both. Commandline will override both.
""" """
vars = Variables([OPTIONSCACHEFILE, CUSTOPTIONSFILE]) vars = Variables([OPTCACHE, CUSTOPTFILE])
vars.AddVariables( vars.AddVariables(
('ARCHFLAGS', 'Set architecture-specific compilation flags (passed literally to gcc)','') ('ARCHFLAGS', 'Set architecture-specific compilation flags (passed literally to gcc)','')
,('CC', 'Set the C compiler to use.', 'gcc') ,('CC', 'Set the C compiler to use.', 'gcc')
@ -164,11 +172,10 @@ def defineCmdlineVariables():
# ,BoolVariable('OPENGL', 'Include support for OpenGL preview rendering', False) # ,BoolVariable('OPENGL', 'Include support for OpenGL preview rendering', False)
# ,EnumVariable('DIST_TARGET', 'Build target architecture', 'auto', # ,EnumVariable('DIST_TARGET', 'Build target architecture', 'auto',
# allowed_values=('auto', 'i386', 'i686', 'x86_64' ), ignorecase=2) # allowed_values=('auto', 'i386', 'i686', 'x86_64' ), ignorecase=2)
,PathVariable('DESTDIR', 'Installation dir prefix', '/usr/local') ,PathVariable('PREFIX', 'Installation dir prefix', 'usr/local', PathVariable.PathAccept)
,PathVariable('PKGLIBDIR', 'Installation dir for plugins, defaults to DESTDIR/lib/lumiera', '',PathVariable.PathAccept) ,PathVariable('INSTALLDIR', 'Root output directory for install. Final installation will happen in INSTALLDIR/PREFIX/... ', '/', PathVariable.PathIsDir)
,PathVariable('PKGDATADIR', 'Installation dir for default config, usually DESTDIR/share/lumiera', '',PathVariable.PathAccept) ,PathVariable('PKGLIBDIR', 'Installation dir for plugins, defaults to PREFIX/lib/lumiera/modules', '',PathVariable.PathAccept)
,PathVariable('SRCTAR', 'Create source tarball prior to compiling', '..', PathVariable.PathAccept) ,PathVariable('PKGDATADIR', 'Installation dir for default config, usually PREFIX/share/lumiera', '',PathVariable.PathAccept)
,PathVariable('DOCTAR', 'Create tarball with developer documentation', '..', PathVariable.PathAccept)
) )
return vars return vars
@ -187,10 +194,8 @@ Special Targets:
testcode: additionally compile the Testsuite testcode: additionally compile the Testsuite
check : build and run the Testsuite check : build and run the Testsuite
doc : generate documentation (Doxygen) doc : generate documentation (Doxygen)
all : build and testcode and doc
install : install created artifacts at PREFIX install : install created artifacts at PREFIX
src.tar : create source tarball
doc.tar : create developer doc tarball
tar : create all tarballs
Configuration Options: Configuration Options:
""" """
@ -238,15 +243,19 @@ def configurePlatform(env):
conf.env.mergeConf('nobugmt') conf.env.mergeConf('nobugmt')
if not conf.CheckCXXHeader('tr1/memory'): 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'): if not conf.CheckCXXHeader('boost/config.hpp'):
problems.append('We need the C++ boost-lib.') problems.append('We need the C++ boost-libraries.')
else: else:
if not conf.CheckCXXHeader('boost/shared_ptr.hpp'): if not conf.CheckCXXHeader('boost/scoped_ptr.hpp'):
problems.append('We need boost::shared_ptr (shared_ptr.hpp).') problems.append('We need boost::scoped_ptr (scoped_ptr.hpp).')
if not conf.CheckCXXHeader('boost/format.hpp'):
problems.append('We need boost::format (header).')
if not conf.CheckLibWithHeader('boost_program_options-mt','boost/program_options.hpp','C++'): if not conf.CheckLibWithHeader('boost_program_options-mt','boost/program_options.hpp','C++'):
problems.append('We need boost::program_options (including binary lib for linking).') problems.append('We need boost::program_options (including binary lib for linking).')
if not conf.CheckLibWithHeader('boost_filesystem-mt','boost/filesystem.hpp','C++'):
problems.append('We need the boost::filesystem (including binary lib for linking).')
if not conf.CheckLibWithHeader('boost_regex-mt','boost/regex.hpp','C++'): if not conf.CheckLibWithHeader('boost_regex-mt','boost/regex.hpp','C++'):
problems.append('We need the boost regular expression lib (incl. binary lib for linking).') problems.append('We need the boost regular expression lib (incl. binary lib for linking).')
@ -263,16 +272,16 @@ def configurePlatform(env):
conf.env.mergeConf('gavl') conf.env.mergeConf('gavl')
if not conf.CheckPkgConfig('gtkmm-2.4', 2.8): 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'): 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'): if not conf.CheckPkgConfig('gthread-2.0', '2.12.4'):
problems.append('Need gthread support lib for glib-- based thread handling.') problems.append('Need gthread support lib for glib-- based thread handling.')
if not conf.CheckPkgConfig('cairomm-1.0', 0.6): 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' verGDL = '2.27.1'
if not conf.CheckPkgConfig('gdl-lum', verGDL, alias='gdl'): if not conf.CheckPkgConfig('gdl-lum', verGDL, alias='gdl'):
@ -308,19 +317,11 @@ def configurePlatform(env):
def definePackagingTargets(env, artifacts): def defineSetupTargets(env, artifacts):
""" build operations and targets to be done /before/ compiling. """ build operations and targets to be done /before/ compiling.
things like creating a source tarball or preparing a version header. things like creating a source tarball or preparing a version header.
""" """
t = Tarball(env,location='$SRCTAR',dirs='$SRCDIR') pass ## currently none
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)
@ -331,50 +332,51 @@ def defineBuildTargets(env, artifacts):
""" """
# use PCH to speed up building // disabled for now due to strange failures # use PCH to speed up building // disabled for now due to strange failures
# env['GCH'] = ( env.PrecompiledHeader('$SRCDIR/pre.hpp') # env['GCH'] = ( env.PrecompiledHeader('src/pre.hpp')
# + env.PrecompiledHeader('$SRCDIR/pre_a.hpp') # + env.PrecompiledHeader('src/pre_a.hpp')
# ) # )
lApp = env.SharedLibrary('$LIBDIR/lumieracommon', srcSubtree(env,'$SRCDIR/common')) lLib = env.SharedLibrary('lumiera', srcSubtree(env,'src/lib'), install=True)
lBack = env.SharedLibrary('$LIBDIR/lumierabackend', srcSubtree(env,'$SRCDIR/backend')) lApp = env.SharedLibrary('lumieracommon', srcSubtree(env,'src/common'), install=True, LIBS=lLib)
lProc = env.SharedLibrary('$LIBDIR/lumieraproc', srcSubtree(env,'$SRCDIR/proc')) lBack = env.SharedLibrary('lumierabackend', srcSubtree(env,'src/backend'),install=True)
lLib = env.SharedLibrary('$LIBDIR/lumiera', srcSubtree(env,'$SRCDIR/lib')) lProc = env.SharedLibrary('lumieraproc', srcSubtree(env,'src/proc'), install=True)
core = lLib+lApp+lBack+lProc core = lLib+lApp+lBack+lProc
artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) artifacts['corelib'] = core
artifacts['corelib'] = lLib+lApp
artifacts['support'] = lLib artifacts['support'] = lLib
artifacts['lumiera'] = ( env.Program('lumiera', ['src/lumiera/main.cpp'], LIBS=core, install=True)
+ env.ConfigData(env.path.srcConf+'setup.ini')
+ env.ConfigData(env.path.srcConf+'dummy_lumiera.ini')
)
# building Lumiera Plugins # building Lumiera Plugins
envPlu = env.Clone()
envPlu.Append(CPPDEFINES='LUMIERA_PLUGIN')
artifacts['plugins'] = [] # currently none artifacts['plugins'] = [] # currently none
# render and install Icons # render and install Icons
vector_icon_dir = env.subst('$ICONDIR/svg') vector_icon_dir = env.path.srcIcon+'svg'
prerendered_icon_dir = env.subst('$ICONDIR/prerendered') prerendered_icon_dir = env.path.srcIcon+'prerendered'
artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])] artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])]
+ [env.IconCopy(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])] + [env.IconResource(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])]
) )
# the Lumiera GTK GUI # the Lumiera GTK GUI
envGtk = env.Clone() envGtk = env.Clone()
envGtk.mergeConf(['gtkmm-2.4','gthread-2.0','cairomm-1.0','gdl','xv','xext','sm']) envGtk.mergeConf(['gtkmm-2.4','gthread-2.0','cairomm-1.0','gdl','xv','xext','sm'])
envGtk.Append(CPPDEFINES='LUMIERA_PLUGIN', LIBS=core) envGtk.Append(LIBS=core)
objgui = srcSubtree(envGtk,'$SRCDIR/gui') objgui = srcSubtree(envGtk,'src/gui')
guimodule = envGtk.LoadableModule('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') guimodule = envGtk.LumieraPlugin('gtk_gui', objgui, install=True)
artifacts['gui'] = ( guimodule artifacts['gui'] = ( guimodule
+ env.Install('$BINDIR', env.Glob('$SRCDIR/gui/*.rc')) + [env.GuiResource(f) for f in env.Glob('src/gui/*.rc')]
+ artifacts['icons'] + artifacts['icons']
) )
# call subdir SConscript(s) for independent components # call subdir SConscript(s) for independent components
SConscript(dirs=[SRCDIR+'/tool'], exports='env artifacts core') SConscript(dirs=['src/tool'], exports='env artifacts core')
SConscript(dirs=[TESTDIR], exports='env envPlu artifacts core') SConscript(dirs=['tests'], exports='env artifacts core')
@ -382,31 +384,33 @@ def definePostBuildTargets(env, artifacts):
""" define further actions after the core build (e.g. Documentaion). """ define further actions after the core build (e.g. Documentaion).
define alias targets to trigger the installing. define alias targets to trigger the installing.
""" """
ib = env.Alias('install-bin', '$DESTDIR/bin') build = env.Alias('build', ( artifacts['lumiera']
il = env.Alias('install-lib', '$DESTDIR/lib') + artifacts['plugins']
env.Alias('install', [ib, il]) + artifacts['tools']
+ artifacts['gui']
build = env.Alias('build', artifacts['lumiera']+artifacts['gui']+artifacts['plugins']+artifacts['tools']) ))
allbu = env.Alias('allbuild', build+artifacts['testsuite'])
env.Default('build')
# additional files to be cleaned when cleaning 'build' # additional files to be cleaned when cleaning 'build'
env.Clean ('build', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log' ]) env.Clean ('build', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log' ])
env.Clean ('build', [ '$SRCDIR/pre.gch' ]) env.Clean ('build', [ 'src/pre.gch' ])
doxydoc = artifacts['doxydoc'] = env.Doxygen('doc/devel/Doxyfile') doxydoc = artifacts['doxydoc'] = env.Doxygen('doc/devel/Doxyfile')
env.Alias ('doc', doxydoc) env.Alias ('doc', doxydoc)
env.Clean ('doc', doxydoc + ['doc/devel/,doxylog','doc/devel/warnings.txt']) env.Clean ('doc', doxydoc + ['doc/devel/,doxylog','doc/devel/warnings.txt'])
env.Alias ('all', build+artifacts['testsuite']+doxydoc)
env.Default('build')
# SCons default target
def defineInstallTargets(env, artifacts): def defineInstallTargets(env, artifacts):
""" define some artifacts to be installed into target locations. """ define additional artifacts to be installed into target locations.
@note: we use customised SCons builders defining install targets
for all executables automatically. see LumieraEnvironment.py
""" """
env.Install(dir = '$DESTDIR/bin', source=artifacts['lumiera']) env.SymLink('$DESTDIR/bin/lumiera',env.path.installExe+'lumiera','../lib/lumiera/lumiera')
env.Install(dir = '$DESTDIR/lib', source=artifacts['corelib']) # env.Install(dir = '$DESTDIR/share/doc/lumiera$VERSION/devel', source=artifacts['doxydoc'])
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']) env.Alias('install', '$DESTDIR')
##################################################################### #####################################################################
@ -416,8 +420,7 @@ def defineInstallTargets(env, artifacts):
### === MAIN === #################################################### ### === MAIN === ####################################################
env = setupBasicEnvironment(localDefinitions)
env = setupBasicEnvironment()
if not (isCleanupOperation(env) or isHelpRequest()): if not (isCleanupOperation(env) or isHelpRequest()):
env = configurePlatform(env) env = configurePlatform(env)
@ -430,10 +433,8 @@ artifacts = {}
# 'gui' : the GTK UI (plugin) # 'gui' : the GTK UI (plugin)
# 'plugins' : plugin shared lib # 'plugins' : plugin shared lib
# 'tools' : small tool applications (e.g mpegtoc) # '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) defineSetupTargets(env, artifacts)
defineBuildTargets(env, artifacts) defineBuildTargets(env, artifacts)
definePostBuildTargets(env, artifacts) definePostBuildTargets(env, artifacts)
defineInstallTargets(env, artifacts) defineInstallTargets(env, artifacts)

View file

@ -217,8 +217,8 @@ def generate(env):
'Doxygen': doxyfile_builder, 'Doxygen': doxyfile_builder,
}) })
env.AppendUnique( env.Replace(
DOXYGEN = 'doxygen', DOXYGEN = 'doxygen'
) )

View file

@ -28,6 +28,7 @@ import fnmatch
import re import re
import tarfile import tarfile
from SCons import Util
from SCons.Action import Action from SCons.Action import Action
@ -98,7 +99,7 @@ def findSrcTrees(location, patterns=SRCPATTERNS):
After having initially expanded the given location with #globRootdirs, each After having initially expanded the given location with #globRootdirs, each
directory is examined depth first, until encountering a directory containing directory is examined depth first, until encountering a directory containing
source files, which then yields a result. Especially, this can be used to traverse 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. to be built into packages, plugins, individual tool executables etc.
@return: the relative path names of all source root dirs found (generator function). @return: the relative path names of all source root dirs found (generator function).
""" """
@ -137,24 +138,31 @@ def filterNodes(nlist, removeName=None):
def getDirname(dir): def getDirname(dir, basePrefix=None):
""" extract directory name without leading path """ """ extract directory name without leading path,
or without the explicitly given basePrefix
"""
dir = os.path.realpath(dir) dir = os.path.realpath(dir)
if not os.path.isdir(dir): if not os.path.isdir(dir):
dir,_ = os.path.split(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 return name
def createPlugins(env, dir): def createPlugins(env, dir, **kw):
""" investigate the given source directory to identify all contained source trees. """ 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: a list of build nodes defining a plugin for each of these source trees.
""" """
return [env.LoadableModule( '#$PLUGDIR/%s' % getDirname(tree) return [env.LumieraPlugin( getDirname(tree)
, srcSubtree(env, tree) , srcSubtree(env, tree)
, SHLIBPREFIX='', SHLIBSUFFIX='.lum' , **kw
) )
for tree in findSrcTrees(dir) for tree in findSrcTrees(dir)
] ]
@ -196,114 +204,39 @@ def checkCommandOption(env, optID, val=None, cmdName=None):
def RegisterIcon_Builder(env):
""" Registers Custom Builders for generating and installing Icons. class Record(dict):
Additionally you need to build the tool (rsvg-convert.c) """ a set of properties with map style access.
used to generate png from the svg source using librsvg. Record is a dictionary, but the elements can be accessed
conveniently as if they where object fields
""" """
def __init__(self, defaults=None, **props):
import render_icon as renderer # load Joel's python script for invoking the rsvg-convert (SVG render) if defaults:
renderer.rsvgPath = env.subst("$BINDIR/rsvg-convert") defaults.update(props)
props = defaults
def invokeRenderer(target, source, env): dict.__init__(self,props)
source = str(source[0])
targetdir = env.subst("$BINDIR")
renderer.main([source,targetdir])
return 0
def createIconTargets(target,source,env): def __getattr__(self,key):
""" parse the SVG to get the target file names """ if key=='__get__' or key=='__set__':
source = str(source[0]) raise AttributeError
targetdir = os.path.basename(str(target[0])) return self.setdefault(key)
targetfiles = renderer.getTargetNames(source) # parse SVG
return (["$BINDIR/%s" % name for name in targetfiles], source)
def IconCopy(env, source): def __setattr__(self,key,val):
"""Copy icon to corresponding icon dir. """ self[key] = val
subdir = getDirname(source)
return env.Install("$BINDIR/%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)
def extract_localPathDefs (localDefs):
def Tarball(env,location,dirs,suffix=''): """ extracts the directory configuration values.
""" Custom Command: create Tarball of some subdirs For sake of simplicity, paths and directories are defined
location: where to create the tar (may optionally include filename.tar.gz) immediately as global variables in the SConstruct. This helper
suffix: (optional) suffix to include in the tar name extracts from the given dict the variables matching some magical
dirs: directories to include in the tar pattern and returns them wrapped into a Record for convenient access
This is a bit of a hack, because we want to be able to include arbitrary directories,
without creating new dependencies on those dirs. Esp. we want to tar the source tree
prior to compiling. Solution is
- use the Command-Builder, but pass all target specifications as custom build vars
- create a pseudo-target located in the parent directory (not built by default)
""" """
targetID = '../extern-tar%s' % suffix def relevantPathDefs (mapping):
versionID = env['VERSION'] for (k,v) in mapping.items():
defaultName = 'lumiera%s_%s' % (suffix, versionID) if (k.startswith('src') or k.startswith('build') or k.startswith('install')) and Util.is_String(v):
nameprefix = 'lumiera-%s/' % (versionID) v = v.strip()
location = env.subst(location) if not v.endswith('/'): v += '/'
dirs = env.subst(dirs) yield (k,v)
return env.Command(targetID,None, createTarball,
location=location, defaultName=defaultName, dirs=dirs, nameprefix=nameprefix) return dict(relevantPathDefs(localDefs))
def createTarball(target,source,env):
""" helper, builds the tar using the python2.3 tarfile lib.
This allows us to prefix all paths, thus moving the tree
into a virtual subdirectory containing the Version number,
as needed by common packaging systems.
"""
name = getTarName( location = env['location']
, defaultName = env['defaultName'])
targetspec = env['dirs']
nameprefix = env['nameprefix'] or ''
print 'Running: tar -czf %s %s ...' % (name,targetspec)
if os.path.isfile(name):
os.remove(name)
tar = tarfile.open(name,'w:gz')
for name in targetspec.split():
tar.add(name,nameprefix+name)
tar.close()
#
# old version using shell command:
#
# cmd = 'tar -czf %s %s' % (name,targetspec)
# print 'running ', cmd, ' ... '
# pipe = os.popen (cmd)
# return pipe.close ()
def getTarName(location, defaultName):
""" create a suitable name for the tarball.
- if location contains a name (*.tar.gz) then use this
- otherwise append the defaultName to the specified dir
"""
spec = os.path.abspath(location)
(head,tail) = os.path.split(spec)
if not os.path.isdir(head):
print 'Target dir "%s" for Tar doesn\'t exist.' % head
Exit(1)
mat = re.match(r'([\w\.\-\+:\~]+)\.((tar)|(tar\.gz)|(tgz))', tail)
if mat:
name = mat.group(1)
ext = '.'+mat.group(2)
else:
ext = '.tar.gz'
if os.path.isdir(spec):
head = spec
name = defaultName
else:
name = tail
return os.path.join(head,name+ext)

View file

@ -22,6 +22,9 @@
##################################################################### #####################################################################
import os
from os import path
import SCons import SCons
import SCons.SConf import SCons.SConf
from SCons.Environment import Environment from SCons.Environment import Environment
@ -35,9 +38,16 @@ class LumieraEnvironment(Environment):
This allows us to carry structured config data without This allows us to carry structured config data without
using global vars. Idea inspired by Ardour. using global vars. Idea inspired by Ardour.
""" """
def __init__(self,*args,**kw): def __init__(self, pathConfig, **kw):
Environment.__init__ (self,*args,**kw) Environment.__init__ (self,**kw)
self.path = Record (pathConfig)
self.libInfo = {} self.libInfo = {}
self.Tool("BuilderGCH")
self.Tool("BuilderDoxygen")
self.Tool("ToolDistCC")
self.Tool("ToolCCache")
register_LumieraResourceBuilder(self)
register_LumieraCustomBuilders(self)
def Configure (self, *args, **kw): def Configure (self, *args, **kw):
kw['env'] = self kw['env'] = self
@ -73,7 +83,7 @@ class LumieraEnvironment(Environment):
print "Problems configuring the Library %s (>= %s)" % (libID,minVersion) print "Problems configuring the Library %s (>= %s)" % (libID,minVersion)
return False return False
self.libInfo[libID] = libInfo = LumieraEnvironment() self.libInfo[libID] = libInfo = Environment()
libInfo["ENV"]["PKG_CONFIG_PATH"] = os.environ.get("PKG_CONFIG_PATH") libInfo["ENV"]["PKG_CONFIG_PATH"] = os.environ.get("PKG_CONFIG_PATH")
libInfo.ParseConfig ('pkg-config --cflags --libs '+ libID ) libInfo.ParseConfig ('pkg-config --cflags --libs '+ libID )
if alias: if alias:
@ -102,3 +112,230 @@ class LumieraConfigContext(ConfigBase):
return self.env.addLibInfo (libID, minVersion, alias) return self.env.addLibInfo (libID, minVersion, alias)
###############################################################################
####### Lumiera custom tools and builders #####################################
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.
"""
import render_icon as renderer # load Joel's python script for invoking the rsvg-convert (SVG render)
renderer.rsvgPath = env.subst("$TARGDIR/rsvg-convert")
def invokeRenderer(target, source, env):
source = str(source[0])
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 = env.path.buildIcon
targetfiles = renderer.getTargetNames(source) # parse SVG
return ([targetdir+name for name in targetfiles], 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")
, single_source = True
, emitter = createIconTargets
)
env.Append(BUILDERS = {'IconRender' : buildIcon})
env.AddMethod(IconResource)
env.AddMethod(GuiResource)
env.AddMethod(ConfigData)
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
wrapped object by Python magic. But some calls are intecepted in order to inject
suitalbe default configuration based on the project setup.
"""
def __init__(self, originalBuilder):
SCons.Util.Proxy.__init__ (self, originalBuilder)
def __call__(self, env, target=None, source=None, **kw):
""" when the builder gets invoked from the SConscript...
create a clone environment for specific configuration
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
"""
customisedEnv = self.getCustomEnvironment(env, target=target, **kw) # defined in subclasses
buildTarget = self.buildLocation(customisedEnv, target)
buildTarget = self.invokeOriginalBuilder(customisedEnv, buildTarget, source, **kw)
self.installTarget(customisedEnv, buildTarget, **kw)
return buildTarget
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 []
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()
custEnv.Append( LINKFLAGS = "-Wl,-rpath=\\$$ORIGIN/modules,--enable-new-dtags" )
return custEnv
def getBuildDestination(self, lumiEnv): return lumiEnv.path.buildExe
def getInstallDestination(self, lumiEnv): return lumiEnv.path.installExe
class LumieraModuleBuilder(WrappedStandardExeBuilder):
def getCustomEnvironment(self, lumiEnv, target, **kw):
""" augments the built-in SharedLibrary() builder to add some tweaks missing in SCons 1.0,
like setting a SONAME proper instead of just passing the relative pathname to the linker
"""
custEnv = lumiEnv.Clone()
custEnv.Append(LINKFLAGS = "-Wl,-soname="+self.defineSoname(target,**kw))
return custEnv
def getBuildDestination(self, lumiEnv): return lumiEnv.path.buildLib
def getInstallDestination(self, lumiEnv): return lumiEnv.path.installLib
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:
soname = self.subst(kw['soname']) # explicitely defined by user
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
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
def register_LumieraCustomBuilders (lumiEnv):
""" install the customised builder versions tightly integrated with our buildsystem.
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
"""
programBuilder = LumieraExeBuilder (lumiEnv['BUILDERS']['Program'])
libraryBuilder = LumieraModuleBuilder (lumiEnv['BUILDERS']['SharedLibrary'])
smoduleBuilder = LumieraModuleBuilder (lumiEnv['BUILDERS']['LoadableModule'])
lpluginBuilder = LumieraPluginBuilder (lumiEnv['BUILDERS']['LoadableModule'])
lumiEnv['BUILDERS']['Program'] = programBuilder
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,6 +12,7 @@
# #
LOGFILE=,valgrind.log LOGFILE=,valgrind.log
SUPPRESS=vgsuppression SUPPRESS=vgsuppression
MODULEDIR=modules
VALGRINDFLAGS=${VALGRINDFLAGS:---leak-check=yes --show-reachable=yes --demangle=yes} VALGRINDFLAGS=${VALGRINDFLAGS:---leak-check=yes --show-reachable=yes --demangle=yes}
EXECUTABLE=$1 EXECUTABLE=$1
@ -24,6 +25,9 @@ fi
PATHPREFIX=${EXECUTABLE%/*} PATHPREFIX=${EXECUTABLE%/*}
SUPPRESS="$PATHPREFIX/$SUPPRESS" SUPPRESS="$PATHPREFIX/$SUPPRESS"
# need to set a library search path, because valgrind doesn't handle DT_RUNPATH and $ORIGIN properly
export LD_LIBRARY_PATH=$PATHPREFIX/$MODULEDIR:$LD_LIBRARY_PATH
if [[ -x $SUPPRESS ]]; then if [[ -x $SUPPRESS ]]; then
if [[ $SUPPRESS -nt $SUPPRESS.supp ]]; then if [[ $SUPPRESS -nt $SUPPRESS.supp ]]; then
echo 'generating valgrind supression file...' echo 'generating valgrind supression file...'
@ -37,6 +41,7 @@ else
echo 'no suppression.' echo 'no suppression.'
fi fi
echo "running......$@" echo "running......$@"
valgrind $VALGRINDFLAGS --log-file=$LOGFILE.%p $SUPPRESSIONFLAG $@ & valgrind $VALGRINDFLAGS --log-file=$LOGFILE.%p $SUPPRESSIONFLAG $@ &

View file

@ -1 +0,0 @@
../.libs

View file

@ -1 +0,0 @@
Lumiera executable(s) and libraries will be built here

1
data/DIR_INFO Normal file
View file

@ -0,0 +1 @@
Additional configuration, icons, graphics etc. to be installed with Lumiera

1
data/config/DIR_INFO Normal file
View file

@ -0,0 +1 @@
Lumiera configuration files

View file

@ -0,0 +1,4 @@
# This is an dummy Lumiera config file
#
# Actually Lumiera can't yet load any extended config, as of 1/2011
#

20
data/config/setup.ini Normal file
View file

@ -0,0 +1,20 @@
###########################################################
# ### Lumiera installation and platform configuration ###
#
# (file located relative to the Lumiera executable)
#
[BuildsystemDemo]
# This is dummy/demonstration executable
# built from the "scons" git tree. It serves to
# document and evolve the SCons buildsystem in isolation
# and for tests of the packaging and build process.
#
gui = gtk_gui.lum
modulepath = $ORIGIN/modules
[Lumiera]
# Lumiera video editor main application
#
# Nothing configurable as of 1/2011
#

268
src/common/bootstrap.cpp Normal file
View file

@ -0,0 +1,268 @@
/*
dummy-func.cpp - placeholder with dummy functions to demonstrate building/loading shared modules
* *************************************************************************************************/
#include "common/bootstrap.hpp"
extern "C" {
#include <unistd.h>
}
#include <dlfcn.h>
#include <nobug.h>
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
#include <boost/utility.hpp>
#include <boost/regex.hpp>
#include <iostream>
#include <fstream>
#include <string>
namespace lumiera {
using std::string;
using std::ifstream;
using boost::regex;
using boost::smatch;
using boost::regex_search;
using boost::sregex_iterator;
typedef smatch::value_type const& SubMatch;
namespace fsys = boost::filesystem;
namespace opt = boost::program_options;
namespace { // Implementation helpers
const size_t STRING_MAX_RELEVANT = 1000;
const char * const BOOTSTRAP_INI = "$ORIGIN/config/setup.ini";
const char * const GET_PATH_TO_EXECUTABLE = "/proc/self/exe";
regex EXTRACT_PATHSPEC ("(\\$?ORIGIN/)?([^:]+)");
/** the real application would throw a custom exception... */
void
dieHard (string msg)
{
NOBUG_ERROR (NOBUG_ON, "Fatal Error: %s ", msg.c_str());
abort();
}
/** figure out the absolute path
* of the currently running executable
*/
string
catchMyself ()
{
static string buff(STRING_MAX_RELEVANT+1, '\0' );
if (!buff[0])
{
ssize_t chars_read = readlink (GET_PATH_TO_EXECUTABLE, &buff[0], STRING_MAX_RELEVANT);
if (0 > chars_read || chars_read == ssize_t(STRING_MAX_RELEVANT))
dieHard ("unable to discover path of running executable");
buff.resize(chars_read);
}
return buff;
}
/**
* Helper: Access a path Specification as a sequence of filesystem Paths.
* This iterator class dissects a ':'-separated path list. The individual
* components may use the symbol \c $ORIGIN to denote the directory holding
* the current executable. After resolving this symbol, a valid absolute or
* relative filesystem path should result, which must not denote an existing
* file (directory is OK).
* @note #fetch picks the current component and advances the iteration.
*/
class SearchPathSplitter
: boost::noncopyable
{
sregex_iterator pos_,
end_;
public:
SearchPathSplitter (string const& searchPath)
: pos_(searchPath.begin(),searchPath.end(), EXTRACT_PATHSPEC)
, end_()
{ }
bool
isValid() const
{
return pos_ != end_;
}
string
fetch ()
{
if (!isValid())
dieHard ("Search path exhausted.");
string currentPathElement = resolveRelative();
++pos_;
return currentPathElement;
}
private:
/** maybe resolve a path spec given relative to
* the current Executable location ($ORIGIN) */
string
resolveRelative ()
{
if (containsORIGINToken())
return asAbsolutePath();
else
return getFullPath();
}
SubMatch found(int group=0) { return (*pos_)[group]; }
bool containsORIGINToken() { return found(1).matched; }
string getRelativePath() { return found(2); }
string getFullPath() { return found(); }
string
asAbsolutePath()
{
fsys::path exePathName (catchMyself());
fsys::path modPathName (exePathName.remove_leaf() / getRelativePath());
if (fsys::exists(modPathName) && !fsys::is_directory (modPathName))
dieHard ("Error in search path: component \""+modPathName.string()+"\" is not a directory");
return modPathName.directory_string();
}
};
/** helper to establish the location to search for loadable modules.
* This is a simple demonstration of the basic technique used in the
* real application source to establish a plugin search path, based
* on the actual executable position plus compiled in and configured
* relative and absolute path specifications.
*/
string
resolveModulePath (string moduleName, string searchPath = "")
{
fsys::path modulePathName (moduleName);
SearchPathSplitter searchLocation(searchPath);
while (true)
{
if (fsys::exists (modulePathName))
{
INFO (config, "found module %s", modulePathName.string().c_str());
return modulePathName.string();
}
// try / continue search path
if (searchLocation.isValid())
modulePathName = fsys::path() / searchLocation.fetch() / moduleName;
else
dieHard ("Module \""+moduleName+"\" not found"
+ (searchPath.empty()? ".":" in search path: "+searchPath));
} }
/**
* Encapsulate an INI-style configuration file.
* The acceptable settings are defined in the ctor.
* Implementation based on boost::program_options
*/
class Config
: boost::noncopyable
{
opt::options_description syntax;
opt::variables_map settings;
public:
Config (string bootstrapIni)
: syntax("Lumiera installation and platform configuration")
, settings()
{
syntax.add_options()
("BuildsystemDemo.gui", opt::value<string>(),
"name of the Lumiera GUI plugin to load")
("BuildsystemDemo.modulepath", opt::value<string>(),
"search path for loadable modules. "
"May us $ORIGIN to refer to the EXE location")
;
ifstream configIn (resolve(bootstrapIni).c_str());
opt::parsed_options parsed =
opt::parse_config_file (configIn, syntax);
opt::store (parsed, settings);
opt::notify(settings);
}
string
operator[] (const string key) const
{
return settings[key].as<string>();
}
private:
string
resolve (fsys::path iniSpec)
{
string file = iniSpec.leaf();
string searchpath = iniSpec.branch_path().string();
return resolveModulePath (file, searchpath);
}
};
}//(End) implementation helpers
void
loadDummyGui()
{
Config appConfig(BOOTSTRAP_INI);
string guiModule = appConfig["BuildsystemDemo.gui"];
string moduleSearch = appConfig["BuildsystemDemo.modulepath"];
string moduleLocation = resolveModulePath (guiModule, moduleSearch);
void* handle = dlopen (moduleLocation.c_str(), RTLD_LAZY|RTLD_LOCAL);
if (handle)
{
typedef void (*VoidFunc)(void);
VoidFunc entryPoint = (VoidFunc) dlsym (handle, "start_dummy_gui");
if (!entryPoint)
dieHard ("unable to resolve the entry point symbol after loading the GUI module.");
else
(*entryPoint) (); // activate loaded module
}
else
dieHard ("unable to load "+moduleLocation);
}
} // namespace lumiera

39
src/common/bootstrap.hpp Normal file
View file

@ -0,0 +1,39 @@
/*
dummy-func.hpp - placeholder with dummy functions to demonstrate building shared modules
* ******************************************************************************************/
#ifndef COMMON_DUMMY_FUNC_H
#define COMMON_DUMMY_FUNC_H
#include "include/nobugcfg.h"
#include <string>
namespace lumiera {
using std::string;
/** this is a function located in the liblumieracore.so,
* which attempts to load the "pseudo-gui" as shared module
* and invoke the gui-main. The sole purpose of this function
* is to demonstrate that the SCons build system is working.
*
* \par requirements
* While this isn't the actual implementation used in Lumiera,
* we try to mimic or demonstrate the techniques used to resolve
* the actual module to be loaded. So there are some requirements
* - \c $ORIGIN/config/setup.ini exists and defines...
* - a section [BuildsystemDemo], which holds
* - a setting gui = gtk_gui.lum
* - a module search path, typically: modulepath = $ORIGIN/modules
* Here the token \c $ORIGIN is automatically resolved to the directory
* holding the current executable, by reading the symlink \c /proc/self/exe
*/
void loadDummyGui();
} // namespace lumiera
#endif

View file

@ -96,7 +96,7 @@ GtkLumiera::get_app_title()
const Glib::ustring const Glib::ustring
GtkLumiera::get_app_version() GtkLumiera::get_app_version()
{ {
return "0.1-dev"; return "0.pre.01";
} }
const Glib::ustring GtkLumiera::get_app_copyright() const Glib::ustring GtkLumiera::get_app_copyright()

View file

@ -12,12 +12,12 @@ envSvg.mergeConf(['librsvg-2.0'])
envSvg.Append(LIBS=support_lib) envSvg.Append(LIBS=support_lib)
luidgen = env.Program('#$BINDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs luidgen = env.Program('luidgen', 'luidgen.c', LIBS=support_lib, install=True) ## for generating Lumiera-UIDs
rsvg = envSvg.Program('#$BINDIR/rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) rsvg = envSvg.Program('rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg)
# build additional test and administrative tools.... # build additional test and administrative tools....
artifacts['tools'] = [ env.Program('#$BINDIR/hello-world','hello.c') #### hello world (checks C build) artifacts['tools'] = [ env.Program('hello-world','hello.c', install=True) #### hello world (checks C build)
+ env.Program('#$BINDIR/try', 'try.cpp') #### to try out some feature... + env.Program('try', 'try.cpp', LIBS=support_lib) #### to try out some feature...
+ luidgen + luidgen
+ rsvg + rsvg
] ]

View file

@ -18,70 +18,57 @@
// 4/10 - pretty printing STL containers with python enabled GDB? // 4/10 - pretty printing STL containers with python enabled GDB?
// 1/11 - exploring numeric limits // 1/11 - exploring numeric limits
// 1/11 - integer floor and wrap operation(s) // 1/11 - integer floor and wrap operation(s)
// 1/11 - how to fetch the path of the own executable -- at least under Linux?
//#include <nobug.h> #include <nobug.h>
#include <iostream> #include <iostream>
//#include <typeinfo>
#include <string> #include <string>
//#include <cstdlib>
#include <limits>
#include <cmath>
#include <boost/format.hpp> extern "C" {
#include <unistd.h>
}
//#include "lib/error.hpp"
//#include "lib/symbol.hpp"
using boost::format;
//using std::rand;
using std::string; using std::string;
using std::cout; using std::cout;
using std::endl; using std::endl;
//using lib::Literal;
//using lib::STRING_MAX_RELEVANT;
const size_t STRING_MAX_RELEVANT = 1000;
div_t //namespace error = lumiera::error;
floorwrap (int num, int den)
//Literal GET_PATH_TO_EXECUTABLE ("/proc/self/exe");
const char * const GET_PATH_TO_EXECUTABLE ("/proc/self/exe");
string
catchMyself ()
{ {
div_t res = div (num,den); string buff(STRING_MAX_RELEVANT+1, '\0' );
if (0 > (num^den) && res.rem) ssize_t chars_read = readlink (GET_PATH_TO_EXECUTABLE, &buff[0], STRING_MAX_RELEVANT);
{ // wrap similar to floor()
--res.quot; if (0 > chars_read || chars_read == ssize_t(STRING_MAX_RELEVANT))
res.rem = den - (-res.rem); // throw error::Fatal ("unable to discover path of running executable")
} throw string("unable to discover path of running executable");
return res;
buff.resize(chars_read);
return buff;
} }
void
checkDiv(int lhs, int rhs)
{
div_t wrap = floorwrap(lhs,rhs);
cout << format ("%2d / %2d = %2d %% = % d \tfloor=%6.2f wrap = (%2d, %2d) \n")
% lhs % rhs % (lhs/rhs) % (lhs%rhs) % floor(double(lhs)/rhs) % wrap.quot % wrap.rem;
}
int int
main (int, char**) main (int, char**) //(int argc, char* argv[])
{ {
// NOBUG_INIT; NOBUG_INIT;
checkDiv (8,4); cout << "\n\nwho am I? :" << catchMyself();
checkDiv (9,4); cout << "\n.gulp.\n";
checkDiv (-8,4);
checkDiv (-9,4);
checkDiv (8,-4);
checkDiv (9,-4);
checkDiv (-8,-4);
checkDiv (-9,-4);
checkDiv (0,4);
checkDiv (0,-4);
checkDiv (1,4);
checkDiv (1,-4);
checkDiv (-1,4);
checkDiv (-1,-4);
cout << "\n.gulp.\n";
return 0; return 0;
} }

1
target/DIR_INFO Normal file
View file

@ -0,0 +1 @@
Lumiera program package tree, holding executable(s) and libraries to be built

1
target/modules/DIR_INFO Normal file
View file

@ -0,0 +1 @@
Lumiera subsystems and other dynamically loadable application components

View file

@ -12,19 +12,17 @@ from Buildhelper import scanSubtree
from Buildhelper import globRootdirs from Buildhelper import globRootdirs
from Buildhelper import createPlugins 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 ? # temp fix to add test.h -- wouldn't it be better to put this header be into src/lib ?
env = env.Clone() env = env.Clone()
env.Append(CPPPATH='#/.') # add Rootdir to Includepath, so test/test.h is found env.Append(CPPPATH='#/.') # add Rootdir to Includepath, so test/test.h is found
envPlu = envPlu.Clone()
envPlu.Append(CPPPATH='#/.')
# temp fix------------- # temp fix-------------
def testExecutable(env,tree, exeName=None, obj=None): def testExecutable(env,tree, exeName=None, obj=None):
""" declare all targets needed to create a standalone """ declare all targets needed to create a standalone
Test executable of the given Sub-tree. Note that Test executable of the given Sub-tree.
each subdir is built in its own Environment. @note this tree uses separate Environment/Includepath
""" """
env = env.Clone() env = env.Clone()
env.Append(CPPPATH=tree) # add Subdir to Includepath env.Append(CPPPATH=tree) # add Subdir to Includepath
@ -35,7 +33,7 @@ def testExecutable(env,tree, exeName=None, obj=None):
obj = srcSubtree(env,tree, isShared=False) # use all sourcefiles found in subtree obj = srcSubtree(env,tree, isShared=False) # use all sourcefiles found in subtree
if not exeName: if not exeName:
exeName = 'test-%s' % tree exeName = 'test-%s' % tree
return env.Program('#$BINDIR/'+exeName, obj + core) return env.Program(exeName, obj + core)
def testCollection(env,dir): def testCollection(env,dir):
@ -44,7 +42,7 @@ def testCollection(env,dir):
""" """
srcpatt = ['test-*.c'] srcpatt = ['test-*.c']
exeName = lambda p: path.basename(path.splitext(p)[0]) exeName = lambda p: path.basename(path.splitext(p)[0])
buildIt = lambda p: env.Program("#$BINDIR/"+exeName(p), [p] + core) buildIt = lambda p: env.Program(exeName(p), [p] + core)
return [buildIt(f) for f in scanSubtree(dir,srcpatt)] return [buildIt(f) for f in scanSubtree(dir,srcpatt)]
@ -59,7 +57,7 @@ moduledirs = globRootdirs('*')
artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['lib','components'] ] artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['lib','components'] ]
+ [ testCollection(env, dir) for dir in moduledirs if not dir in specials] + [ 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 + env.File(glob('*.tests')) # depending on the test definition files for test.sh
) )
@ -67,7 +65,7 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['lib','co
# for creating a Valgrind-Suppression file # for creating a Valgrind-Suppression file
vgsuppr = env.Program('#$BINDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms vgsuppr = env.Program('vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms
artifacts['tools'] += [vgsuppr] artifacts['tools'] += [vgsuppr]
Depends(ts,vgsuppr) Depends(ts,vgsuppr)
@ -103,10 +101,10 @@ if testsuites:
testEnv['ENV']['TEST_CONF'] = env.File("test.conf").abspath testEnv['ENV']['TEST_CONF'] = env.File("test.conf").abspath
testDir = env.Dir('#$BINDIR') testDir = env.Dir('#$TARGDIR')
runTest = env.File("test.sh").abspath runTest = env.File("test.sh").abspath
runTs = testEnv.Command('#$BINDIR/,testlog', ts, runTest, chdir=testDir) runTs = testEnv.Command('#$TARGDIR/,testlog', ts, runTest, chdir=testDir)