diff --git a/.gitignore b/.gitignore index c5b3efe27..e2f73fc4d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ optcache Makefile.in build/* -bin/* +target/* autom4te.cache/* scripts/* configure @@ -18,7 +18,7 @@ config.log aclocal.m4 autom4te.cache semantic.cache -tests/,* wiki/backups/* +doc/devel/draw/*.png doc/devel/uml/fig128309.png m4/* diff --git a/AUTHORS b/AUTHORS index e950124df..8f909c0eb 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,58 +1,134 @@ +Lumiera Authors and Credits +=========================== +Version: 0.pre.0.1 +Date: 2/2011 -Cinelerra(2) Authors -==================== -hv=Jack Crossfire -j6t=Johannes Sixt -minmax=Andraz Tori -herman=Herman Robak -baver=Richard Baverstock -pere=Petter Reinholdtsen -tfheen=Tollef Fog Heen -andreask=Andreas Kielb -theraz=Tyler Geddes -dyce=Gergely Erdelyi -dreamlx=David Arendt -ga=Gustavo Iniguez -memenk=Michael Eric Menk -benjif=Benjamin Flaming -cobra=Kevin Brosius -taraba=Mark Taraba -nate=Nathan Kurz -mammique=Camille Harang -kbielefe=Karl Bielefeldt -alexf=Alex Ferrer -pmdumuid=Pierre Dumuid -giskard=Riccardo Setti -jstewart=Joe Stewart -doudou=Sylvain Joyeux -rafael2k=Rafael Diniz -nicolasm=Nicolas Maufrais +'`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Architecture and Design, +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +graphical user interface, JOEL HOLDSWORTH + , CLAY BARNES +processing layer , HERMANN VOSSELER +backend , CHRISTIAN THÄTER +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Involved in Lumiera development -=============================== -cehteh=Christian Thaeter -ichthyo=Hermann Vosseler -plouj=Michael Ploujnikov +'`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Programming, +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +rendering engine, HERMANN VOSSELER +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 +--------------- 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. - See: http://loki-lib.sourceforge.net - and the book: - Alexandrescu, Andrei. - "Modern C++ Design: Generic Programming and Design - Patterns Applied". Copyright (c) 2001. Addison-Wesley. - ISBN 0201704315 - - Loki Copyright Notice: - Permission to use, copy, modify, distribute and sell this software for any + + +.The Loki Library +[quote] +__________________________________________________________________________ +Copyright (c) 2001 by *Andrei Alexandrescu* + + +.Loki Copyright Notice +* 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 purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The author makes no representations about the suitability of this software 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 +_____________________________________________________________________________ + + diff --git a/INSTALL b/INSTALL index ee8aebf2f..bba2bf476 100644 --- a/INSTALL +++ b/INSTALL @@ -1,50 +1,82 @@ Running / Installing Lumiera Prototype ====================================== +Date: 2/2011 -From: -http://www.pipapo.org/pipawiki/Lumiera/NewbiesTutorials +Lumiera uses a fairly standard build system. There are no special quirks. +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 -developers of Lumiera. +For building Lumiera, besides the GNU C/C++ compiler (Version 4.X), you'll need: -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 - * libtool - * git - * libgavl - * nobug(see below) +.Notes for Ubuntu: -For Ubuntu Hardy also: +On Hardy you need also: - * libglade2-dev - * libgdl-1-dev - * libgtkmm-2.4-dev - * libxv-dev + * libglade2-dev + * libgtkmm-2.4-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 -will use as well as lumieras branches you want to try. Example ~/temp. cd to -that directory and run: +Lumiera specific libraries +~~~~~~~~~~~~~~~~~~~~~~~~~~ +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 +------------------------------------------------------------ +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 autoreconf -i mkdir build @@ -52,11 +84,78 @@ cd build ../configure make 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 cd LUMIERA autoreconf -fi @@ -64,40 +163,75 @@ mkdir build cd build ../configure 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 +------------ -Nothing is easier, follow the basic instructions at http://www.kernel.org/pub/ -software/scm/git/docs/gittutorial.html, notably the - +Nothing is easier, follow the http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html[the basic instructions], +notably the following parts: +------------------------------------------------------------ $ git config --global user.name "Your Name Comes Here" $ 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 -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 -anything - - * by running 'make check'. - -Finally you can push your changes to the lumiera server to the 'mob' -repository: - -$ 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. +------------------------------------------------------------ + + +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. + +Check that you didn't break anything, by running the testsuite (see above) + +Finally you can push your changes to the lumiera server to the 'mob' repository: + +------------------------------------------------------------ +$ 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. diff --git a/README b/README index e759bf22c..3d62663eb 100644 --- a/README +++ b/README @@ -1,45 +1,73 @@ -==================================== Lumiera -- the video NLE for Linux ==================================== - Lumiera is a nonlinear video editing and compositing tool. - It understands some of the common multimedia formats - (quicktime, avi, ogg) and audio/video compression - codecs (divx, xvid, mpeg1/2/4, ...). +************************************************************* +Lumiera is a nonlinear video editing and compositing tool. +It understands some of the common multimedia formats +(quicktime, avi, ogg) and audio/video compression +codecs (divx, xvid, mpeg1/2/4, ...) - It features non-destructive editing, compositing tools, - a selection of effects plugins, processing in RGB, YUV - and RGB-float colormodels and the ability to mix media - with differing sizes and framerates. +It features non-destructive editing, compositing tools, +a selection of effects plugins, processing in RGB, YUV +and RGB-float colormodels and the ability to mix media +with differing sizes and framerates. -For more information about Lumiera visit http://lumiera.org/ -For more information about Cinelerra visit http://cinelerra.org/ +More Informations at http://lumiera.org/[Lumiera.org] +**************************************************************** +Lumiera pre-Alpha Versions +-------------------------- ----------------------------- -"Lumiera" prototype code ----------------------------- +**This source tree doesn't yet contain a working video editing application** + +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** -Rather, it contains the initial framework and core modules of the lower and -middle layer of the envisioned new Application "Lumiera". - -As of 7/2007, we start here with some backend and render engine modules +As of _7/2007_:: +we start here with the backend and render engine modules together with some unit tests. You should find a wiki with detailed design considerations and developer documentation and a UML model (usable with BOUML 2.29) in the sibling directories. -As of 2/2008 the project has been separated completely from its -ancestor "Cinelerra". The Community, which is largely identical to the -Cinelerra-CV community, chose the new project name "Lumiera". The -basic project infrastructure is up and running, and work on the new -codebase is going on continuously. We can show nothing but a running -test suite for now. +As of _2/2008_:: +the project has been separated completely from his ancestor ``Cinelerra'' +The Community, which is largely identical to the Cinelerra-CV community, choose the +new project name ``Lumiera''. The basic project infrastructure is up and running, +and work on the new codebase is going on continuosely. We can show nothing but +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 +------------------ ----------------------------- -Installation ----------------------------- +For building Lumiera, you'll need: + + - 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 diff --git a/SConstruct b/SConstruct index eaf03c54e..aa382f2c8 100644 --- a/SConstruct +++ b/SConstruct @@ -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. # Read more about the SCons build system at: http://www.scons.org # Basically, this script just /defines/ the components and how they # fit together. SCons will derive the necessary build steps. +#-----------------------------------Configuration +TARGDIR = 'target' +VERSION = '0.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 sys @@ -55,10 +69,10 @@ from LumieraEnvironment import * ##################################################################### -def setupBasicEnvironment(): +def setupBasicEnvironment(localDefinitions): """ define cmdline options, build type decisions """ - EnsurePythonVersion(2,3) + EnsurePythonVersion(2,4) EnsureSConsVersion(1,0) Decider('MD5-timestamp') # detect changed files by timestamp, then do a MD5 @@ -66,26 +80,20 @@ def setupBasicEnvironment(): vars = defineCmdlineVariables() env = LumieraEnvironment(variables=vars ,toolpath = [TOOLDIR] - ,tools = ["default", "BuilderGCH", "BuilderDoxygen"] - ) - env.Tool("ToolDistCC") - env.Tool("ToolCCache") + ,pathConfig = extract_localPathDefs(localDefinitions) # e.g. buildExe -> env.path.buildExe + ,TARGDIR = TARGDIR + ,DESTDIR = '$INSTALLDIR/$PREFIX' + ,VERSION = VERSION + ) handleVerboseMessages(env) env.Append ( CCCOM=' -std=gnu99') env.Append ( SHCCCOM=' -std=gnu99') # workaround for a bug: CCCOM currently doesn't honour CFLAGS, only CCFLAGS - env.Replace( VERSION=VERSION - , SRCDIR=SRCDIR - , BINDIR=BINDIR - , LIBDIR=LIBDIR - , PLUGDIR=PLUGDIR - , ICONDIR=ICONDIR - , CPPPATH=["#"+SRCDIR] # used to find includes, "#" means always absolute to build-root + env.Replace( CPPPATH =["#src"] # 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 -Wextra ' , CFLAGS='-std=gnu99' ) - RegisterIcon_Builder(env) handleNoBugSwitches(env) env.Append(CPPDEFINES = '_GNU_SOURCE') @@ -96,13 +104,13 @@ def setupBasicEnvironment(): appendVal(env,'DEBUG', 'CCFLAGS', val=' -ggdb') # setup search path for Lumiera plugins - appendCppDefine(env,'PKGLIBDIR','LUMIERA_PLUGIN_PATH=\\"$PKGLIBDIR/:./.libs\\"' - ,'LUMIERA_PLUGIN_PATH=\\"$DESTDIR/lib/lumiera/:./.libs\\"') + appendCppDefine(env,'PKGLIBDIR','LUMIERA_PLUGIN_PATH=\\"$PKGLIBDIR/:ORIGIN/modules\\"' + ,'LUMIERA_PLUGIN_PATH=\\"ORIGIN/modules\\"') appendCppDefine(env,'PKGDATADIR','LUMIERA_CONFIG_PATH=\\"$PKGLIBDIR/:.\\"' ,'LUMIERA_CONFIG_PATH=\\"$DESTDIR/share/lumiera/:.\\"') prepareOptionsHelp(vars,env) - vars.Save(OPTIONSCACHEFILE, env) + vars.Save(OPTCACHE, env) return env def appendCppDefine(env,var,cppVar, elseVal=''): @@ -148,7 +156,7 @@ def defineCmdlineVariables(): you may define custom variable settings in a separate file. Commandline will override both. """ - vars = Variables([OPTIONSCACHEFILE, CUSTOPTIONSFILE]) + vars = Variables([OPTCACHE, CUSTOPTFILE]) vars.AddVariables( ('ARCHFLAGS', 'Set architecture-specific compilation flags (passed literally to gcc)','') ,('CC', 'Set the C compiler to use.', 'gcc') @@ -164,11 +172,10 @@ def defineCmdlineVariables(): # ,BoolVariable('OPENGL', 'Include support for OpenGL preview rendering', False) # ,EnumVariable('DIST_TARGET', 'Build target architecture', 'auto', # allowed_values=('auto', 'i386', 'i686', 'x86_64' ), ignorecase=2) - ,PathVariable('DESTDIR', 'Installation dir prefix', '/usr/local') - ,PathVariable('PKGLIBDIR', 'Installation dir for plugins, defaults to DESTDIR/lib/lumiera', '',PathVariable.PathAccept) - ,PathVariable('PKGDATADIR', 'Installation dir for default config, usually DESTDIR/share/lumiera', '',PathVariable.PathAccept) - ,PathVariable('SRCTAR', 'Create source tarball prior to compiling', '..', PathVariable.PathAccept) - ,PathVariable('DOCTAR', 'Create tarball with developer documentation', '..', PathVariable.PathAccept) + ,PathVariable('PREFIX', 'Installation dir prefix', 'usr/local', PathVariable.PathAccept) + ,PathVariable('INSTALLDIR', 'Root output directory for install. Final installation will happen in INSTALLDIR/PREFIX/... ', '/', PathVariable.PathIsDir) + ,PathVariable('PKGLIBDIR', 'Installation dir for plugins, defaults to PREFIX/lib/lumiera/modules', '',PathVariable.PathAccept) + ,PathVariable('PKGDATADIR', 'Installation dir for default config, usually PREFIX/share/lumiera', '',PathVariable.PathAccept) ) return vars @@ -187,10 +194,8 @@ Special Targets: testcode: additionally compile the Testsuite check : build and run the Testsuite doc : generate documentation (Doxygen) + all : build and testcode and doc install : install created artifacts at PREFIX - src.tar : create source tarball - doc.tar : create developer doc tarball - tar : create all tarballs Configuration Options: """ @@ -238,15 +243,19 @@ def configurePlatform(env): conf.env.mergeConf('nobugmt') if not conf.CheckCXXHeader('tr1/memory'): - problems.append('We rely on the std::tr1 proposed standard extension for shared_ptr.') + problems.append('We rely on the std::tr1 standard C++ extension for shared_ptr.') if not conf.CheckCXXHeader('boost/config.hpp'): - problems.append('We need the C++ boost-lib.') + problems.append('We need the C++ boost-libraries.') else: - if not conf.CheckCXXHeader('boost/shared_ptr.hpp'): - problems.append('We need boost::shared_ptr (shared_ptr.hpp).') + if not conf.CheckCXXHeader('boost/scoped_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++'): 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++'): 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') if not conf.CheckPkgConfig('gtkmm-2.4', 2.8): - problems.append('Unable to configure GTK--, exiting.') + problems.append('Unable to configure GTK--') if not conf.CheckPkgConfig('glibmm-2.4', '2.16'): - problems.append('Unable to configure Lib glib--, exiting.') + problems.append('Unable to configure Lib glib--') if not conf.CheckPkgConfig('gthread-2.0', '2.12.4'): problems.append('Need gthread support lib for glib-- based thread handling.') if not conf.CheckPkgConfig('cairomm-1.0', 0.6): - problems.append('Unable to configure Cairo--, exiting.') + problems.append('Unable to configure Cairo--') verGDL = '2.27.1' if not conf.CheckPkgConfig('gdl-lum', verGDL, alias='gdl'): @@ -308,19 +317,11 @@ def configurePlatform(env): -def definePackagingTargets(env, artifacts): +def defineSetupTargets(env, artifacts): """ build operations and targets to be done /before/ compiling. things like creating a source tarball or preparing a version header. """ - 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) + pass ## currently none @@ -331,50 +332,51 @@ def defineBuildTargets(env, artifacts): """ # use PCH to speed up building // disabled for now due to strange failures -# env['GCH'] = ( env.PrecompiledHeader('$SRCDIR/pre.hpp') -# + env.PrecompiledHeader('$SRCDIR/pre_a.hpp') +# env['GCH'] = ( env.PrecompiledHeader('src/pre.hpp') +# + env.PrecompiledHeader('src/pre_a.hpp') # ) - lApp = env.SharedLibrary('$LIBDIR/lumieracommon', srcSubtree(env,'$SRCDIR/common')) - lBack = env.SharedLibrary('$LIBDIR/lumierabackend', srcSubtree(env,'$SRCDIR/backend')) - lProc = env.SharedLibrary('$LIBDIR/lumieraproc', srcSubtree(env,'$SRCDIR/proc')) - lLib = env.SharedLibrary('$LIBDIR/lumiera', srcSubtree(env,'$SRCDIR/lib')) + lLib = env.SharedLibrary('lumiera', srcSubtree(env,'src/lib'), install=True) + lApp = env.SharedLibrary('lumieracommon', srcSubtree(env,'src/common'), install=True, LIBS=lLib) + lBack = env.SharedLibrary('lumierabackend', srcSubtree(env,'src/backend'),install=True) + lProc = env.SharedLibrary('lumieraproc', srcSubtree(env,'src/proc'), install=True) core = lLib+lApp+lBack+lProc - artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) - artifacts['corelib'] = lLib+lApp + artifacts['corelib'] = core 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 - envPlu = env.Clone() - envPlu.Append(CPPDEFINES='LUMIERA_PLUGIN') artifacts['plugins'] = [] # currently none # 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'])] + vector_icon_dir = env.path.srcIcon+'svg' + prerendered_icon_dir = env.path.srcIcon+'prerendered' + artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])] + + [env.IconResource(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])] ) # the Lumiera GTK GUI envGtk = env.Clone() 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') - guimodule = envGtk.LoadableModule('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') + objgui = srcSubtree(envGtk,'src/gui') + guimodule = envGtk.LumieraPlugin('gtk_gui', objgui, install=True) artifacts['gui'] = ( guimodule - + env.Install('$BINDIR', env.Glob('$SRCDIR/gui/*.rc')) + + [env.GuiResource(f) for f in env.Glob('src/gui/*.rc')] + artifacts['icons'] ) - + # call subdir SConscript(s) for independent components - SConscript(dirs=[SRCDIR+'/tool'], exports='env artifacts core') - SConscript(dirs=[TESTDIR], exports='env envPlu artifacts core') + SConscript(dirs=['src/tool'], exports='env 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 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['gui']+artifacts['plugins']+artifacts['tools']) - allbu = env.Alias('allbuild', build+artifacts['testsuite']) - env.Default('build') + build = env.Alias('build', ( artifacts['lumiera'] + + artifacts['plugins'] + + artifacts['tools'] + + artifacts['gui'] + )) # additional files to be cleaned when cleaning 'build' env.Clean ('build', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log' ]) - env.Clean ('build', [ '$SRCDIR/pre.gch' ]) + env.Clean ('build', [ 'src/pre.gch' ]) doxydoc = artifacts['doxydoc'] = env.Doxygen('doc/devel/Doxyfile') env.Alias ('doc', doxydoc) 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): - """ 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.Install(dir = '$DESTDIR/lib', source=artifacts['corelib']) - env.Install(dir = '$DESTDIR/lib', source=artifacts['plugins']) - env.Install(dir = '$DESTDIR/bin', source=artifacts['tools']) + env.SymLink('$DESTDIR/bin/lumiera',env.path.installExe+'lumiera','../lib/lumiera/lumiera') +# env.Install(dir = '$DESTDIR/share/doc/lumiera$VERSION/devel', source=artifacts['doxydoc']) - 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 === #################################################### - -env = setupBasicEnvironment() +env = setupBasicEnvironment(localDefinitions) if not (isCleanupOperation(env) or isHelpRequest()): env = configurePlatform(env) @@ -430,10 +433,8 @@ artifacts = {} # 'gui' : the GTK UI (plugin) # '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) +defineSetupTargets(env, artifacts) defineBuildTargets(env, artifacts) definePostBuildTargets(env, artifacts) defineInstallTargets(env, artifacts) diff --git a/admin/scons/BuilderDoxygen.py b/admin/scons/BuilderDoxygen.py index a397ef32e..7c9514f2c 100644 --- a/admin/scons/BuilderDoxygen.py +++ b/admin/scons/BuilderDoxygen.py @@ -217,8 +217,8 @@ def generate(env): 'Doxygen': doxyfile_builder, }) - env.AppendUnique( - DOXYGEN = 'doxygen', + env.Replace( + DOXYGEN = 'doxygen' ) diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index f8e349a5e..aed9c07da 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -28,6 +28,7 @@ import fnmatch import re import tarfile +from SCons import Util from SCons.Action import Action @@ -98,7 +99,7 @@ def findSrcTrees(location, patterns=SRCPATTERNS): After having initially expanded the given location with #globRootdirs, each directory is examined depth first, until encountering a directory containing source files, which then yields a result. Especially, this can be used to traverse - an organisational directory structure and find out all possible source trees of + an organisational directory structure and find out all possible source trees to be built into packages, plugins, individual tool executables etc. @return: the relative path names of all source root dirs found (generator function). """ @@ -137,24 +138,31 @@ def filterNodes(nlist, removeName=None): -def getDirname(dir): - """ extract directory name without leading path """ +def getDirname(dir, basePrefix=None): + """ extract directory name without leading path, + or without the explicitly given basePrefix + """ dir = os.path.realpath(dir) if not os.path.isdir(dir): dir,_ = os.path.split(dir) - _, name = os.path.split(dir) + if basePrefix: + basePrefix = os.path.realpath(basePrefix) + if str(dir).startswith(basePrefix): + name = str(dir)[len(basePrefix):] + else: + _, name = os.path.split(dir) return name -def createPlugins(env, dir): +def createPlugins(env, dir, **kw): """ 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 [env.LoadableModule( '#$PLUGDIR/%s' % getDirname(tree) - , srcSubtree(env, tree) - , SHLIBPREFIX='', SHLIBSUFFIX='.lum' - ) + return [env.LumieraPlugin( getDirname(tree) + , srcSubtree(env, tree) + , **kw + ) 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. - Additionally you need to build the tool (rsvg-convert.c) - used to generate png from the svg source using librsvg. + +class Record(dict): + """ a set of properties with map style access. + Record is a dictionary, but the elements can be accessed + conveniently as if they where object fields """ - - import render_icon as renderer # load Joel's python script for invoking the rsvg-convert (SVG render) - renderer.rsvgPath = env.subst("$BINDIR/rsvg-convert") - - def invokeRenderer(target, source, env): - source = str(source[0]) - targetdir = env.subst("$BINDIR") - renderer.main([source,targetdir]) - return 0 + def __init__(self, defaults=None, **props): + if defaults: + defaults.update(props) + props = defaults + dict.__init__(self,props) - def createIconTargets(target,source,env): - """ parse the SVG to get the target file names """ - source = str(source[0]) - targetdir = os.path.basename(str(target[0])) - targetfiles = renderer.getTargetNames(source) # parse SVG - return (["$BINDIR/%s" % name for name in targetfiles], source) + def __getattr__(self,key): + if key=='__get__' or key=='__set__': + raise AttributeError + return self.setdefault(key) - def IconCopy(env, source): - """Copy icon to corresponding icon dir. """ - 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 __setattr__(self,key,val): + self[key] = val - -def Tarball(env,location,dirs,suffix=''): - """ Custom Command: create Tarball of some subdirs - location: where to create the tar (may optionally include filename.tar.gz) - suffix: (optional) suffix to include in the tar name - dirs: directories to include in the tar - - 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) +def extract_localPathDefs (localDefs): + """ extracts the directory configuration values. + For sake of simplicity, paths and directories are defined + immediately as global variables in the SConstruct. This helper + extracts from the given dict the variables matching some magical + pattern and returns them wrapped into a Record for convenient access """ - targetID = '../extern-tar%s' % suffix - versionID = env['VERSION'] - defaultName = 'lumiera%s_%s' % (suffix, versionID) - nameprefix = 'lumiera-%s/' % (versionID) - location = env.subst(location) - dirs = env.subst(dirs) - return env.Command(targetID,None, createTarball, - location=location, defaultName=defaultName, dirs=dirs, nameprefix=nameprefix) - - -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) - - + def relevantPathDefs (mapping): + for (k,v) in mapping.items(): + if (k.startswith('src') or k.startswith('build') or k.startswith('install')) and Util.is_String(v): + v = v.strip() + if not v.endswith('/'): v += '/' + yield (k,v) + + return dict(relevantPathDefs(localDefs)) diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index 8b6a4b594..82a89b6ae 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -22,6 +22,9 @@ ##################################################################### +import os +from os import path + import SCons import SCons.SConf from SCons.Environment import Environment @@ -35,9 +38,16 @@ class LumieraEnvironment(Environment): This allows us to carry structured config data without using global vars. Idea inspired by Ardour. """ - def __init__(self,*args,**kw): - Environment.__init__ (self,*args,**kw) + def __init__(self, pathConfig, **kw): + Environment.__init__ (self,**kw) + self.path = Record (pathConfig) 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): kw['env'] = self @@ -73,7 +83,7 @@ class LumieraEnvironment(Environment): print "Problems configuring the Library %s (>= %s)" % (libID,minVersion) return False - self.libInfo[libID] = libInfo = LumieraEnvironment() + self.libInfo[libID] = libInfo = Environment() libInfo["ENV"]["PKG_CONFIG_PATH"] = os.environ.get("PKG_CONFIG_PATH") libInfo.ParseConfig ('pkg-config --cflags --libs '+ libID ) if alias: @@ -102,3 +112,230 @@ class LumieraConfigContext(ConfigBase): 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) diff --git a/admin/vg-run.sh b/admin/vg-run.sh index f8d82040b..3a3aa1f57 100644 --- a/admin/vg-run.sh +++ b/admin/vg-run.sh @@ -12,6 +12,7 @@ # LOGFILE=,valgrind.log SUPPRESS=vgsuppression +MODULEDIR=modules VALGRINDFLAGS=${VALGRINDFLAGS:---leak-check=yes --show-reachable=yes --demangle=yes} EXECUTABLE=$1 @@ -24,6 +25,9 @@ fi PATHPREFIX=${EXECUTABLE%/*} 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 [[ $SUPPRESS -nt $SUPPRESS.supp ]]; then echo 'generating valgrind supression file...' @@ -37,6 +41,7 @@ else echo 'no suppression.' fi + echo "running......$@" valgrind $VALGRINDFLAGS --log-file=$LOGFILE.%p $SUPPRESSIONFLAG $@ & diff --git a/bin/.libs b/bin/.libs deleted file mode 120000 index 2e321a8e9..000000000 --- a/bin/.libs +++ /dev/null @@ -1 +0,0 @@ -../.libs \ No newline at end of file diff --git a/bin/DIR_INFO b/bin/DIR_INFO deleted file mode 100644 index 9dafe61c3..000000000 --- a/bin/DIR_INFO +++ /dev/null @@ -1 +0,0 @@ -Lumiera executable(s) and libraries will be built here diff --git a/data/DIR_INFO b/data/DIR_INFO new file mode 100644 index 000000000..fc5c22ea2 --- /dev/null +++ b/data/DIR_INFO @@ -0,0 +1 @@ +Additional configuration, icons, graphics etc. to be installed with Lumiera diff --git a/data/config/DIR_INFO b/data/config/DIR_INFO new file mode 100644 index 000000000..c4dfc006a --- /dev/null +++ b/data/config/DIR_INFO @@ -0,0 +1 @@ +Lumiera configuration files diff --git a/data/config/dummy_lumiera.ini b/data/config/dummy_lumiera.ini new file mode 100644 index 000000000..a8408c41b --- /dev/null +++ b/data/config/dummy_lumiera.ini @@ -0,0 +1,4 @@ +# This is an dummy Lumiera config file +# +# Actually Lumiera can't yet load any extended config, as of 1/2011 +# diff --git a/data/config/setup.ini b/data/config/setup.ini new file mode 100644 index 000000000..e4a00f4e2 --- /dev/null +++ b/data/config/setup.ini @@ -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 +# diff --git a/src/common/bootstrap.cpp b/src/common/bootstrap.cpp new file mode 100644 index 000000000..35f2d20cc --- /dev/null +++ b/src/common/bootstrap.cpp @@ -0,0 +1,268 @@ +/* + dummy-func.cpp - placeholder with dummy functions to demonstrate building/loading shared modules + +* *************************************************************************************************/ + + + + +#include "common/bootstrap.hpp" + +extern "C" { +#include +} +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +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(), + "name of the Lumiera GUI plugin to load") + ("BuildsystemDemo.modulepath", opt::value(), + "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(); + } + + 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 diff --git a/src/common/bootstrap.hpp b/src/common/bootstrap.hpp new file mode 100644 index 000000000..43e43726a --- /dev/null +++ b/src/common/bootstrap.hpp @@ -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 + + +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 diff --git a/src/gui/gtk-lumiera.cpp b/src/gui/gtk-lumiera.cpp index 1b0303903..3ec81680f 100644 --- a/src/gui/gtk-lumiera.cpp +++ b/src/gui/gtk-lumiera.cpp @@ -96,7 +96,7 @@ GtkLumiera::get_app_title() const Glib::ustring GtkLumiera::get_app_version() { - return "0.1-dev"; + return "0.pre.01"; } const Glib::ustring GtkLumiera::get_app_copyright() diff --git a/src/tool/SConscript b/src/tool/SConscript index ca3f99211..1cd45d0d6 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -12,12 +12,12 @@ envSvg.mergeConf(['librsvg-2.0']) envSvg.Append(LIBS=support_lib) -luidgen = env.Program('#$BINDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs -rsvg = envSvg.Program('#$BINDIR/rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) +luidgen = env.Program('luidgen', 'luidgen.c', LIBS=support_lib, install=True) ## for generating Lumiera-UIDs +rsvg = envSvg.Program('rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) # build additional test and administrative tools.... -artifacts['tools'] = [ env.Program('#$BINDIR/hello-world','hello.c') #### hello world (checks C build) - + env.Program('#$BINDIR/try', 'try.cpp') #### to try out some feature... +artifacts['tools'] = [ env.Program('hello-world','hello.c', install=True) #### hello world (checks C build) + + env.Program('try', 'try.cpp', LIBS=support_lib) #### to try out some feature... + luidgen + rsvg ] diff --git a/src/tool/try.cpp b/src/tool/try.cpp index 46080a56e..01a99925b 100644 --- a/src/tool/try.cpp +++ b/src/tool/try.cpp @@ -18,70 +18,57 @@ // 4/10 - pretty printing STL containers with python enabled GDB? // 1/11 - exploring numeric limits // 1/11 - integer floor and wrap operation(s) +// 1/11 - how to fetch the path of the own executable -- at least under Linux? -//#include +#include #include -//#include #include -//#include -#include -#include -#include +extern "C" { +#include +} +//#include "lib/error.hpp" +//#include "lib/symbol.hpp" -using boost::format; -//using std::rand; using std::string; using std::cout; using std::endl; +//using lib::Literal; +//using lib::STRING_MAX_RELEVANT; +const size_t STRING_MAX_RELEVANT = 1000; -div_t -floorwrap (int num, int den) +//namespace error = lumiera::error; + +//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); - if (0 > (num^den) && res.rem) - { // wrap similar to floor() - --res.quot; - res.rem = den - (-res.rem); - } - return res; + string buff(STRING_MAX_RELEVANT+1, '\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)) +// throw error::Fatal ("unable to discover path of running executable") + throw string("unable to discover path of running executable"); + + 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 -main (int, char**) +main (int, char**) //(int argc, char* argv[]) { -// NOBUG_INIT; + NOBUG_INIT; - checkDiv (8,4); - checkDiv (9,4); - 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"; + cout << "\n\nwho am I? :" << catchMyself(); + cout << "\n.gulp.\n"; return 0; } diff --git a/target/DIR_INFO b/target/DIR_INFO new file mode 100644 index 000000000..8764b3989 --- /dev/null +++ b/target/DIR_INFO @@ -0,0 +1 @@ +Lumiera program package tree, holding executable(s) and libraries to be built diff --git a/target/modules/DIR_INFO b/target/modules/DIR_INFO new file mode 100644 index 000000000..ffdc4efcb --- /dev/null +++ b/target/modules/DIR_INFO @@ -0,0 +1 @@ +Lumiera subsystems and other dynamically loadable application components diff --git a/tests/SConscript b/tests/SConscript index fc0fba7e8..6920e912c 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -12,19 +12,17 @@ from Buildhelper import scanSubtree from Buildhelper import globRootdirs from Buildhelper import createPlugins -Import('env','envPlu','artifacts','core') +Import('env','artifacts','core') # temp fix to add test.h -- wouldn't it be better to put this header be into src/lib ? env = env.Clone() env.Append(CPPPATH='#/.') # add Rootdir to Includepath, so test/test.h is found -envPlu = envPlu.Clone() -envPlu.Append(CPPPATH='#/.') # temp fix------------- def testExecutable(env,tree, exeName=None, obj=None): """ declare all targets needed to create a standalone - Test executable of the given Sub-tree. Note that - each subdir is built in its own Environment. + Test executable of the given Sub-tree. + @note this tree uses separate Environment/Includepath """ env = env.Clone() 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 if not exeName: exeName = 'test-%s' % tree - return env.Program('#$BINDIR/'+exeName, obj + core) + return env.Program(exeName, obj + core) def testCollection(env,dir): @@ -44,7 +42,7 @@ def testCollection(env,dir): """ srcpatt = ['test-*.c'] 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)] @@ -59,7 +57,7 @@ moduledirs = globRootdirs('*') artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['lib','components'] ] + [ testCollection(env, dir) for dir in moduledirs if not dir in specials] - + createPlugins(envPlu, 'plugin') + + createPlugins(env, 'plugin') + env.File(glob('*.tests')) # depending on the test definition files for test.sh ) @@ -67,7 +65,7 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['lib','co # 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] Depends(ts,vgsuppr) @@ -103,10 +101,10 @@ if testsuites: testEnv['ENV']['TEST_CONF'] = env.File("test.conf").abspath -testDir = env.Dir('#$BINDIR') +testDir = env.Dir('#$TARGDIR') runTest = env.File("test.sh").abspath -runTs = testEnv.Command('#$BINDIR/,testlog', ts, runTest, chdir=testDir) +runTs = testEnv.Command('#$TARGDIR/,testlog', ts, runTest, chdir=testDir)