From f2c9e67fbc50208dd12bbba2ac06bcab0e5b33fc Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 5 Sep 2008 05:54:14 +0200 Subject: [PATCH 01/32] merge generating icons from SVG source --- .gitignore | 6 +- SConstruct | 28 +- admin/SConscript | 17 + admin/render-icon.py | 178 +++++ admin/rsvg-convert.c | 219 ++++++ admin/scons/Buildhelper.py | 66 +- admin/scons/LumieraEnvironment.py | 6 + icons/prerendered/16x16/panel-timeline.png | Bin 0 -> 453 bytes icons/prerendered/32x32/panel-viewer.png | Bin 0 -> 1502 bytes icons/svg/tool-arrow.svg | 732 +++++++++++++++++++++ src/gui/lumiera_ui.rc | 14 +- 11 files changed, 1233 insertions(+), 33 deletions(-) create mode 100644 admin/SConscript create mode 100755 admin/render-icon.py create mode 100644 admin/rsvg-convert.c create mode 100644 icons/prerendered/16x16/panel-timeline.png create mode 100644 icons/prerendered/32x32/panel-viewer.png create mode 100644 icons/svg/tool-arrow.svg diff --git a/.gitignore b/.gitignore index 10dbaee23..cf7ebb45d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,11 @@ *~ *.tar.* .[^.]* +*.o *.os *.gch ,valgrind.log* -admin/scons/*.pyc +*.pyc optcache Makefile.in build/* @@ -13,5 +14,8 @@ bin/* autom4te.cache/* scripts/* configure +config.log aclocal.m4 semantic.cache +wiki/backups/* +doc/devel/draw/*.png diff --git a/SConstruct b/SConstruct index 173803853..5b2980130 100644 --- a/SConstruct +++ b/SConstruct @@ -37,6 +37,7 @@ BINDIR = 'bin' TESTDIR = 'tests' ICONDIR = 'icons' VERSION = '0.1+pre.01' +SVGRENDERER = 'admin/render-icon' #-----------------------------------Configuration # NOTE: scons -h for help. @@ -68,7 +69,7 @@ def setupBasicEnvironment(): , CCFLAGS='-Wall ' # -fdiagnostics-show-option ) - RegisterPrecompiledHeader_Builder(env) + RegisterIcon_Builder(env,SVGRENDERER) handleNoBugSwitches(env) env.Append(CPPDEFINES = '_GNU_SOURCE') @@ -225,6 +226,10 @@ def configurePlatform(env): if not conf.CheckPkgConfig('gtkmm-2.4', 2.8): print 'Unable to configure GTK--, exiting.' Exit(1) + + if not conf.CheckPkgConfig('glibmm-2.4', '2.16'): + print 'Unable to configure Lib glib--, exiting.' + Exit(1) if not conf.CheckPkgConfig('cairomm-1.0', 0.6): print 'Unable to configure Cairo--, exiting.' @@ -234,6 +239,10 @@ def configurePlatform(env): print 'Unable to configure the GNOME DevTool Library, exiting.' Exit(1) + if not conf.CheckPkgConfig('librsvg-2.0', '2.18.1'): + print 'Need rsvg Library for rendering icons.' + Exit(1) + if not conf.CheckPkgConfig('xv'): Exit(1) # if not conf.CheckPkgConfig('xext'): Exit(1) # if not conf.CheckPkgConfig('sm'): Exit(1) @@ -281,26 +290,29 @@ def defineBuildTargets(env, artifacts): + env.StaticLibrary('$BINDIR/lumi.la', objlib) ) - # use PCH to speed up building - precomp = ( env.PrecompiledHeader('$SRCDIR/pre') - ) - env.Depends(objproc, precomp) - env.Depends(objlib, precomp) artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/main.cpp']+ core ) artifacts['plugins'] = env.SharedLibrary('$BINDIR/lumiera-plugin', objplug) # the Lumiera GTK GUI - envgtk = env.Clone().mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','xv','xext','sm']) + envgtk = env.Clone().mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','librsvg-2.0','xv','xext','sm']) objgui = srcSubtree(envgtk,'$SRCDIR/gui') + # render and install Icons + vector_icon_dir = env.subst('$ICONDIR/svg') + prerendered_icon_dir = env.subst('$ICONDIR/prerendered') + artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])] + + [env.IconCopy(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])] + ) + artifacts['lumigui'] = ( envgtk.Program('$BINDIR/lumigui', objgui + core) - + env.Install('$BINDIR', env.Glob('$ICONDIR/*.png')) + env.Install('$BINDIR', env.Glob('$SRCDIR/gui/*.rc')) + + artifacts['icons'] ) # call subdir SConscript(s) for independent components SConscript(dirs=[SRCDIR+'/tool'], exports='env artifacts core') + SConscript(dirs=['admin'], exports='env envgtk artifacts core') SConscript(dirs=[TESTDIR], exports='env artifacts core') diff --git a/admin/SConscript b/admin/SConscript new file mode 100644 index 000000000..d0ad7b84e --- /dev/null +++ b/admin/SConscript @@ -0,0 +1,17 @@ +# -*- python -*- +## +## SConscript - SCons buildscript for helper tools (called by SConstruct) +## + +Import('env','envgtk','artifacts','core') + +vgsuppr = env.Program('#$BINDIR/vgsuppression',['vgsuppression.c']+core) +rsvg = envgtk.Program('#$BINDIR/rsvg-convert','rsvg-convert.c') + +artifacts['tools'] += [ vgsuppr ## for supressing false valgrind alarms + + rsvg ## for rendering SVG icons (uses librsvg) + ] + +# Rendering the SVG Icons depends on rsvg-convert +env.Depends(artifacts['icons'], rsvg) + diff --git a/admin/render-icon.py b/admin/render-icon.py new file mode 100755 index 000000000..26bdb3653 --- /dev/null +++ b/admin/render-icon.py @@ -0,0 +1,178 @@ +#!/usr/bin/python + +# render-icons.py - Icon rendering utility script +# +# Copyright (C) Lumiera.org +# 2008, Joel Holdsworth +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import sys +import getopt +from xml.dom import minidom +import os +import shutil + +#svgDir = "svg" +#prerenderedDir = "prerendered" +inkscapePath = "/usr/bin/inkscape" +rsvgPath = "./rsvg-convert" +artworkLayerPrefix = "artwork:" + +def createDirectory( name ): + if os.path.exists(name) == False: + os.mkdir(name) + +def copyMergeDirectory( src, dst ): + listing = os.listdir(src) + for file_name in listing: + src_file_path = os.path.join(src, file_name) + dst_file_path = os.path.join(dst, file_name) + shutil.copyfile(src_file_path, dst_file_path) + +def getDocumentSize( svg_element ): + width = float(svg_element.getAttribute("width")) + height = float(svg_element.getAttribute("height")) + return [width, height] + +def findChildLayerElement( parent_element ): + for node in parent_element.childNodes: + if node.nodeType == minidom.Node.ELEMENT_NODE: + if node.tagName == "g": + if node.getAttribute("inkscape:groupmode") == "layer": + return node + return None + +def parsePlateLayer( layer ): + rectangles = [] + for node in layer.childNodes: + if node.nodeType == minidom.Node.ELEMENT_NODE: + if node.tagName == "rect": + x = float(node.getAttribute("x")) + y = float(node.getAttribute("y")) + width = float(node.getAttribute("width")) + height = float(node.getAttribute("height")) + rectangles.append([x, y, width, height]) + return rectangles + +def parseSVG( file_path ): + print "Parsing " + file_path + svgdoc = minidom.parse(file_path) + for root_node in svgdoc.childNodes: + if root_node.nodeType == minidom.Node.ELEMENT_NODE: + if root_node.tagName == "svg": + size = getDocumentSize( root_node ) + layer = findChildLayerElement( root_node ) + if layer != None: + layer_name = layer.getAttribute("inkscape:label") + if layer_name[:len(artworkLayerPrefix)] == artworkLayerPrefix: + artwork_name = layer_name[len(artworkLayerPrefix):] + plate = findChildLayerElement( layer ) + if plate != None: + return artwork_name, size, parsePlateLayer( plate ) + return None + +def renderSvgInkscape(file_path, out_dir, artwork_name, rectangle, doc_size): + + # Calculate the rendering rectangle + x1 = rectangle[0] + y1 = doc_size[1] - rectangle[1] - rectangle[3] + x2 = x1 + rectangle[2] + y2 = y1 + rectangle[3] + + # Call Inkscape to do the render + os.spawnlp(os.P_WAIT, inkscapePath, inkscapePath, + file_path, + "-z", + "-a %g:%g:%g:%g" % (x1, y1, x2, y2), + "-w %g" % (rectangle[2]), "-h %g" % (rectangle[3]), + "--export-png=" + os.path.join(out_dir, "%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name))) + +def renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size): + # Prepare a Cairo context + width = int(rectangle[2]) + height = int(rectangle[3]) + + if not os.path.exists(rsvgPath): + print "Error: executable %s not found." % rsvgPath + + os.spawnlp(os.P_WAIT, rsvgPath, rsvgPath, + "--source-rect=%g:%g:%g:%g" % (rectangle[0], rectangle[1], rectangle[2], rectangle[3]), + "--output=" + os.path.join(out_dir, "%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name)), + file_path) + +def renderSvgIcon(file_path, out_dir): + artwork_name, doc_size, rectangles = parseSVG(file_path) + for rectangle in rectangles: + renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size) + +def getTargetNames(file_path): + """get a list of target names to be rendered from the given source SVG + usable to setup the build targets for SCons + """ + artwork_name, _ , rectangles = parseSVG(file_path) + return ["%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name) for rectangle in rectangles ] + +#def renderSvgIcons(): +# listing = os.listdir(svgDir) +# for file_path in listing: +# [root, extension] = os.path.splitext(file_path) +# if extension.lower() == ".svg": +# renderSvgIcon(os.path.join(svgDir, file_path)) + +#def copyPrerenderedIcons(): +# listing = os.listdir(prerenderedDir) +# for list_item in listing: +# src_dir = os.path.join(prerenderedDir, list_item) +# copyMergeDirectory(src_dir, list_item) + +def printHelp(): + print "render-icon.py SRCFILE.svg TARGETDIR" + print "An icon rendering utility script for lumiera" + +def parseArguments(argv): + optlist, args = getopt.getopt(argv, "") + + if len(args) == 2: + return args[0], args[1] + + printHelp() + return None, None + +def main(argv): + in_path, out_dir = parseArguments(argv) + + if in_path == None or out_dir == None: + return + + if os.path.exists(out_dir) == False: + print "Directory not found: " + out_dir + return + + # Create the icons folders + createDirectory(os.path.join(out_dir, "48x48")) + createDirectory(os.path.join(out_dir, "32x32")) + createDirectory(os.path.join(out_dir, "24x24")) + createDirectory(os.path.join(out_dir, "22x22")) + createDirectory(os.path.join(out_dir, "16x16")) + + renderSvgIcon(in_path, out_dir) + + # Copy in prerendered icons + #copyPrerenderedIcons() + +if __name__=="__main__": + main(sys.argv[1:]) + diff --git a/admin/rsvg-convert.c b/admin/rsvg-convert.c new file mode 100644 index 000000000..7ed5a9910 --- /dev/null +++ b/admin/rsvg-convert.c @@ -0,0 +1,219 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- + + rsvg-convert.c: Command line utility for exercising rsvg with cairo. + + Copyright (C) 2005 Red Hat, Inc. + Copyright (C) 2005 Dom Lachowicz + Copyright (C) 2005 Caleb Moore + Copyright (C) 2008 Joel Holdsworth + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Carl Worth , + Caleb Moore , + Dom Lachowicz , + Joel Holdsworth +*/ + +#ifndef N_ +#define N_(X) X +#endif + +#include +#include +#include + +#include +#include + +#ifdef CAIRO_HAS_PS_SURFACE +#include +#endif + +#ifdef CAIRO_HAS_PDF_SURFACE +#include +#endif + +#ifdef CAIRO_HAS_SVG_SURFACE +#include +#endif + +#ifndef _ +#define _(X) X +#endif + +struct RsvgSizeCallbackData { + gint width; + gint height; +}; + +struct RsvgSourceRectangle { + double left; + double top; + double width; + double height; +}; + +static void +display_error (GError * err) +{ + if (err) { + g_print ("%s", err->message); + g_error_free (err); + } +} + +static void +rsvg_cairo_size_callback (int *width, int *height, gpointer data) +{ + RsvgDimensionData *dimensions = data; + *width = dimensions->width; + *height = dimensions->height; +} + +static cairo_status_t +rsvg_cairo_write_func (void *closure, const unsigned char *data, unsigned int length) +{ + fwrite (data, 1, length, (FILE *) closure); + return CAIRO_STATUS_SUCCESS; +} + +int +main (int argc, char **argv) +{ + GOptionContext *g_option_context; + int width = -1; + int height = -1; + char *source_rect_string = NULL; + char *output = NULL; + GError *error = NULL; + char *filename = NULL; + + char **args = NULL; + RsvgHandle *rsvg; + cairo_surface_t *surface = NULL; + cairo_t *cr = NULL; + RsvgDimensionData dimensions; + FILE *output_file = stdout; + + struct RsvgSourceRectangle source_rect = {0, 0, 0, 0}; + + GOptionEntry options_table[] = { + {"width", 'w', 0, G_OPTION_ARG_INT, &width, + N_("width [optional; defaults to the SVG's width]"), N_("")}, + {"height", 'h', 0, G_OPTION_ARG_INT, &height, + N_("height [optional; defaults to the SVG's height]"), N_("")}, + {"source-rect", 'r', 0, G_OPTION_ARG_STRING, &source_rect_string, + N_("source rectangle [optional; defaults to rectangle of the SVG document]"), N_("left:top:width:height")}, + {"output", 'o', 0, G_OPTION_ARG_STRING, &output, + N_("output filename"), NULL}, + {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &args, NULL, N_("FILE")}, + {NULL} + }; + + g_thread_init(NULL); + + g_option_context = g_option_context_new (_("- SVG Converter")); + g_option_context_add_main_entries (g_option_context, options_table, NULL); + g_option_context_set_help_enabled (g_option_context, TRUE); + if (!g_option_context_parse (g_option_context, &argc, &argv, &error)) { + display_error (error); + exit (1); + } + + g_option_context_free (g_option_context); + + if (output != NULL) { + output_file = fopen (output, "wb"); + if (!output_file) { + fprintf (stderr, _("Error saving to file: %s\n"), output); + exit (1); + } + } + + if (args[0] != NULL) { + filename = args[0]; + } + + /* Parse the source rect */ + if(source_rect_string != NULL) { + const int n = sscanf(source_rect_string, "%lg:%lg:%lg:%lg", + &source_rect.left, &source_rect.top, + &source_rect.width, &source_rect.height); + if(n != 4 || source_rect.width <= 0.0 || source_rect.height < 0.0) { + fprintf (stderr, _("Invalid source rect: %s\n"), source_rect_string); + exit(1); + } + } + + rsvg_init (); + + rsvg = rsvg_handle_new_from_file (filename, &error); + + if (!rsvg) { + fprintf (stderr, _("Error reading SVG:")); + display_error (error); + fprintf (stderr, "\n"); + exit (1); + } + + /* if the user did not specify a source rectangle, get the page size from the SVG */ + if(source_rect_string == NULL) { + rsvg_handle_set_size_callback (rsvg, rsvg_cairo_size_callback, &dimensions, NULL); + source_rect.left = 0; + source_rect.top = 0; + source_rect.width = dimensions.width; + source_rect.height = dimensions.height; + } + + rsvg_handle_get_dimensions (rsvg, &dimensions); + + if(width != -1 && height != -1) { + dimensions.width = width; + dimensions.height = height; + } else if(source_rect_string != NULL) { + dimensions.width = source_rect.width; + dimensions.height = source_rect.height; + } + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + dimensions.width, dimensions.height); + + cr = cairo_create (surface); + + cairo_translate(cr, -source_rect.left, -source_rect.top); + + if(width != -1 && height != -1 && source_rect_string != NULL) { + cairo_scale(cr, (double)dimensions.width / (double)source_rect.width, + (double)dimensions.height / (double)source_rect.height); + } + + rsvg_handle_render_cairo (rsvg, cr); + + cairo_surface_write_to_png_stream (surface, rsvg_cairo_write_func, output_file); + + g_object_unref (G_OBJECT (rsvg)); + + cairo_destroy (cr); + cairo_surface_destroy (surface); + + fclose (output_file); + + rsvg_term (); + + return 0; +} + diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index 02f17b2b4..38940424c 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -28,6 +28,8 @@ import fnmatch import re import tarfile +from SCons.Action import Action + # @@ -58,13 +60,13 @@ def srcSubtree(env,tree,isShared=False,builder=None, **args): else: builder = lambda f: env.Object(f, **args) - return [builder(f) for f in scanSrcSubtree(root)] + return [builder(f) for f in scanSubtree(root)] SRCPATTERNS = ['*.c','*.cpp','*.cc'] -def scanSrcSubtree(roots): +def scanSubtree(roots, patterns=SRCPATTERNS): """ first expand (possible) wildcards and filter out non-dirs. Then scan the given subtree for source filesnames (python generator function) @@ -73,7 +75,7 @@ def scanSrcSubtree(roots): for (dir,_,files) in os.walk(root): if dir.startswith('./'): dir = dir[2:] - for p in SRCPATTERNS: + for p in patterns: for f in fnmatch.filter(files, p): yield os.path.join(dir,f) @@ -102,22 +104,50 @@ def filterNodes(nlist, removeName=None): return filter(predicate, nlist) -def RegisterPrecompiledHeader_Builder(env): - """ Registeres an Custom Builder for generating a precompiled Header. - Note you should define a dependency to the PCH file - """ - def genCmdline(source, target, env, for_signature): - return '$CXXCOM -x c++-header %s' % source[0] - def fixSourceDependency(target, source, env): - print "precompiled header: %s --> %s" % (source[0],target[0]) - return (target, source) + +def getDirname(dir): + """ extract directory name without leading path """ + dir = os.path.realpath(dir) + if not os.path.isdir(dir): + dir,_ = os.path.split(dir) + _, name = os.path.split(dir) + return name - gchBuilder = env.Builder( generator = genCmdline - , emitter = fixSourceDependency - , suffix = '.gch' - , src_suffix = '.hpp' - ) - env.Append(BUILDERS = {'PrecompiledHeader' : gchBuilder}) + + +def RegisterIcon_Builder(env, renderer): + """ Registeres 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. + """ + renderer = __import__(renderer) # load python script for invoking the 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 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 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) diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index 82d419a65..00c217351 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -81,6 +81,12 @@ class LumieraEnvironment(Environment): """ pattern = self.subst(pattern) return glob.glob(pattern) + + def AddMethod (self, function): + """ temporary workaround; newer versions of SCons provide this as a global function """ + self.__dict__[function.__name__] = function.__get__(self) + + class LumieraConfigContext(SConf): diff --git a/icons/prerendered/16x16/panel-timeline.png b/icons/prerendered/16x16/panel-timeline.png new file mode 100644 index 0000000000000000000000000000000000000000..e61a0aea10b398eb7984c86ccb7a839352584f78 GIT binary patch literal 453 zcmV;$0XqJPP){Yk18DncoxhzKH~6mP)nyA^Mso8Evc;XCIfGp`F1ja@}_lBdGc_)&)a28%_8LvId|yioI3yv%ZovidIA`h7Z=krDQ9v| z{lZ~5>zj?LBtCpvlO*1)zLg~2EWMT_7GJ%TBoZPe8OMM1(lb3{59@fwj_pkrmQCVaHb{{mgdom*2N01s zk`eMXX$AYlTiTznj;BzR7avw6-LUf8_G)2r*;yLXQeLSu%2 zh%{<(tV9Cc-T?0%N#dt~CY6tm6`IQ{^m<+8y}vX=Kx^Ho zR3Z~3aCkVvD9AEDp}tf(-j*K8GDoM=quV{i``jZ+DXfj~KJef{hkt+kDRCSdV15Xq zO2vi{I6cj%$JvDHNx;(0f^(iPzdWSZJ0t`_DTB2JP$&hUa4xX6{xnOQOWghN@76gt zOTc^Ih$3r6@Sa{}H82fYLC-~A`c&1E|`3ANTO z8%4RhL%=x-(CPRKX`0dP9+4y?Kx3^w1J2v=_gp|FUf`8iU*@yz9h6e783G_nk+B2` zg=+)lX;!-5`@r$>fRmFUB4BN0M(uP9;9Q{JcQlthQ52!IUYe5wEZN8sLcqCzVsc9* z$%uY`NC*LAq6vlb+&*bj3{Fyf2oxBz1iW{bjIjit6VNK(Qln8yl4OVkv^E%H3T5-v z&L@?7K)lD=2ne&=(ED)78pFtEj1o^W9OAv8ltOERQuZ-wrwL4sS*tiYOzPh>3;!tA%eIak-l(FnHWM%TyNCac$NvL14jrR zYb;ro%^~1ij8dejJ6s-ovkKtX-Y~EKk4jV^~DEy#7pnIF(ygrhZ$_9s7#z?(SlYKAj=py?_08@BaRs zG))`-YJOJ&%bcv`L}9uZR6_KuU6}|+T2UyU@*wG zwzsonn6y9q+ufhF+wC3TbgT{lKR##v?Gp@80jfat`i;$Zzy0#JuH5*>b*+?QYioP% zq!+(=GkWE_--+(uyMIk<{hM~X{X-xW)dQ{|av=d-)=H&PG1gpOTVL147_`zn_uRF! zn8Nw?6A@hIXsxbjrPVWq5Hr5sJf)8+7O>uX-E6gv_PgCzjkTs;Ur;N}6`IW!&1Q?` zrO=FRIbUHR&j zpH$=8_v-c9VtrvDRI615FiH{`3H6|^8f$< literal 0 HcmV?d00001 diff --git a/icons/svg/tool-arrow.svg b/icons/svg/tool-arrow.svg new file mode 100644 index 000000000..026b6633f --- /dev/null +++ b/icons/svg/tool-arrow.svg @@ -0,0 +1,732 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/gui/lumiera_ui.rc b/src/gui/lumiera_ui.rc index 428b7bed4..02f6d90fc 100644 --- a/src/gui/lumiera_ui.rc +++ b/src/gui/lumiera_ui.rc @@ -124,6 +124,8 @@ class "GtkProgressBar" style:highest "lumiera_progressbars" style "timeline_body" { gtkmm__CustomObject_TimelineBody::background = "#7E838B" + gtkmm__CustomObject_TimelineBody::selection = "#2D2D90" + gtkmm__CustomObject_TimelineBody::selection_alpha = 0.5 } style "timeline_ruler" = "default_base" @@ -137,16 +139,16 @@ style "timeline_ruler" = "default_base" gtkmm__CustomObject_TimelineRuler::annotation_vert_margin = 0 gtkmm__CustomObject_TimelineRuler::min_division_width = 100 gtkmm__CustomObject_TimelineRuler::mouse_chevron_size = 5 + gtkmm__CustomObject_TimelineRuler::selection_chevron_size = 5 + gtkmm__CustomObject_TimelineRuler::playback_arrow_colour = "#2D2D90" + gtkmm__CustomObject_TimelineRuler::playback_arrow_alpha = 0.5 + gtkmm__CustomObject_TimelineRuler::playback_arrow_size = 10 + gtkmm__CustomObject_TimelineRuler::playback_arrow_stem_size = 3 } style "timeline_header_base" = "default_base" { -# fg[NORMAL] = { 0.77, 0.77, 0.72 } -# bg[NORMAL] = { 0.18, 0.19, 0.22 } -# bg[ACTIVE] = { 0.20, 0.20, 0.20 } -# bg[PRELIGHT] = { 0.20, 0.20, 0.20 } -# bg[INSENSITIVE] = { 0.20, 0.20, 0.20 } -# bg[SELECTED] = { 0.20, 0.20, 0.20 } + } class "gtkmm__CustomObject_TimelineBody" style:highest "timeline_body" From 84052f1fabf1a65819afcc449567aad49a7b747b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 5 Sep 2008 07:06:46 +0200 Subject: [PATCH 02/32] add placeholder gui main to make the compile work --- admin/vgsuppression.c | 5 +- src/gui/gtk-lumiera.cpp | 214 ++++++++++++++++++++++++++++++++++++++++ src/gui/gtk-lumiera.hpp | 163 ++++++++++++++++++++++++++++++ 3 files changed, 378 insertions(+), 4 deletions(-) create mode 100644 src/gui/gtk-lumiera.cpp create mode 100644 src/gui/gtk-lumiera.hpp diff --git a/admin/vgsuppression.c b/admin/vgsuppression.c index cad026e52..514be9ecb 100644 --- a/admin/vgsuppression.c +++ b/admin/vgsuppression.c @@ -23,15 +23,12 @@ just place any problematic calls where valgrind whines about in main (with comments please) */ -#include "lib/safeclib.h" int main () { - /* debian etch glibc is lazy about cleaning up TLS */ - lumiera_tmpbuf_provide (100); - lumiera_tmpbuf_freeall (); + /* dummy placeholder */ return 0; } diff --git a/src/gui/gtk-lumiera.cpp b/src/gui/gtk-lumiera.cpp new file mode 100644 index 000000000..1b7676dd2 --- /dev/null +++ b/src/gui/gtk-lumiera.cpp @@ -0,0 +1,214 @@ +/* + gtk-lumiera.cpp - simple placeholder to make the compile work + +* *****************************************************/ + +#include +#include + +#include + +using namespace Gtk; + + +#ifdef ENABLE_NLS +# include +#endif + +#include +#include +#include +#include +#include + +#include "gtk-lumiera.hpp" + +NOBUG_CPP_DEFINE_FLAG(gui); + +using namespace Gtk; +using namespace Glib; +using namespace sigc; +using namespace lumiera::gui; + +GtkLumiera the_application; + +int +main (int argc, char *argv[]) +{ + return the_application.main(argc, argv); +} + + + +namespace lumiera { +namespace gui { + +int +GtkLumiera::main(int argc, char *argv[]) +{ + NOBUG_INIT; + + Main kit(argc, argv); + + Glib::set_application_name(AppTitle); + + workspace::WorkspaceWindow main_window; + + kit.run(main_window); + + return 23; +} + + +GtkLumiera& +application() +{ + return the_application; +} + + +namespace workspace { + +WorkspaceWindow::WorkspaceWindow() +: actions(*this) +{ + + layout = NULL; + create_ui(); +} + +WorkspaceWindow::~WorkspaceWindow() +{ + REQUIRE(layout != NULL); + g_object_unref(layout); +} + + +void +WorkspaceWindow::create_ui() +{ + //----- Configure the Window -----// + set_title(AppTitle); + set_default_size(1024, 768); + + //----- Set up the UI Manager -----// + // The UI will be nested within a VBox + add(baseContainer); + + uiManager = Gtk::UIManager::create(); + uiManager->insert_action_group(actions.actionGroup); + + //Layout the actions in a menubar and toolbar: + Glib::ustring ui_info = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + + try + { + uiManager->add_ui_from_string(ui_info); + } + catch(const Glib::Error& ex) + { + ERROR(gui, "Building menus failed: %s", ex.what().data()); + return; + } + + //----- Set up the Menu Bar -----// + Gtk::Widget* menu_bar = uiManager->get_widget("/MenuBar"); + ASSERT(menu_bar != NULL); + baseContainer.pack_start(*menu_bar, Gtk::PACK_SHRINK); + + //----- Set up the Tool Bar -----// + Gtk::Toolbar* toolbar = dynamic_cast( + uiManager->get_widget("/ToolBar")); + ASSERT(toolbar != NULL); + toolbar->set_toolbar_style(TOOLBAR_ICONS); + baseContainer.pack_start(*toolbar, Gtk::PACK_SHRINK); + + + //----- Create the Dock -----// + dock = Glib::wrap(gdl_dock_new()); + layout = gdl_dock_layout_new((GdlDock*)dock->gobj()); + + dockbar = Glib::wrap(gdl_dock_bar_new ((GdlDock*)dock->gobj())); + + dockContainer.pack_start(*dockbar, PACK_SHRINK); + dockContainer.pack_end(*dock, PACK_EXPAND_WIDGET); + baseContainer.pack_start(dockContainer, PACK_EXPAND_WIDGET); + + //----- Create the status bar -----// + statusBar.set_has_resize_grip(); + baseContainer.pack_start(statusBar, PACK_SHRINK); + + show_all_children(); + + +} + + + /* -- Actions -- */ + + +Actions::Actions(WorkspaceWindow &workspace_window) : + workspaceWindow(workspace_window), + is_updating_action_state(false) +{ + workspace_window.signal_show ().connect_notify(mem_fun(this, &Actions::update_action_state)); + + //----- Create the Action Group -----// + actionGroup = ActionGroup::create(); + + // File menu + actionGroup->add(Action::create("FileMenu", _("_File"))); + actionGroup->add(Action::create("FileQuit", Stock::QUIT), + sigc::mem_fun(*this, &Actions::on_menu_file_quit)); + + // Help Menu + actionGroup->add(Action::create("HelpMenu", _("_Help")) ); + actionGroup->add(Action::create("HelpAbout", _("say hello...")), + sigc::mem_fun(*this, &Actions::on_menu_help_about) ); +} + +void +Actions::update_action_state() +{ + is_updating_action_state = true; + is_updating_action_state = false; +} + +/* ===== File Menu Event Handlers ===== */ + +void +Actions::on_menu_file_quit() +{ + workspaceWindow.hide(); // Closes the main window to stop the Gtk::Main::run(). +} + +/* ===== Help Menu Event Handlers ===== */ + +void +Actions::on_menu_help_about() +{ + g_message("Hello Lumi World"); +} + + + +} // namespace workspace + + + +} // namespace gui +} // namespace lumiera + + diff --git a/src/gui/gtk-lumiera.hpp b/src/gui/gtk-lumiera.hpp new file mode 100644 index 000000000..3a20b7731 --- /dev/null +++ b/src/gui/gtk-lumiera.hpp @@ -0,0 +1,163 @@ +/* + gtk-lumiera.cpp - simple placeholder to make the compile work + +* *****************************************************/ + + +#ifndef GTK_LUMIERA_HPP +#define GTK_LUMIERA_HPP + +#include +#include +#include + +#include + +extern "C" { +#include +} + +NOBUG_DECLARE_FLAG(gui); + +#ifdef ENABLE_NLS +# include +# define _(String) gettext (String) +# define gettext_noop(String) String +# define N_(String) gettext_noop (String) +#else +# define _(String) (String) +# define N_(String) String +# define textdomain(Domain) +# define bindtextdomain(Package, Directory) +#endif + +namespace lumiera { + +/** + * The namespace of all GUI code. + */ +namespace gui { + +/* ===== Global Constants ===== */ + +/** + * The name of the application + */ +static const gchar* AppTitle = "Lumiera"; + + + +/* ===== The Application Class ===== */ + +/** + * The main application class. + */ +class GtkLumiera +{ +public: + int main(int argc, char *argv[]); + + +}; + +/** + * Returns a reference to the global application object + */ +GtkLumiera& application(); + + + +namespace workspace { + +class WorkspaceWindow; + +/** +* A helper class which registers and handles +* user action events. +*/ +class Actions +{ +private: + Actions(WorkspaceWindow &workspace_window); + + /* ===== Internals ===== */ +private: + /** + * Updates the state of the menu/toolbar actions + * to reflect the current state of the workspace */ + void update_action_state(); + + /** A reference to the MainWindow */ + WorkspaceWindow &workspaceWindow; + + /* ===== Event Handlers ===== */ +private: + void on_menu_file_quit(); + void on_menu_help_about(); + + // Temporary Junk + void on_menu_others(); + + + /* ===== Actions ===== */ +private: + Glib::RefPtr actionGroup; + + /* ===== Internals ===== */ +private: + bool is_updating_action_state; + + friend class WorkspaceWindow; +}; + + + +/** +* A Mock main window +*/ +class WorkspaceWindow : public Gtk::Window +{ +public: + WorkspaceWindow(); + + ~WorkspaceWindow(); + +private: + void create_ui(); + + + /* ===== UI ===== */ +private: + Glib::RefPtr uiManager; + Gtk::VBox baseContainer; + Gtk::HBox dockContainer; + + //----- Dock Frame -----// + Gtk::Widget *dock; + Gtk::Widget *dockbar; + GdlDockLayout *layout; + + //----- Status Bar -----// + Gtk::Statusbar statusBar; + + /** instance of the actions helper class, which + * registers and handles user action events */ + Actions actions; + + friend class Actions; + +}; + + + + + +} // namespace workspace + + +} // namespace gui +} // namespace lumiera + +#endif // GTK_LUMIERA_HPP + + From 4286c860886dcf3d1023ec0abcf4a4d5fc287cbc Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 18 Oct 2008 05:29:35 +0200 Subject: [PATCH 03/32] merge after landing config system --- SConstruct | 2 +- icons/svg/tool-arrow.svg | 237 +++++++++++++++++++++++++-------------- src/gui/gtk-lumiera.cpp | 4 +- src/gui/gtk-lumiera.hpp | 3 - src/gui/lumiera_ui.rc | 25 +++-- src/proc/lumiera.hpp | 73 +++++++++++- src/tool/SConscript | 1 + src/tool/luidgen.c | 51 +++++++++ tests/SConscript | 20 ++-- tests/test.h | 2 +- tests/test.sh | 2 +- 11 files changed, 306 insertions(+), 114 deletions(-) create mode 100644 src/tool/luidgen.c diff --git a/SConstruct b/SConstruct index 9660003ef..07b791cb0 100644 --- a/SConstruct +++ b/SConstruct @@ -293,7 +293,7 @@ def defineBuildTargets(env, artifacts): objplug = srcSubtree(env,'$SRCDIR/plugin', isShared=True) core = ( env.StaticLibrary('$BINDIR/lumiback.la', objback) + env.StaticLibrary('$BINDIR/lumiproc.la', objproc) - + env.StaticLibrary('$BINDIR/lumi.la', objlib) + + env.StaticLibrary('$BINDIR/lumiera.la', objlib) ) diff --git a/icons/svg/tool-arrow.svg b/icons/svg/tool-arrow.svg index 026b6633f..3f0b72102 100644 --- a/icons/svg/tool-arrow.svg +++ b/icons/svg/tool-arrow.svg @@ -510,6 +510,89 @@ y1="-129.52815" x2="252.00447" y2="-135.47408" /> + + + + + + + + - - - - - + + + - - - - - - + + + + - - - - - - - + + + + + + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "lib/luid.h" + +#include + +/** + * @file + * Generate amd print a Lumiera uid as octal escaped string + */ + +int +main (int argc, char** argv) +{ + lumiera_uid luid; + lumiera_uid_gen (&luid); + + printf ("\""); + for (int i = 0; i < 16; ++i) + printf ("\\%.3hho", *(((char*)&luid)+i)); + printf ("\"\n"); + + return 0; +} + +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/tests/SConscript b/tests/SConscript index b817cdece..d47b9d943 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -36,26 +36,32 @@ def testCollection(env,dir): """ treat a Directory containing a collection of standalone tests. Link each of them into an independent executable """ + srcpatt = ['test-*.c'] exeName = lambda p: path.basename(path.splitext(p)[0]) buildIt = lambda p: env.Program("#$BINDIR/"+exeName(p), [p] + core) - return [buildIt(f) for f in scanSubtree(dir)] + return [buildIt(f) for f in scanSubtree(dir,srcpatt)] def treatPluginTestcase(env): """ Special case: the test-plugin executable """ + tree = 'backend' env = env.Clone() - env.Append(CPPPATH='plugin') - prfx = 'plugin/example_plugin' + env.Append(CPPPATH=tree) + prfx = path.join(tree,'example_plugin') oC = env.SharedObject(prfx, prfx+'.c') oCPP = env.SharedObject(prfx+'_cpp', prfx+'.cpp') testplugin = ( env.SharedLibrary('#$BINDIR/.libs/example_plugin', oC, SHLIBPREFIX='') + env.SharedLibrary('#$BINDIR/.libs/example_plugin_cpp', oCPP, SHLIBPREFIX='') ) - testExe = env.Program('#$BINDIR/test-plugin', ['plugin/plugin_main.c'] + core) - env.Depends(testExe, testplugin) - return testExe - #-- it depentds (at the moment) on a specific isolated test-plugin, +# testExe = env.Program('#$BINDIR/test-plugin', ['plugin/plugin_main.c'] + core) +# env.Depends(testExe, testplugin) +# return testExe + + # 10/2008 example_plugin moved to backend directory. + # ...we should try to find some convention here + return testplugin + #-- it depends (at the moment) on a specific isolated test-plugin, # which is not integrated in the "normal procedure" for building Plugins # (which is not yet implemented as of 8/07) # TODO: handle this case automatically diff --git a/tests/test.h b/tests/test.h index 060d007fc..987892956 100644 --- a/tests/test.h +++ b/tests/test.h @@ -33,7 +33,7 @@ LUMIERA_ERROR_DEFINE (TEST, "test error"); #define TESTS_BEGIN \ int \ -main (int argc, char** argv) \ +main (int argc, const char** argv) \ { \ NOBUG_INIT; \ NOBUG_INIT_FLAG (tests); \ diff --git a/tests/test.sh b/tests/test.sh index d919ed073..e2d5159b7 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -30,7 +30,7 @@ export LC_ALL=C arg0="$0" srcdir="$(dirname "$arg0")" -ulimit -S -t 1 -v 524288 +ulimit -S -t 2 -v 524288 valgrind="" if [ "$VALGRINDFLAGS" = 'DISABLE' ]; then echo "valgrind explicit disabled" From 9ff04e676937bca3d092daa78857106f11dfb070 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 18 Oct 2008 05:34:33 +0200 Subject: [PATCH 04/32] (fix) luidgen needs lib/luid.h --- src/lib/luid.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/luid.h | 97 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+) create mode 100644 src/lib/luid.c create mode 100644 src/lib/luid.h diff --git a/src/lib/luid.c b/src/lib/luid.c new file mode 100644 index 000000000..c8d766094 --- /dev/null +++ b/src/lib/luid.c @@ -0,0 +1,113 @@ +/* + luid - Lumiera unique identifiers + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "lib/luid.h" + +#include +#include +#include +#include +#include +#include +#include + +void +lumiera_uid_set_ptr (lumiera_uid* luid, void* ptr) +{ + memset (luid, 0, 16); + *(void**)luid = ptr; +} + + +void* +lumiera_uid_ptr_get (lumiera_uid* luid) +{ + return *(void**)luid; +} + + +void +lumiera_uid_gen (lumiera_uid* luid) +{ + static int fd = -2; + if (!luid) + return; + + if (fd == -2) + { + fd = open ("/dev/urandom", O_RDONLY); + /* on linux /dev/random would be way to slow for our purpose, so we comment that out for now. + other unixiods offer a /dev/random which has the same semantics as linux /dev/urandom has, + configuration should do this right some day. + if (fd == -1) + fd = open ("/dev/random", O_RDONLY); + */ + if (fd >= 0) + fcntl (fd, F_SETFD, FD_CLOEXEC); + else + srand (getpid () + time (NULL)); + } + + do + { + if (fd < 0) + { + for (int i = 0; i < 16; ++i) + ((unsigned char*)luid)[i] = (unsigned char)(rand()>>7); + } + else + { + if (read (fd, luid, 16) < 16) + abort (); + } + } + /* we identify generic pointers by having some zeros in the luid, + * this happens very unlikely to be in a random luid, just regenerate it then */ + while (!*(((intptr_t*)luid)+1)); +} + + +void +lumiera_uid_copy (lumiera_uid* dest, lumiera_uid* src) +{ + memcpy (dest, src, 16); +} + + +int +lumiera_uid_eq (lumiera_uid* luida, lumiera_uid* luidb) +{ + return !memcmp (luida, luidb, 16); +} + +size_t +lumiera_uid_hash (lumiera_uid* luid) +{ + return *(size_t*)luid; +} + +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/src/lib/luid.h b/src/lib/luid.h new file mode 100644 index 000000000..553d22765 --- /dev/null +++ b/src/lib/luid.h @@ -0,0 +1,97 @@ +/* + luid - Lumiera unique identifiers + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#ifndef LUMIERA_LUID_H +#define LUMIERA_LUID_H + +#include + +/** + * @file + * Lumiera unique identifiers are 128 byte random value. Unlike standard uuid's we + * don't tag a version within them and we may store generic pointers in the space + * occupied by an luid. + */ + +typedef unsigned char lumiera_uid[16]; +typedef lumiera_uid* LumieraUid; + +/* + C++ can't initialize arrays from string literals with the trailing \0 cropped + C can't initialize non constant members, + there we go +*/ +#ifdef __cplusplus +#define LUMIERA_UID_INITIALIZER(l) \ + { \ + l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], \ + l[8], l[9], l[10], l[11], l[12], l[13], l[14], l[15] \ + } +#else +#define LUMIERA_UID_INITIALIZER(l) l +#endif + +/** + * Retrieve a generic pointer stored in a luid + */ +void* +lumiera_uid_ptr_get (lumiera_uid* luid); + +/** + * Generate a new luid + */ +void +lumiera_uid_gen (lumiera_uid* luid); + +/** + * Store a generic pointer in a luid + */ +void +lumiera_uid_set_ptr (lumiera_uid* luid, void* ptr); + + +/** + * Copy an luid + */ +void +lumiera_uid_copy (lumiera_uid* dest, lumiera_uid* src); + + +/** + * Test 2 luid's for equality + */ +int +lumiera_uid_eq (lumiera_uid* luida, lumiera_uid* luidb); + + +/** + * Generate a hashsum over an luid + */ +size_t +lumiera_uid_hash (lumiera_uid* luid); + +#endif +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ From a89b7f8eba3d27bdce5a71b8e704722efc8e8334 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 27 Oct 2008 00:00:40 +0100 Subject: [PATCH 05/32] fix (to make the pseudo gtk_lumiera compile again) --- src/gui/gtk-lumiera.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/gtk-lumiera.cpp b/src/gui/gtk-lumiera.cpp index 66698150c..9c0528bbd 100644 --- a/src/gui/gtk-lumiera.cpp +++ b/src/gui/gtk-lumiera.cpp @@ -161,7 +161,7 @@ Actions::Actions(WorkspaceWindow &workspace_window) : workspaceWindow(workspace_window), is_updating_action_state(false) { - workspace_window.signal_show ().connect_notify(mem_fun(this, &Actions::update_action_state)); + workspace_window.signal_show ().connect_notify(sigc::mem_fun(this, &Actions::update_action_state)); //----- Create the Action Group -----// actionGroup = ActionGroup::create(); From 62922d357beffce111a4794fca751f15e33877c5 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 20 Dec 2008 03:40:28 +0100 Subject: [PATCH 06/32] (irrelevant) changes to make the dummy code build and load shared module Explanation: together with the bare SCons build system, on this branch I added some dummy codefiles, to validate the build system is working as merged in from master --- admin/scons/ToolCCache.py | 65 ++++++++++++++++++++ src/common/dummy-func.cpp | 42 +++++++++++++ src/common/dummy-func.hpp | 20 ++++++ src/gui/gtk-lumiera.cpp | 10 +++ src/gui/gtk-lumiera.hpp | 8 ++- src/include/nobugcfg.h | 39 ------------ src/lumiera/main.cpp | 58 ++---------------- src/proc/common.hpp | 7 +-- src/tool/SConscript | 1 - src/tool/luidgen.c | 124 -------------------------------------- tests/00test.tests | 1 - tests/bugs/buggy.cpp | 2 +- 12 files changed, 151 insertions(+), 226 deletions(-) create mode 100644 admin/scons/ToolCCache.py create mode 100644 src/common/dummy-func.cpp create mode 100644 src/common/dummy-func.hpp delete mode 100644 src/tool/luidgen.c diff --git a/admin/scons/ToolCCache.py b/admin/scons/ToolCCache.py new file mode 100644 index 000000000..ecc45d011 --- /dev/null +++ b/admin/scons/ToolCCache.py @@ -0,0 +1,65 @@ +# -*- python -*- +## +## ToolDistCC.py - SCons tool for distributed compilation using DistCC +## + +# Copyright (C) Lumiera.org and FreeOrion.org +# 2008, Hermann Vosseler +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +##################################################################### + +# This SCons builder was extracted from http://www.freeorion.org/ +# FreeOrion is an open-source platform-independent galactic conquest game +# +# history: 12/2008 adapted for Lumiera build system + + +import os +from Buildhelper import * + + +def generate(env): + """ Modify the environment such as to redirect any + C/C++ compiler invocations through DistCC. Additionally + pull in the environment config variables used by DistCC + """ + if not exists(env): return + + assert env['DISTCC'] + if not env['DISTCC'] in env['CC']: + env['CC'] = env.subst('$DISTCC $CC') + if not env['DISTCC'] in env['CXX']: + env['CXX'] = env.subst('$DISTCC $CXX') + print env.subst("* Build using $DISTCC") + for i in ['HOME' + ,'DISTCC_HOSTS' + ,'DISTCC_VERBOSE' + ,'DISTCC_FALLBACK' + ,'DISTCC_LOG' + ,'DISTCC_MMAP' + ,'DISTCC_SAVE_TEMPS' + ,'DISTCC_TCP_CORK' + ,'DISTCC_SSH' + ]: + if os.environ.has_key(i) and not env.has_key(i): + env['ENV'][i] = os.environ[i] + + +def exists(env): + """ Ensure DistCC exists. + """ + return checkCommandOption(env, 'DISTCC', cmdName='distcc') + diff --git a/src/common/dummy-func.cpp b/src/common/dummy-func.cpp new file mode 100644 index 000000000..08b7f69a0 --- /dev/null +++ b/src/common/dummy-func.cpp @@ -0,0 +1,42 @@ +/* + dummy-func.cpp - placeholder with dummy functions to demonstrate building shared modules + +* ******************************************************************************************/ + + +#include "common/dummy-func.hpp" + +#include +#include + + + + + +namespace lumiera { + + const char * const GUI_MODULE_NAME = ".libs/gtk_gui.lum"; + + typedef void (*VoidFunc)(void); + + + void + loadDummyGui() + { + void* handle = dlopen (GUI_MODULE_NAME, RTLD_LAZY|RTLD_LOCAL); + if (handle) + { + VoidFunc entryPoint = (VoidFunc) dlsym (handle, "start_dummy_gui"); + + if (!entryPoint) + ERROR (lumiera, "unable to resolve the entry point symbol after loading the GUI module."); + + else + (*entryPoint) (); + } + else + ERROR (lumiera, "unable to load %s", GUI_MODULE_NAME); + } + + +} // namespace lumiera diff --git a/src/common/dummy-func.hpp b/src/common/dummy-func.hpp new file mode 100644 index 000000000..cbf3a96bb --- /dev/null +++ b/src/common/dummy-func.hpp @@ -0,0 +1,20 @@ +/* + dummy-func.hpp - placeholder with dummy functions to demonstrate building shared modules + +* ******************************************************************************************/ + + +#include "include/nobugcfg.h" + + +namespace lumiera { + + /** 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 demonstarte that the SCons build system is working. + */ + void loadDummyGui(); + + +} // namespace lumiera diff --git a/src/gui/gtk-lumiera.cpp b/src/gui/gtk-lumiera.cpp index 9c0528bbd..4dbc6ec5e 100644 --- a/src/gui/gtk-lumiera.cpp +++ b/src/gui/gtk-lumiera.cpp @@ -37,6 +37,16 @@ main (int argc, char *argv[]) return the_application.main(argc, argv); } +extern "C" +void +start_dummy_gui () +{ + NOTICE(gui, "This is a placeholder for the Lumiera GTK-GUI starting...."); +} + + + + namespace gui { diff --git a/src/gui/gtk-lumiera.hpp b/src/gui/gtk-lumiera.hpp index f543f1fde..a55160530 100644 --- a/src/gui/gtk-lumiera.hpp +++ b/src/gui/gtk-lumiera.hpp @@ -12,14 +12,20 @@ #include #include #include -#include "lib/util.hpp" #include extern "C" { #include + + +/** Dummy function just to demonstrate loading the GUI as + * shared module from the SCons build. */ +void start_dummy_gui (); + } + NOBUG_DECLARE_FLAG(gui); #ifdef ENABLE_NLS diff --git a/src/include/nobugcfg.h b/src/include/nobugcfg.h index cfcedd6b7..5e1a33eb1 100644 --- a/src/include/nobugcfg.h +++ b/src/include/nobugcfg.h @@ -24,37 +24,6 @@ /** @file nobugcfg.h ** This header is for including and configuring NoBug. - ** The idea is that configuration and some commonly used flag - ** declarations are to be kept in one central location. Subsystems - ** are free to define and use additional flags for local use. Typically, - ** this header will be included via some of the basic headers like error.hpp, - ** which in turn gets included e.g. by proc/common.hpp - ** - ** This header can thus be assumed to be effectively global. It should contain - ** only declarations of global relevance, as any change causes the whole project - ** to be rebuilt. Moreover, for C++ this header assures automatic initialisation - ** of NoBug by placing a static ctor call. - ** - ** Besides the usual guarded declarations, this header contains one section - ** with the corresponding definitions. This section is to be included once - ** by some translation unit (currently this is lumiera/nobugcfg.cpp) in order to - ** generate the necessary definitions. - ** - ** @par Logging configuration - ** By default, logging is configured such as to emit a small number of informative - ** messages on the starting terminal and to report fatal errors. But besides the - ** usual fine-grained tracing messages, we define a small number of distinct - ** thematic Logging Channels providing a consistent high-level view of - ** what is going on with regards to a specific aspect of the application - ** - \c operate documents a high-level overall view of what the application \em does - ** - \c render focuses on the working of the render engine (without logging each frame) - ** - \c config shows anything of relevance regarding the configured state of App and session - ** - \c memory allows to diagnose a high-level view of memory management - ** - ** Any log level can be overridden by an environment variable, for example - ** \code NOBUG_LOG='operate:INFO' ./lumiera \endcode - ** - ** @todo logging to files? */ @@ -67,14 +36,6 @@ #ifdef __cplusplus /* ============= C++ ================ */ -#include "include/lifecycle.h" -#include "include/error.hpp" ///< make assertions throw instead of abort() - -namespace lumiera { - void initialise_NoBug (); - namespace { - LifecycleHook trigger_it_ (ON_BASIC_INIT, &initialise_NoBug); -} } #endif /* =====================(End) C++ ================ */ diff --git a/src/lumiera/main.cpp b/src/lumiera/main.cpp index 8dce65c54..f148965d6 100644 --- a/src/lumiera/main.cpp +++ b/src/lumiera/main.cpp @@ -23,67 +23,17 @@ #include "include/nobugcfg.h" -#include "include/error.hpp" -#include "common/appstate.hpp" -#include "common/option.hpp" - -#include "backend/enginefacade.hpp" -#include "backend/netnodefacade.hpp" -#include "backend/scriptrunnerfacade.hpp" -#include "proc/facade.hpp" -#include "gui/guifacade.hpp" - -using util::Cmdline; -using lumiera::Subsys; -using lumiera::AppState; -using lumiera::ON_GLOBAL_INIT; - -namespace { - Subsys& engine = backend::EngineFacade::getDescriptor(); - Subsys& netNode = backend::NetNodeFacade::getDescriptor(); - Subsys& script = backend::ScriptRunnerFacade::getDescriptor(); - Subsys& builder = proc::Facade::getBuilderDescriptor(); - Subsys& session = proc::Facade::getSessionDescriptor(); - Subsys& lumigui = gui::GuiFacade::getDescriptor(); -} +#include "common/dummy-func.hpp" int main (int argc, const char* argv[]) { + NOBUG_INIT; + NOTICE (lumiera, "*** Lumiera NLE for Linux ***"); - AppState& application = AppState::instance(); - try - { - Cmdline args (argc,argv); - lumiera::Option options (args); - application.init (options); - - session.depends (builder); - netNode.depends (session); - netNode.depends (engine); -// lumigui.depends (session); //////TODO commented out in order to be able to start up a dummy GuiStarterPlugin -// lumigui.depends (engine); - script.depends (session); - script.depends (engine); - - application.maybeStart (session); - application.maybeStart (netNode); - application.maybeStart (lumigui); - application.maybeStart (script); - - return application.maybeWait(); - } + lumiera::loadDummyGui(); - - catch (lumiera::Error& problem) - { - return application.abort (problem); - } - catch (...) - { - return application.abort(); - } } diff --git a/src/proc/common.hpp b/src/proc/common.hpp index 970811102..8c9c7fe78 100644 --- a/src/proc/common.hpp +++ b/src/proc/common.hpp @@ -41,11 +41,8 @@ /* common types frequently used... */ -#include "lib/p.hpp" -#include "lib/util.hpp" -#include "lib/lumitime.hpp" -#include "include/symbol.hpp" -#include "include/error.hpp" ///< pulls in NoBug via nobugcfg.h +#include "include/nobugcfg.h" +#include "common/dummy-func.hpp" /** diff --git a/src/tool/SConscript b/src/tool/SConscript index 2336c3553..41a1593d1 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -8,7 +8,6 @@ Import('env','artifacts','core') # build the ubiquitous Hello World application (note: C source) artifacts['tools'] = [ env.Program('#$BINDIR/hello-world','hello.c') - + env.Program('#$BINDIR/luidgen', ['luidgen.c']+core) + env.Program('#$BINDIR/try', 'try.cpp') #### to try out some feature... ] diff --git a/src/tool/luidgen.c b/src/tool/luidgen.c deleted file mode 100644 index 730395b6c..000000000 --- a/src/tool/luidgen.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - luidgen.c - generate a lumiera uuid - - Copyright (C) Lumiera.org - 2008 Christian Thaeter - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "lib/safeclib.h" -#include "lib/luid.h" - -#include -#include -#include -#include -#include -#include - -/** - * @file - * Generate amd print a Lumiera uid as octal escaped string - * or process a file replaceing 'LUIDGEN' with a octal escaped string - */ - - -int -main (int argc, char** argv) -{ - NOBUG_INIT; - lumiera_uid luid; - - if (argc == 1) - { - lumiera_uid_gen (&luid); - printf ("\""); - for (int i = 0; i < 16; ++i) - printf ("\\%.3hho", *(((char*)&luid)+i)); - printf ("\"\n"); - } - else - { - for (int i = 1; i < argc; ++i) - { - FILE* in = fopen (argv[i], "r"); - if (!in) - { - fprintf (stderr, "Failed to open file %s for reading: %s\n", argv[i], strerror (errno)); - continue; - } - - char* outname = lumiera_tmpbuf_snprintf (SIZE_MAX, "%s.luidgen", argv[i]); - FILE* out = fopen (outname, "wx"); - if (!out) - { - fprintf (stderr, "Failed to open file %s for writing: %s\n", outname, strerror (errno)); - fclose (in); - continue; - } - - char buf[4096]; - char luidbuf[67]; - - printf ("Luidgen %s ", argv[i]); fflush (stdout); - - while (fgets (buf, 4096, in)) - { - char* pos; - while ((pos = strstr(buf, "LUIDGEN"))) - { - memmove (pos+66, pos+7, strlen (pos+7)+1); - lumiera_uid_gen (&luid); - sprintf (luidbuf, "\""LUMIERA_UID_FMT"\"", LUMIERA_UID_ELEMENTS(luid)); - memcpy (pos, luidbuf, 66); - putchar ('.'); fflush (stdout); - } - fputs (buf, out); - } - - fclose (out); - fclose (in); - - char* backup = lumiera_tmpbuf_snprintf (SIZE_MAX, "%s~", argv[i]); - unlink (backup); - - if (!!rename (argv[i], backup)) - { - fprintf (stderr, "Failed to create backupfile %s: %s\n", backup, strerror (errno)); - continue; - } - - if (!!rename (outname, argv[i])) - { - fprintf (stderr, "Renaming %s to %s failed: %s\n", outname, argv[i], strerror (errno)); - rename (backup, argv[i]); - continue; - } - - printf (" done\n"); - } - } - - return 0; -} - -/* -// Local Variables: -// mode: C -// c-file-style: "gnu" -// indent-tabs-mode: nil -// End: -*/ diff --git a/tests/00test.tests b/tests/00test.tests index d1205b8c1..71b7edccb 100644 --- a/tests/00test.tests +++ b/tests/00test.tests @@ -21,5 +21,4 @@ return: 2 END PLANNED "this may never happen" -END diff --git a/tests/bugs/buggy.cpp b/tests/bugs/buggy.cpp index b856f2a44..630d3b00b 100644 --- a/tests/bugs/buggy.cpp +++ b/tests/bugs/buggy.cpp @@ -23,7 +23,7 @@ #include -#include "proc/lumiera.hpp" +#include "proc/common.hpp" using std::cout; From 83e0c44a49047693bec15b7182cfb046b59b61f2 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 15 Jan 2009 14:48:07 +0100 Subject: [PATCH 07/32] (irrelevant) fixes to make the dummy/demo build work again --- src/gui/gtk-lumiera.cpp | 8 +- src/gui/gtk-lumiera.hpp | 2 + src/tool/SConscript | 2 +- tests/SConscript | 2 +- tests/plugin/examplepluginc/example_plugin.c | 169 +----------------- .../plugin/test-cpp-plugin/example_plugin.cpp | 129 ------------- 6 files changed, 11 insertions(+), 301 deletions(-) delete mode 100644 tests/plugin/test-cpp-plugin/example_plugin.cpp diff --git a/src/gui/gtk-lumiera.cpp b/src/gui/gtk-lumiera.cpp index 102c424dd..4d8f9bda5 100644 --- a/src/gui/gtk-lumiera.cpp +++ b/src/gui/gtk-lumiera.cpp @@ -37,7 +37,11 @@ extern "C" void start_dummy_gui () { - NOTICE(gui, "This is a placeholder for the Lumiera GTK-GUI starting...."); + NOTICE(gui, "Dummy Lumiera GTK-GUI starting...."); + + int argc =0; + char *argv[] = {}; // faked command line for GTK + gui::application().main(argc, argv); } @@ -90,7 +94,7 @@ void WorkspaceWindow::create_ui() { //----- Configure the Window -----// - set_title(AppTitle); + set_title(GtkLumiera::AppTitle); set_default_size(1024, 768); //----- Set up the UI Manager -----// diff --git a/src/gui/gtk-lumiera.hpp b/src/gui/gtk-lumiera.hpp index c4efb6259..832a460ad 100644 --- a/src/gui/gtk-lumiera.hpp +++ b/src/gui/gtk-lumiera.hpp @@ -16,6 +16,8 @@ #include #include +#include + extern "C" { #include diff --git a/src/tool/SConscript b/src/tool/SConscript index 0ca19490d..f5c22a478 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -16,7 +16,7 @@ rsvg = envGtk.Program('#$BINDIR/rsvg-convert','rsvg-convert.c') # 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... - + luidgen +# + luidgen + vgsuppr + rsvg ] diff --git a/tests/SConscript b/tests/SConscript index e914ca001..65ac7aa79 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -55,7 +55,7 @@ moduledirs = globRootdirs('*') -artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['lib','components'] ] +artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] # was: ['lib','components'] + [ testCollection(env, dir) for dir in moduledirs if not dir in specials] + createPlugins(envPlu, 'plugin') ) diff --git a/tests/plugin/examplepluginc/example_plugin.c b/tests/plugin/examplepluginc/example_plugin.c index 60992745d..b18212522 100644 --- a/tests/plugin/examplepluginc/example_plugin.c +++ b/tests/plugin/examplepluginc/example_plugin.c @@ -1,50 +1,11 @@ /* - example_plugin - example plugin for testing the interface/plugin system - - Copyright (C) Lumiera.org - 2008, Christian Thaeter - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + example_plugin - dummy example plugin * *****************************************************/ #include -#include "common/interfacedescriptor.h" -#include "common/config_interface.h" - -#include "tests/common/hello_interface.h" - - -LUMIERA_PLUGIN_INTERFACEHANDLE; - -LumieraInterface -myopen (LumieraInterface self, LumieraInterface interfaces) -{ - LUMIERA_PLUGIN_STORE_INTERFACEHANDLE (interfaces); - - fprintf (stderr, "opened %p global interfaces %p\n", self, interfaces); - return self; -} - -void -myclose (LumieraInterface self) -{ - fprintf (stderr, "closed %p\n", self); -} void hallo (void) { @@ -66,131 +27,3 @@ void bye (const char* m) printf ("Bye %s\n", m); } - -void yeahbabe (void) -{ - LUMIERA_INTERFACE_HANDLE (lumieraorg_testhello, 0) german = - LUMIERA_INTERFACE_OPEN (lumieraorg_testhello, 0, 0, lumieraorg_hello_german); - - LUMIERA_INTERFACE_HANDLE (lumieraorg_testhello, 0) english = - LUMIERA_INTERFACE_OPEN (lumieraorg_testhello, 0, 0, lumieraorg_hello_english); - - LUMIERA_INTERFACE_HANDLE (lumieraorg_configuration, 0) config = - LUMIERA_INTERFACE_OPEN (lumieraorg_configuration, 0, 0, lumieraorg_configuration); - - const char* path; - if (config->wordlist_get ("config.path", &path)) - printf ("config path is: %s\n", path); - if (config->wordlist_get ("plugin.path", &path)) - printf ("plugin path is: %s\n", path); - - LUMIERA_INTERFACE_CLOSE (config); - - german->hello (); - english->hello (); - english->goodbye ("World!"); - german->goodbye ("Welt!"); - - LUMIERA_INTERFACE_CLOSE (german); - LUMIERA_INTERFACE_CLOSE (english); -} - - - -LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0, - lumieraorg_exampleplugin_descriptor, - NULL, NULL, NULL, - LUMIERA_INTERFACE_INLINE (name, "\003\307\005\305\201\304\175\377\120\105\332\016\136\354\251\022", - const char*, (LumieraInterface iface), - {return "LumieraTest";} - ), - LUMIERA_INTERFACE_INLINE (brief, "\303\047\265\010\242\210\365\340\024\030\350\310\067\171\170\260", - const char*, (LumieraInterface iface), - {return "Lumiera Test suite examples";} - ), - LUMIERA_INTERFACE_INLINE (homepage, "\363\125\352\312\056\255\274\322\351\245\051\350\120\024\115\263", - const char*, (LumieraInterface iface), - {return "http://www.lumiera.org/develompent.html";} - ), - LUMIERA_INTERFACE_INLINE (version, "\114\043\133\175\354\011\232\002\117\240\107\141\234\157\217\176", - const char*, (LumieraInterface iface), - {return "No Version";} - ), - LUMIERA_INTERFACE_INLINE (author, "\313\300\055\156\126\320\144\247\140\023\261\002\270\367\017\267", - const char*, (LumieraInterface iface), - {return "Christian Thaeter";} - ), - LUMIERA_INTERFACE_INLINE (email, "\163\051\312\276\137\317\267\305\237\274\133\012\276\006\255\160", - const char*, (LumieraInterface iface), - {return "ct@pipapo.org";} - ), - LUMIERA_INTERFACE_INLINE (copyright, "\160\246\161\204\123\262\375\351\157\276\333\073\355\036\062\341", - const char*, (LumieraInterface iface), - { - return - "Copyright (C) Lumiera.org\n" - " 2008 Christian Thaeter "; - } - ), - LUMIERA_INTERFACE_INLINE (license, "\007\311\044\214\064\223\201\326\331\111\233\356\055\264\211\201", - const char*, (LumieraInterface iface), - { - return - "This program is free software; you can redistribute it and/or modify\n" - "it under the terms of the GNU General Public License as published by\n" - "the Free Software Foundation; either version 2 of the License, or\n" - "(at your option) any later version.\n" - "\n" - "This program is distributed in the hope that it will be useful,\n" - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - "GNU General Public License for more details.\n" - "\n" - "You should have received a copy of the GNU General Public License\n" - "along with this program; if not, write to the Free Software\n" - "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"; - } - ), - - LUMIERA_INTERFACE_INLINE (state, "\331\353\126\162\067\376\340\242\232\175\167\105\122\177\306\354", - int, (LumieraInterface iface), - {return LUMIERA_INTERFACE_EXPERIMENTAL;} - ), - - LUMIERA_INTERFACE_INLINE (versioncmp, "\363\145\363\224\325\104\177\057\344\023\367\111\376\221\152\135", - int, (const char* a, const char* b), - {return 0;} - ) - ); - - -LUMIERA_EXPORT( - LUMIERA_INTERFACE_DEFINE (lumieraorg_testhello, 0, - lumieraorg_hello_german, - LUMIERA_INTERFACE_REF (lumieraorg_interfacedescriptor, 0, lumieraorg_exampleplugin_descriptor), - myopen, - myclose, - LUMIERA_INTERFACE_MAP (hello, "\167\012\306\023\031\151\006\362\026\003\125\017\170\022\100\333", - hallo), - LUMIERA_INTERFACE_MAP (goodbye, "\324\267\214\166\340\213\155\053\157\125\064\264\167\235\020\223", - tschuess) - ), - LUMIERA_INTERFACE_DEFINE (lumieraorg_testhello, 0, - lumieraorg_hello_english, - LUMIERA_INTERFACE_REF (lumieraorg_interfacedescriptor, 0, lumieraorg_exampleplugin_descriptor), - myopen, - myclose, - LUMIERA_INTERFACE_MAP (hello, "\326\247\370\247\032\103\223\357\262\007\356\042\051\330\073\116", - hello), - LUMIERA_INTERFACE_MAP (goodbye, "\365\141\371\047\101\230\050\106\071\231\022\235\325\112\354\241", - bye) - ), - LUMIERA_INTERFACE_DEFINE (lumieraorg_testtest, 0, - lumieraorg_test_both, - LUMIERA_INTERFACE_REF (lumieraorg_interfacedescriptor, 0, lumieraorg_exampleplugin_descriptor), - myopen, - myclose, - LUMIERA_INTERFACE_MAP (testit, "\101\060\122\277\370\023\164\257\347\247\164\325\157\266\323\370", - yeahbabe) - ) - ) diff --git a/tests/plugin/test-cpp-plugin/example_plugin.cpp b/tests/plugin/test-cpp-plugin/example_plugin.cpp deleted file mode 100644 index b99d951d3..000000000 --- a/tests/plugin/test-cpp-plugin/example_plugin.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - example_plugin.cpp - example plugin (C++) for testing the interface/plugin system - - Copyright (C) Lumiera.org - 2008, Christian Thaeter , - Hermann Vosseler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -* *****************************************************/ - - -#include -#include - -#include "common/interfacedescriptor.h" -#include "common/config_interface.h" - -extern "C" { -#include "common/interface.h" -#include "common/interfacedescriptor.h" - -#include "tests/common/hello_interface.h" -} - -using boost::format; -using std::cout; -using std::endl; - - - -class example_plugin - { - public: - static LumieraInterface - myopen (LumieraInterface self, LumieraInterface interfaces) - { - static format fmt("opened %x global interfaces %x"); - cout << fmt % self % interfaces << endl; - return self; - } - - static void - myclose (LumieraInterface) - { - std::cout << "closed" << endl; - } - }; - - -class example_plugin_de - : public example_plugin - { - public: - static void - griazi () - { - std::cout << "Hallo Welt!" << endl; - } - - static void - servus (const char* m) - { - std::cout << "Tschuess " << m << endl; - } - }; - - -class example_plugin_en - : public example_plugin - { - public: - static void - hello () - { - std::cout << "Hello World!" << endl; - } - - static void - bye (const char* m) - { - std::cout << "Bye " << m << endl; - } - }; - - - - -extern "C" { /* ================== define two lumieraorg_testhello instance ======================= */ - - - - LUMIERA_EXPORT( /* ===================== PLUGIN EXPORTS ================================== */ - - LUMIERA_INTERFACE_DEFINE (lumieraorg_testhello, 0 - ,lumieraorg_hello_german_cpp - , NULL /* no descriptor given */ - , example_plugin::myopen - , example_plugin::myclose - , LUMIERA_INTERFACE_MAP (hello, "\300\244\125\265\235\312\175\263\335\044\371\047\247\263\015\322", - example_plugin_de::griazi) - , LUMIERA_INTERFACE_MAP (goodbye, "\115\365\126\102\201\104\012\257\153\232\006\210\010\346\076\070", - example_plugin_de::servus) - ), - LUMIERA_INTERFACE_DEFINE (lumieraorg_testhello, 0 - ,lumieraorg_hello_english_cpp - , NULL /* no descriptor given */ - , example_plugin::myopen - , example_plugin::myclose - , LUMIERA_INTERFACE_MAP (hello, "\303\367\107\154\077\063\237\066\034\034\050\136\170\220\260\226", - example_plugin_en::hello) - , LUMIERA_INTERFACE_MAP (goodbye, "\107\207\072\105\101\102\150\201\322\043\104\110\232\023\205\161", - example_plugin_en::bye) - ) - ); - -} // extern "C" From bdcef03834bb542e345920858cd978438e4ccb03 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 24 Apr 2009 17:33:03 +0200 Subject: [PATCH 08/32] Fix: (re)add gthread to make the dummy work --- SConstruct | 2 +- src/tool/SConscript | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SConstruct b/SConstruct index c1466d66b..de7a7edc2 100644 --- a/SConstruct +++ b/SConstruct @@ -353,7 +353,7 @@ def defineBuildTargets(env, artifacts): # the Lumiera GTK GUI envGtk = env.Clone() - envGtk.mergeConf(['gtkmm-2.4','cairomm-1.0','gdl','xv','xext','sm']) + envGtk.mergeConf(['gtkmm-2.4','cairomm-1.0','gdl','gthread-2.0','xv','xext','sm']) envGtk.Append(CPPDEFINES='LUMIERA_PLUGIN', LIBS=core) objgui = srcSubtree(envGtk,'$SRCDIR/gui') diff --git a/src/tool/SConscript b/src/tool/SConscript index e475fc057..d5e89270d 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -8,7 +8,7 @@ Import('env','artifacts','core') support_lib = artifacts['support'] envSvg = env.Clone() -envSvg.mergeConf(['librsvg-2.0']) +envSvg.mergeConf(['librsvg-2.0','gthread-2.0']) envSvg.Append(LIBS=support_lib) @@ -19,7 +19,7 @@ rsvg = envSvg.Program('#$BINDIR/rsvg-convert','rsvg-convert.c') ## f # 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... - + luidgen +# + luidgen + vgsuppr + rsvg ] From 8e9edad9e7c7af023d350568ef00ae59c16f24aa Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 11 Oct 2009 07:10:29 +0200 Subject: [PATCH 09/32] fixes to make this dummy compile again --- src/gui/gtk-lumiera.hpp | 2 -- src/tool/try.cpp | 15 --------------- 2 files changed, 17 deletions(-) diff --git a/src/gui/gtk-lumiera.hpp b/src/gui/gtk-lumiera.hpp index 99b0a5efc..951b861ef 100644 --- a/src/gui/gtk-lumiera.hpp +++ b/src/gui/gtk-lumiera.hpp @@ -17,8 +17,6 @@ #include #include -#include "lib/lumitime.hpp" - #include extern "C" { diff --git a/src/tool/try.cpp b/src/tool/try.cpp index fb41545d7..14eb754ff 100644 --- a/src/tool/try.cpp +++ b/src/tool/try.cpp @@ -20,7 +20,6 @@ #include -using std::rand; using std::string; using std::cout; @@ -31,20 +30,6 @@ main (int, char**) //(int argc, char* argv[]) NOBUG_INIT; - for (int i=0; i<10; ++i) - { - TestIt1 testrosteron (i); - - if (testrosteron) - cout << "doIt \n"; - if (!testrosteron) - cout << i << "\n"; - } - cout << "size=" << sizeof(TestIt1) <<"\n"; - - char* horror = 0; - ERROR (all, "note: %s is a horrible thing", horror); - cout << "\n.gulp.\n"; return 0; From f0aed2c2cc79d77e434efec75b2e26f01ff10fd2 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 21 May 2010 03:50:41 +0200 Subject: [PATCH 10/32] fix dummy compilation/tests --- src/proc/common.hpp | 2 -- tests/00test.tests | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/proc/common.hpp b/src/proc/common.hpp index 31e885f1d..8c9c7fe78 100644 --- a/src/proc/common.hpp +++ b/src/proc/common.hpp @@ -43,8 +43,6 @@ #include "include/nobugcfg.h" #include "common/dummy-func.hpp" -#include "lib/lumitime.hpp" -#include "lib/symbol.hpp" /** diff --git a/tests/00test.tests b/tests/00test.tests index 71b7edccb..84dc646bb 100644 --- a/tests/00test.tests +++ b/tests/00test.tests @@ -15,8 +15,8 @@ END TESTING "Run the Dummy Test Executable" ./test-bugs TEST "I am a dummy test" < Date: Thu, 3 Jun 2010 04:18:34 +0200 Subject: [PATCH 11/32] Bump required nobug version to 201006.1 --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index dc4dc392a..eaf03c54e 100644 --- a/SConstruct +++ b/SConstruct @@ -232,7 +232,7 @@ def configurePlatform(env): else: print 'Valgrind not found. The use of Valgrind is optional; building without.' - if not conf.CheckPkgConfig('nobugmt', 201005.1): + if not conf.CheckPkgConfig('nobugmt', 201006.1): problems.append('Did not find NoBug [http://www.lumiera.org/nobug_manual.html].') else: conf.env.mergeConf('nobugmt') From 002f024ed8bdc67ca7b911aae8b3216d2aa07c46 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 26 Jun 2010 05:08:16 +0200 Subject: [PATCH 12/32] SCons: improve dependency handling for the testsuite --- tests/SConscript | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tests/SConscript b/tests/SConscript index 5fe43738d..6e97f1c5a 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -5,6 +5,8 @@ import os from os import path +from glob import glob + from Buildhelper import srcSubtree from Buildhelper import scanSubtree from Buildhelper import globRootdirs @@ -58,8 +60,9 @@ moduledirs = globRootdirs('*') artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] # was: ['lib','components'] + [ testCollection(env, dir) for dir in moduledirs if not dir in specials] + createPlugins(envPlu, 'plugin') - ) - + + env.File(glob('*.tests')) # depending on the test definition files for test.sh + ) + @@ -70,8 +73,9 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] # # - the product of running the Testsuite is the ",testlog" # - it depends on all artifacts defined as "ts" above -# - if not set via options switch, the environment variable TESTSUITES -# is explicitly propagated to test.sh +# - including the tests/*.tests (suite definition files) +# - if not set via options switch, the environment variables +# TESTSUITES and VALGRINDFLAGS are explicitly propagated to test.sh # testEnv = env.Clone() @@ -80,25 +84,25 @@ if not valgrind and not env['VALGRIND']: valgrind = 'DISABLE' testEnv.Append(ENV = { 'VALGRINDFLAGS' : valgrind - , 'LUMIERA_CONFIG_PATH' : './' + , 'LUMIERA_CONFIG_PATH' : './' }) - + testsuites = env['TESTSUITES'] or os.environ.get('TESTSUITES') if testsuites: - testEnv['ENV']['TESTSUITES'] = testsuites + testEnv['ENV']['TESTSUITES'] = testsuites pluginpath = os.environ.get('LUMIERA_PLUGIN_PATH') if testsuites: - testEnv['ENV']['LUMIERA_PLUGIN_PATH'] = pluginpath + testEnv['ENV']['LUMIERA_PLUGIN_PATH'] = pluginpath # specify path to test.conf -testEnv['ENV']['TEST_CONF'] = env.File("test.conf").abspath +testEnv['ENV']['TEST_CONF'] = env.File("test.conf").abspath + - testDir = env.Dir('#$BINDIR') runTest = env.File("test.sh").abspath -runTs = testEnv.Command(',testlog', ts, runTest, chdir=testDir) +runTs = testEnv.Command('#$BINDIR/,testlog', ts, runTest, chdir=testDir) @@ -111,4 +115,4 @@ env.Alias('testcode', ts ) env.Alias('check', runTs ) # allow tempfiles of test.sh to be cleaned -env.Clean ('check', [',testlog.pre',',expect_stdout',',stdout',',stderr',',testtmp','.libs']) +env.Clean ('check', [',testlog',',testlog.pre',',expect_stdout',',stdout',',stderr',',testtmp','.libs']) From a29591c2992c307bc08258ae82b483b14fc21795 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 26 Jul 2010 03:24:15 +0200 Subject: [PATCH 13/32] SCons: several small improvements, e.g. valgrind-suppressionfile --- admin/scons/ToolCCache.py | 53 +++++++++++++++++------------ src/tool/SConscript | 4 +-- tests/SConscript | 4 +++ tests/test.conf | 3 ++ tests/test.h | 39 +++++++++++---------- tests/test.sh | 2 +- {src => tests}/tool/vgsuppression.c | 0 7 files changed, 60 insertions(+), 45 deletions(-) rename {src => tests}/tool/vgsuppression.c (100%) diff --git a/admin/scons/ToolCCache.py b/admin/scons/ToolCCache.py index ecc45d011..7d93fb7a4 100644 --- a/admin/scons/ToolCCache.py +++ b/admin/scons/ToolCCache.py @@ -1,6 +1,6 @@ # -*- python -*- ## -## ToolDistCC.py - SCons tool for distributed compilation using DistCC +## ToolCCache.py - SCons tool for integrating with CCache compiler cache ## # Copyright (C) Lumiera.org and FreeOrion.org @@ -33,33 +33,44 @@ from Buildhelper import * def generate(env): """ Modify the environment such as to redirect any - C/C++ compiler invocations through DistCC. Additionally - pull in the environment config variables used by DistCC + C/C++ compiler invocations through CCache, while using + CCache config variables found in the os.environment. """ if not exists(env): return - assert env['DISTCC'] - if not env['DISTCC'] in env['CC']: - env['CC'] = env.subst('$DISTCC $CC') - if not env['DISTCC'] in env['CXX']: - env['CXX'] = env.subst('$DISTCC $CXX') - print env.subst("* Build using $DISTCC") + assert env['CCACHE'] + if not env['CCACHE'] in env['CC']: + env['CC'] = env.subst('$CCACHE $CC') + if not env['CCACHE'] in env['CXX']: + env['CXX'] = env.subst('$CCACHE $CXX') + print env.subst("* Build using $CCACHE") + for i in ['HOME' - ,'DISTCC_HOSTS' - ,'DISTCC_VERBOSE' - ,'DISTCC_FALLBACK' - ,'DISTCC_LOG' - ,'DISTCC_MMAP' - ,'DISTCC_SAVE_TEMPS' - ,'DISTCC_TCP_CORK' - ,'DISTCC_SSH' + ,'CCACHE_DIR' + ,'CCACHE_TEMPDIR' + ,'CCACHE_LOGFILE' + ,'CCACHE_PATH' + ,'CCACHE_CC' + ,'CCACHE_CPP2' + ,'CCACHE_PREFIX' + ,'CCACHE_DISABLE' + ,'CCACHE_READONLY' + ,'CCACHE_NOSTATS' + ,'CCACHE_NLEVELS' + ,'CCACHE_HARDLINK' + ,'CCACHE_RECACHE' + ,'CCACHE_UMASK' + ,'CCACHE_HASHDIR' + ,'CCACHE_UNIFY' + ,'CCACHE_EXTENSION' ]: if os.environ.has_key(i) and not env.has_key(i): env['ENV'][i] = os.environ[i] -def exists(env): - """ Ensure DistCC exists. - """ - return checkCommandOption(env, 'DISTCC', cmdName='distcc') + +def exists(env): + """ Ensure CCache is available. + """ + return checkCommandOption(env, 'CCACHE', cmdName='ccache') diff --git a/src/tool/SConscript b/src/tool/SConscript index d5e89270d..bae8d7d12 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -8,11 +8,10 @@ Import('env','artifacts','core') support_lib = artifacts['support'] envSvg = env.Clone() -envSvg.mergeConf(['librsvg-2.0','gthread-2.0']) +envSvg.mergeConf(['librsvg-2.0']) envSvg.Append(LIBS=support_lib) -vgsuppr = env.Program('#$BINDIR/vgsuppression','vgsuppression.c', LIBS=core)## for suppressing false valgrind alarms 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) @@ -20,7 +19,6 @@ rsvg = envSvg.Program('#$BINDIR/rsvg-convert','rsvg-convert.c') ## f 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... # + luidgen - + vgsuppr + rsvg ] diff --git a/tests/SConscript b/tests/SConscript index 6e97f1c5a..5e97f03e6 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -66,6 +66,10 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] +# for creating a Valgrind-Suppression file +vgsuppr = env.Program('#$BINDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms +artifacts['tools'] += [vgsuppr] +Depends(ts,vgsuppr) # diff --git a/tests/test.conf b/tests/test.conf index 38cf8082d..c3abbce1c 100755 --- a/tests/test.conf +++ b/tests/test.conf @@ -1 +1,4 @@ LOGSUPPRESS='^\(\*\*[0-9]*\*\* \)\?[0-9]\{10,\}[:!] \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\|TODO\|PLANNED\|FIXME\|DEPRECATED\|UNIMPLEMENTED\|RESOURCE_ANNOUNCE\|RESOURCE_ENTER\|RESOURCE_STATE\|RESOURCE_LEAVE\):' + +LIMIT_VG_CPU=55 +LIMIT_VG_TIME=60 diff --git a/tests/test.h b/tests/test.h index 01374701a..15e88529c 100644 --- a/tests/test.h +++ b/tests/test.h @@ -22,40 +22,39 @@ #ifndef TEST_H #define TEST_H +#include +#include +#include #include -#include "lib/error.h" - -#include - -NOBUG_DEFINE_FLAG (TESTS); -LUMIERA_ERROR_DEFINE (TEST, "test error"); +NOBUG_DEFINE_FLAG_LIMIT(TEST, LOG_DEBUG); #define TESTS_BEGIN \ int \ main (int argc, const char** argv) \ { \ NOBUG_INIT; \ - NOBUG_INIT_FLAG (TESTS); \ + NOBUG_INIT_FLAG (TEST); \ + unsigned testcnt=0; \ + int ret = 0; \ \ if (argc == 1) \ - { \ - fprintf (stderr, "missing argument\n"); \ - return 1; \ - } + fprintf (stderr, "supported tests:\n"); #define TEST(name) \ - else if (!strcmp(argv[1], name)) + if (argc == 1) \ + fprintf (stderr, " "#name"\n"); \ + else if (!strcmp(argv[1], #name) && ++testcnt) +#define PLANNED_TEST(name) \ + if (argc == 1) \ + fprintf (stderr, " "#name" (planned)\n"); \ + else if (!++testcnt) -#define TESTS_END \ - else \ - { \ - fprintf (stderr, "unknown test\n"); \ - return 1; \ - } \ - \ - return 0; \ +#define TESTS_END \ + if (!testcnt && argc !=1) \ + fprintf (stderr,"no such test: %s\n", argv[1]); \ + return ret; \ } diff --git a/tests/test.sh b/tests/test.sh index 77eae39e7..6b4944d55 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -141,7 +141,7 @@ if [ "$VALGRINDFLAGS" = 'DISABLE' ]; then echo "valgrind explicit disabled" else if [ "$(which valgrind)" ]; then - ulimit -S -t ${ULIMIT_VG_CPU:-20} -v ${ULIMIT_VG_VSZ:-524288} + ulimit -S -t ${LIMIT_VG_CPU:-20} -v ${LIMIT_VG_VSZ:-524288} LIMIT_TIME_REAL="$LIMIT_VG_TIME" if [[ -x 'vgsuppression' ]]; then if [[ 'vgsuppression' -nt 'vgsuppression.supp' ]]; then diff --git a/src/tool/vgsuppression.c b/tests/tool/vgsuppression.c similarity index 100% rename from src/tool/vgsuppression.c rename to tests/tool/vgsuppression.c From 764a38abe641fb52ae7c3f20498132554fc9436a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 28 Jan 2011 23:31:00 +0100 Subject: [PATCH 14/32] SCons: experimental support for some library lookup concerns - setting -rpath with $ORIGIN to build a relocatable package - fix missing DT_SONAME (likely just a problem of very old SCons version) --- SConstruct | 10 +++---- admin/scons/LumieraEnvironment.py | 46 +++++++++++++++++++++++++++++++ src/tool/SConscript | 8 +++--- tests/SConscript | 6 ++-- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/SConstruct b/SConstruct index eaf03c54e..958ba3328 100644 --- a/SConstruct +++ b/SConstruct @@ -337,14 +337,14 @@ def defineBuildTargets(env, artifacts): - 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.LumieraLibrary('$LIBDIR/lumiera', srcSubtree(env,'$SRCDIR/lib')) + lApp = env.LumieraLibrary('$LIBDIR/lumieracommon', srcSubtree(env,'$SRCDIR/common'), LIBS=lLib) + lBack = env.LumieraLibrary('$LIBDIR/lumierabackend', srcSubtree(env,'$SRCDIR/backend')) + lProc = env.LumieraLibrary('$LIBDIR/lumieraproc', srcSubtree(env,'$SRCDIR/proc')) core = lLib+lApp+lBack+lProc - artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) + artifacts['lumiera'] = env.LumieraExe('$BINDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) artifacts['corelib'] = lLib+lApp artifacts['support'] = lLib diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index 8b6a4b594..6f2f188b3 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -27,6 +27,7 @@ import SCons.SConf from SCons.Environment import Environment from Buildhelper import * +from os import path @@ -79,6 +80,51 @@ class LumieraEnvironment(Environment): if alias: self.libInfo[alias] = libInfo return libInfo + + + def LumieraLibrary (self, *args,**kw): + """ add some tweaks missing in SCons 1.0 + like proper handling for SONAME + """ + print "hurgha" + if 'soname' in kw: + soname = self.subst(kw['soname']) + else: + if len(args) > 0: + pathname = args[0] + elif 'target' in kw: + pathname = kw['target'] + else: + raise SyntaxError("Library builder requires target spec. Arguments: %s %s" % (args,kw)) + print "SharedLib: path=%s" % pathname + (dirprefix, libname) = path.split(pathname) + if not libname: + raise ValueError("Library name missing. Only got a directory: "+pathname) + libname = "${SHLIBPREFIX}%s$SHLIBSUFFIX" % libname + print "name = "+libname + soname = self.subst(libname) + print "konstruierter name "+soname + + assert soname + subEnv = self.Clone() + subEnv.Append(LINKFLAGS = "-Wl,-soname="+soname ) + + libBuilder = self.get_builder('SharedLibrary') + print "libBuilder=%s" % libBuilder + print "args = %s, kw = %s" % (args,kw) + return libBuilder(subEnv, *args,**kw); + + + def LumieraExe (self, *args,**kw): + """ add handling for rpath with $ORIGIN + """ + print "progrom" + + subEnv = self.Clone() + subEnv.Append( LINKFLAGS = "-Wl,-rpath=\\$$ORIGIN/$LIBDIR,--enable-new-dtags" ) + + programBuilder = self.get_builder('Program') + return programBuilder (subEnv, *args,**kw); diff --git a/src/tool/SConscript b/src/tool/SConscript index bae8d7d12..0930ffbe3 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.LumieraExe('#$BINDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs +rsvg = envSvg.LumieraExe('#$BINDIR/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.LumieraExe('#$BINDIR/hello-world','hello.c') #### hello world (checks C build) + + env.LumieraExe('#$BINDIR/try', 'try.cpp') #### to try out some feature... # + luidgen + rsvg ] diff --git a/tests/SConscript b/tests/SConscript index 5e97f03e6..8dcfe4bf3 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -35,7 +35,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.LumieraExe('#$BINDIR/'+exeName, obj + core) def testCollection(env,dir): @@ -44,7 +44,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.LumieraExe("#$BINDIR/"+exeName(p), [p] + core) return [buildIt(f) for f in scanSubtree(dir,srcpatt)] @@ -67,7 +67,7 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] # for creating a Valgrind-Suppression file -vgsuppr = env.Program('#$BINDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms +vgsuppr = env.LumieraExe('#$BINDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms artifacts['tools'] += [vgsuppr] Depends(ts,vgsuppr) From 35953b335b6482c37722932a4d093b10f2d2e533 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 29 Jan 2011 02:06:21 +0100 Subject: [PATCH 15/32] SCons: rearrange output directory to target/modules --- .gitignore | 2 +- SConstruct | 16 ++++++++-------- admin/scons/Buildhelper.py | 8 ++++---- admin/scons/LumieraEnvironment.py | 26 ++++++++++++-------------- bin/.libs | 1 - bin/DIR_INFO | 1 - modules | 1 + src/common/dummy-func.cpp | 2 +- src/tool/SConscript | 8 ++++---- target/DIR_INFO | 1 + target/modules/DIR_INFO | 1 + tests/SConscript | 10 +++++----- 12 files changed, 38 insertions(+), 39 deletions(-) delete mode 120000 bin/.libs delete mode 100644 bin/DIR_INFO create mode 120000 modules create mode 100644 target/DIR_INFO create mode 100644 target/modules/DIR_INFO diff --git a/.gitignore b/.gitignore index f66bd5b09..bc696a9a2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ optcache Makefile.in build/* -bin/* +target/* autom4te.cache/* scripts/* configure diff --git a/SConstruct b/SConstruct index 958ba3328..465abdee7 100644 --- a/SConstruct +++ b/SConstruct @@ -26,9 +26,9 @@ OPTIONSCACHEFILE = 'optcache' CUSTOPTIONSFILE = 'custom-options' SRCDIR = 'src' -BINDIR = 'bin' -LIBDIR = '.libs' -PLUGDIR = '.libs' +TARDIR = 'target' +LIBDIR = 'modules' +PLUGDIR = 'modules' TESTDIR = 'tests' ICONDIR = 'icons' VERSION = '0.1+pre.01' @@ -76,7 +76,7 @@ def setupBasicEnvironment(): 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 + , TARDIR=TARDIR , LIBDIR=LIBDIR , PLUGDIR=PLUGDIR , ICONDIR=ICONDIR @@ -96,8 +96,8 @@ 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/:./modules\\"' + ,'LUMIERA_PLUGIN_PATH=\\"$DESTDIR/lib/lumiera/:./modules\\"') appendCppDefine(env,'PKGDATADIR','LUMIERA_CONFIG_PATH=\\"$PKGLIBDIR/:.\\"' ,'LUMIERA_CONFIG_PATH=\\"$DESTDIR/share/lumiera/:.\\"') @@ -344,7 +344,7 @@ def defineBuildTargets(env, artifacts): core = lLib+lApp+lBack+lProc - artifacts['lumiera'] = env.LumieraExe('$BINDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) + artifacts['lumiera'] = env.LumieraExe('$TARDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) artifacts['corelib'] = lLib+lApp artifacts['support'] = lLib @@ -368,7 +368,7 @@ def defineBuildTargets(env, artifacts): objgui = srcSubtree(envGtk,'$SRCDIR/gui') guimodule = envGtk.LoadableModule('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') artifacts['gui'] = ( guimodule - + env.Install('$BINDIR', env.Glob('$SRCDIR/gui/*.rc')) + + env.Install('$TARDIR', env.Glob('$SRCDIR/gui/*.rc')) + artifacts['icons'] ) diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index f8e349a5e..f781aa730 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -203,11 +203,11 @@ def RegisterIcon_Builder(env): """ import render_icon as renderer # load Joel's python script for invoking the rsvg-convert (SVG render) - renderer.rsvgPath = env.subst("$BINDIR/rsvg-convert") + renderer.rsvgPath = env.subst("$TARDIR/rsvg-convert") def invokeRenderer(target, source, env): source = str(source[0]) - targetdir = env.subst("$BINDIR") + targetdir = env.subst("$TARDIR") renderer.main([source,targetdir]) return 0 @@ -216,12 +216,12 @@ def RegisterIcon_Builder(env): 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) + return (["$TARDIR/%s" % name for name in targetfiles], source) def IconCopy(env, source): """Copy icon to corresponding icon dir. """ subdir = getDirname(source) - return env.Install("$BINDIR/%s" % subdir, source) + return env.Install("$TARDIR/%s" % subdir, source) buildIcon = env.Builder( action = Action(invokeRenderer, "rendering Icon: $SOURCE --> $TARGETS") diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index 6f2f188b3..e7f4e7076 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -83,12 +83,12 @@ class LumieraEnvironment(Environment): def LumieraLibrary (self, *args,**kw): - """ add some tweaks missing in SCons 1.0 - like proper handling for SONAME + """ 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 """ - print "hurgha" if 'soname' in kw: - soname = self.subst(kw['soname']) + soname = self.subst(kw['soname']) # explicitely defined by user else: if len(args) > 0: pathname = args[0] @@ -96,30 +96,28 @@ class LumieraEnvironment(Environment): pathname = kw['target'] else: raise SyntaxError("Library builder requires target spec. Arguments: %s %s" % (args,kw)) - print "SharedLib: path=%s" % pathname (dirprefix, libname) = path.split(pathname) if not libname: raise ValueError("Library name missing. Only got a directory: "+pathname) + libname = "${SHLIBPREFIX}%s$SHLIBSUFFIX" % libname - print "name = "+libname - soname = self.subst(libname) - print "konstruierter name "+soname + soname = self.subst(libname) # else: use the library filename as DT_SONAME assert soname subEnv = self.Clone() subEnv.Append(LINKFLAGS = "-Wl,-soname="+soname ) libBuilder = self.get_builder('SharedLibrary') - print "libBuilder=%s" % libBuilder - print "args = %s, kw = %s" % (args,kw) - return libBuilder(subEnv, *args,**kw); + return libBuilder(subEnv, *args,**kw); # invoke the predefined builder on the augmented environment def LumieraExe (self, *args,**kw): - """ add handling for rpath with $ORIGIN + """ 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 """ - print "progrom" - subEnv = self.Clone() subEnv.Append( LINKFLAGS = "-Wl,-rpath=\\$$ORIGIN/$LIBDIR,--enable-new-dtags" ) 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/modules b/modules new file mode 120000 index 000000000..eb149d644 --- /dev/null +++ b/modules @@ -0,0 +1 @@ +target/modules \ No newline at end of file diff --git a/src/common/dummy-func.cpp b/src/common/dummy-func.cpp index 08b7f69a0..b6250ee75 100644 --- a/src/common/dummy-func.cpp +++ b/src/common/dummy-func.cpp @@ -15,7 +15,7 @@ namespace lumiera { - const char * const GUI_MODULE_NAME = ".libs/gtk_gui.lum"; + const char * const GUI_MODULE_NAME = "modules/gtk_gui.lum"; typedef void (*VoidFunc)(void); diff --git a/src/tool/SConscript b/src/tool/SConscript index 0930ffbe3..725248ca8 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.LumieraExe('#$BINDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs -rsvg = envSvg.LumieraExe('#$BINDIR/rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) +luidgen = env.LumieraExe('#$TARDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs +rsvg = envSvg.LumieraExe('#$TARDIR/rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) # build additional test and administrative tools.... -artifacts['tools'] = [ env.LumieraExe('#$BINDIR/hello-world','hello.c') #### hello world (checks C build) - + env.LumieraExe('#$BINDIR/try', 'try.cpp') #### to try out some feature... +artifacts['tools'] = [ env.LumieraExe('#$TARDIR/hello-world','hello.c') #### hello world (checks C build) + + env.LumieraExe('#$TARDIR/try', 'try.cpp') #### to try out some feature... # + luidgen + rsvg ] 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 8dcfe4bf3..b9e204676 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -35,7 +35,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.LumieraExe('#$BINDIR/'+exeName, obj + core) + return env.LumieraExe('#$TARDIR/'+exeName, obj + core) def testCollection(env,dir): @@ -44,7 +44,7 @@ def testCollection(env,dir): """ srcpatt = ['test-*.c'] exeName = lambda p: path.basename(path.splitext(p)[0]) - buildIt = lambda p: env.LumieraExe("#$BINDIR/"+exeName(p), [p] + core) + buildIt = lambda p: env.LumieraExe("#$TARDIR/"+exeName(p), [p] + core) return [buildIt(f) for f in scanSubtree(dir,srcpatt)] @@ -67,7 +67,7 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] # for creating a Valgrind-Suppression file -vgsuppr = env.LumieraExe('#$BINDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms +vgsuppr = env.LumieraExe('#$TARDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms artifacts['tools'] += [vgsuppr] Depends(ts,vgsuppr) @@ -103,10 +103,10 @@ if testsuites: testEnv['ENV']['TEST_CONF'] = env.File("test.conf").abspath -testDir = env.Dir('#$BINDIR') +testDir = env.Dir('#$TARDIR') runTest = env.File("test.sh").abspath -runTs = testEnv.Command('#$BINDIR/,testlog', ts, runTest, chdir=testDir) +runTs = testEnv.Command('#$TARDIR/,testlog', ts, runTest, chdir=testDir) From 2bcc8d9ae3a9a7d7fc1508c87d635237ce099dda Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 29 Jan 2011 02:33:13 +0100 Subject: [PATCH 16/32] SCons: build loadable modules immediately to the target destination --- SConstruct | 10 +++++----- admin/scons/LumieraEnvironment.py | 2 +- modules | 1 - 3 files changed, 6 insertions(+), 7 deletions(-) delete mode 120000 modules diff --git a/SConstruct b/SConstruct index 465abdee7..a633e0583 100644 --- a/SConstruct +++ b/SConstruct @@ -27,8 +27,8 @@ OPTIONSCACHEFILE = 'optcache' CUSTOPTIONSFILE = 'custom-options' SRCDIR = 'src' TARDIR = 'target' -LIBDIR = 'modules' -PLUGDIR = 'modules' +LIBDIR = 'target/modules' +MODULES = 'modules' TESTDIR = 'tests' ICONDIR = 'icons' VERSION = '0.1+pre.01' @@ -78,7 +78,7 @@ def setupBasicEnvironment(): , SRCDIR=SRCDIR , TARDIR=TARDIR , LIBDIR=LIBDIR - , PLUGDIR=PLUGDIR + , MODULES=MODULES , 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 @@ -96,8 +96,8 @@ def setupBasicEnvironment(): appendVal(env,'DEBUG', 'CCFLAGS', val=' -ggdb') # setup search path for Lumiera plugins - appendCppDefine(env,'PKGLIBDIR','LUMIERA_PLUGIN_PATH=\\"$PKGLIBDIR/:./modules\\"' - ,'LUMIERA_PLUGIN_PATH=\\"$DESTDIR/lib/lumiera/:./modules\\"') + appendCppDefine(env,'PKGLIBDIR','LUMIERA_PLUGIN_PATH=\\"$PKGLIBDIR/:./$MODULES\\"' + ,'LUMIERA_PLUGIN_PATH=\\"$DESTDIR/lib/lumiera/:./$MODULES\\"') appendCppDefine(env,'PKGDATADIR','LUMIERA_CONFIG_PATH=\\"$PKGLIBDIR/:.\\"' ,'LUMIERA_CONFIG_PATH=\\"$DESTDIR/share/lumiera/:.\\"') diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index e7f4e7076..3a08695f9 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -119,7 +119,7 @@ class LumieraEnvironment(Environment): it is linked with """ subEnv = self.Clone() - subEnv.Append( LINKFLAGS = "-Wl,-rpath=\\$$ORIGIN/$LIBDIR,--enable-new-dtags" ) + subEnv.Append( LINKFLAGS = "-Wl,-rpath=\\$$ORIGIN/$MODULES,--enable-new-dtags" ) programBuilder = self.get_builder('Program') return programBuilder (subEnv, *args,**kw); diff --git a/modules b/modules deleted file mode 120000 index eb149d644..000000000 --- a/modules +++ /dev/null @@ -1 +0,0 @@ -target/modules \ No newline at end of file From a6810957b49896634175d1cf5349296b3d5b419d Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 29 Jan 2011 14:10:19 +0100 Subject: [PATCH 17/32] Install: change organisation of target and output directory variables now supporting a PREFIX in addition to the INSTALLDIR. The latter is intended for package building --- SConstruct | 8 +++++--- admin/scons/Buildhelper.py | 2 +- admin/vg-run.sh | 5 +++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/SConstruct b/SConstruct index a633e0583..974b3d7c9 100644 --- a/SConstruct +++ b/SConstruct @@ -80,6 +80,7 @@ def setupBasicEnvironment(): , LIBDIR=LIBDIR , MODULES=MODULES , ICONDIR=ICONDIR + , DESTDIR=env.subst('$INSTALLDIR/$PREFIX') , CPPPATH=["#"+SRCDIR] # used to find includes, "#" means always absolute to build-root , CPPDEFINES=['-DLUMIERA_VERSION='+VERSION ] # note: it's a list to append further defines , CCFLAGS='-Wall -Wextra ' @@ -164,9 +165,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('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) ,PathVariable('SRCTAR', 'Create source tarball prior to compiling', '..', PathVariable.PathAccept) ,PathVariable('DOCTAR', 'Create tarball with developer documentation', '..', PathVariable.PathAccept) ) diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index f781aa730..f555489dd 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -151,7 +151,7 @@ def createPlugins(env, dir): """ 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) + return [env.LoadableModule( '#$TARDIR/$MODULES/%s' % getDirname(tree) , srcSubtree(env, tree) , SHLIBPREFIX='', SHLIBSUFFIX='.lum' ) 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 $@ & From 7993759f8ead6e56cf41aa5f69ebb3d642d50f64 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 29 Jan 2011 14:16:15 +0100 Subject: [PATCH 18/32] SCons: remove the homebrew tarballer that was a nice SCons learning exercise, but never used moreover, packaing is not the concern of a build system --- SConstruct | 12 +----- admin/scons/Buildhelper.py | 76 -------------------------------------- 2 files changed, 1 insertion(+), 87 deletions(-) diff --git a/SConstruct b/SConstruct index 974b3d7c9..b2e9d803a 100644 --- a/SConstruct +++ b/SConstruct @@ -169,8 +169,6 @@ def defineCmdlineVariables(): ,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) - ,PathVariable('SRCTAR', 'Create source tarball prior to compiling', '..', PathVariable.PathAccept) - ,PathVariable('DOCTAR', 'Create tarball with developer documentation', '..', PathVariable.PathAccept) ) return vars @@ -314,15 +312,7 @@ def definePackagingTargets(env, artifacts): """ build operations and targets to be done /before/ compiling. things like creating a source tarball or preparing a version header. """ - t = Tarball(env,location='$SRCTAR',dirs='$SRCDIR') - artifacts['src.tar'] = t - env.Alias('src.tar', t) - env.Alias('tar', t) - - t = Tarball(env,location='$DOCTAR',suffix='-doc',dirs='admin doc wiki uml tests') - artifacts['doc.tar'] = t - env.Alias('doc.tar', t) - env.Alias('tar', t) + pass diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index f555489dd..2fef49cf3 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -231,79 +231,3 @@ def RegisterIcon_Builder(env): env.Append(BUILDERS = {'IconRender' : buildIcon}) env.AddMethod(IconCopy) - - -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) - """ - 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) - - From bc22ec7faaf0d30c08a9470cafb4b1a1182e4a1a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 29 Jan 2011 16:45:22 +0100 Subject: [PATCH 19/32] Install: first preliminary working installation setup the installed lumiera exe can even be started... ...well with a bit of cheating: you need to cd into the lib/lumiera because the PLUGINPATH problem isn't solved yet --- SConstruct | 32 +++++++++++++------ admin/scons/Buildhelper.py | 8 ++--- admin/scons/LumieraEnvironment.py | 52 ++++++++++++++++++++++++++----- data/config/dummy_lumiera.ini | 4 +++ 4 files changed, 75 insertions(+), 21 deletions(-) create mode 100644 data/config/dummy_lumiera.ini diff --git a/SConstruct b/SConstruct index b2e9d803a..3ae0c4fcb 100644 --- a/SConstruct +++ b/SConstruct @@ -336,9 +336,9 @@ def defineBuildTargets(env, artifacts): core = lLib+lApp+lBack+lProc - artifacts['lumiera'] = env.LumieraExe('$TARDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) - artifacts['corelib'] = lLib+lApp + artifacts['corelib'] = core artifacts['support'] = lLib + artifacts['lumiera'] = env.LumieraExe('$TARDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) # building Lumiera Plugins envPlu = env.Clone() @@ -351,6 +351,7 @@ def defineBuildTargets(env, artifacts): artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])] + [env.IconCopy(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])] ) + ##TODO make that into a resource builder # the Lumiera GTK GUI envGtk = env.Clone() @@ -363,6 +364,7 @@ def defineBuildTargets(env, artifacts): + env.Install('$TARDIR', env.Glob('$SRCDIR/gui/*.rc')) + artifacts['icons'] ) + artifacts['guimodule'] = guimodule ###TODO better organisation of GUI components # call subdir SConscript(s) for independent components SConscript(dirs=[SRCDIR+'/tool'], exports='env artifacts core') @@ -376,10 +378,10 @@ def definePostBuildTargets(env, artifacts): """ ib = env.Alias('install-bin', '$DESTDIR/bin') il = env.Alias('install-lib', '$DESTDIR/lib') - env.Alias('install', [ib, il]) + id = env.Alias('install-dat', '$DESTDIR/share') + env.Alias('install', [ib, il, id]) 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' env.Clean ('build', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log' ]) @@ -388,17 +390,27 @@ def definePostBuildTargets(env, artifacts): doxydoc = artifacts['doxydoc'] = env.Doxygen('doc/devel/Doxyfile') env.Alias ('doc', doxydoc) env.Clean ('doc', doxydoc + ['doc/devel/,doxylog','doc/devel/warnings.txt']) + + allbu = env.Alias('allbuild', build+artifacts['testsuite']+doxydoc) def defineInstallTargets(env, artifacts): - """ define some artifacts to be installed into target locations. + """ define artifacts to be installed into target locations. """ - 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']) + binDir = '$DESTDIR/bin/' + lumDir = '$DESTDIR/lib/lumiera/' + modDir = '$DESTDIR/lib/lumiera/$MODULES/' + shaDir = '$DESTDIR/share/lumiera/' + env.Install(dir = modDir, source=artifacts['corelib']) + env.Install(dir = modDir, source=artifacts['plugins']) + env.Install(dir = modDir, source=artifacts['guimodule']) + lumi = env.Install(dir = lumDir, source=artifacts['lumiera']) + tool = env.Install(dir = lumDir, source=artifacts['tools']) + print "Aufruf LINK DESTDIR=" + env.get('DESTDIR') + env.SymLink(binDir+"lumiera",lumi,"../lib/lumiera/lumiera") - env.Install(dir = '$DESTDIR/share/doc/lumiera$VERSION/devel', source=artifacts['doxydoc']) + env.Install(dir = shaDir, source="data/config/dummy_lumiera.ini") ### TODO should become a resource builder +# env.Install(dir = '$DESTDIR/share/doc/lumiera$VERSION/devel', source=artifacts['doxydoc']) ##################################################################### diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index 2fef49cf3..8e7356271 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -151,10 +151,10 @@ def createPlugins(env, dir): """ 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( '#$TARDIR/$MODULES/%s' % getDirname(tree) - , srcSubtree(env, tree) - , SHLIBPREFIX='', SHLIBSUFFIX='.lum' - ) + return [env.LumieraPlugin( '#$TARDIR/$MODULES/%s' % getDirname(tree) + , srcSubtree(env, tree) + , SHLIBPREFIX='', SHLIBSUFFIX='.lum' + ) for tree in findSrcTrees(dir) ] diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index 3a08695f9..b9a018c08 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -22,12 +22,14 @@ ##################################################################### +import os +from os import path + import SCons import SCons.SConf from SCons.Environment import Environment from Buildhelper import * -from os import path @@ -82,10 +84,29 @@ class LumieraEnvironment(Environment): return libInfo - def LumieraLibrary (self, *args,**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 + def SymLink(self, target, source, linktext=None): + """ use python to create a symlink + """ + def makeLink(target,source,env): + if linktext: + dest = linktext + else: + dest = str(source[0]) + link = str(target[0]) + os.symlink(dest, link) + def reportLink(target,source,env): + dest = str(source[0]) + link = str(target[0]) + return "Install link %s -> %s" % (link,dest) + + action = Action(makeLink,reportLink) + self.Command (target,source, action) + + + def defineSoname (self, *args,**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 @@ -102,15 +123,32 @@ class LumieraEnvironment(Environment): libname = "${SHLIBPREFIX}%s$SHLIBSUFFIX" % libname soname = self.subst(libname) # else: use the library filename as DT_SONAME - assert soname + return soname + + + def LumieraLibrary (self, *args,**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 + """ subEnv = self.Clone() - subEnv.Append(LINKFLAGS = "-Wl,-soname="+soname ) + subEnv.Append(LINKFLAGS = "-Wl,-soname="+self.defineSoname(*args,**kw)) libBuilder = self.get_builder('SharedLibrary') return libBuilder(subEnv, *args,**kw); # invoke the predefined builder on the augmented environment + def LumieraPlugin (self, *args,**kw): + """ builds a shared library, autmented by some defaults for lumiera plugins. + """ + subEnv = self.Clone() + subEnv.Append(LINKFLAGS = "-Wl,-soname="+self.defineSoname(*args,**kw)) + + libBuilder = self.get_builder('LoadableModule') + return libBuilder(subEnv, *args,**kw); # invoke the predefined builder on the augmented environment + + def LumieraExe (self, *args,**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, diff --git a/data/config/dummy_lumiera.ini b/data/config/dummy_lumiera.ini new file mode 100644 index 000000000..cfe91da1e --- /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 config, as of 1/2011 + */ From 9e56434c7ec4130098bf374649103bc5c071b50b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 29 Jan 2011 23:09:02 +0100 Subject: [PATCH 20/32] SCons: start concentrating all custom builders into LumieraEnvironment --- SConstruct | 1 - admin/scons/LumieraEnvironment.py | 40 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index 3ae0c4fcb..3711f489e 100644 --- a/SConstruct +++ b/SConstruct @@ -86,7 +86,6 @@ def setupBasicEnvironment(): , CCFLAGS='-Wall -Wextra ' , CFLAGS='-std=gnu99' ) - RegisterIcon_Builder(env) handleNoBugSwitches(env) env.Append(CPPDEFINES = '_GNU_SOURCE') diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index b9a018c08..a1e050156 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -41,6 +41,7 @@ class LumieraEnvironment(Environment): def __init__(self,*args,**kw): Environment.__init__ (self,*args,**kw) self.libInfo = {} + RegisterIcon_Builder(self) def Configure (self, *args, **kw): kw['env'] = self @@ -184,3 +185,42 @@ class LumieraConfigContext(ConfigBase): return self.env.addLibInfo (libID, minVersion, alias) + +###### Lumiera custom tools and builders ######################## + + +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. + """ + + import render_icon as renderer # load Joel's python script for invoking the rsvg-convert (SVG render) + renderer.rsvgPath = env.subst("$TARDIR/rsvg-convert") + + def invokeRenderer(target, source, env): + source = str(source[0]) + targetdir = env.subst("$TARDIR") + renderer.main([source,targetdir]) + return 0 + + def createIconTargets(target,source,env): + """ parse the SVG to get the target file names """ + source = str(source[0]) + targetdir = os.path.basename(str(target[0])) + targetfiles = renderer.getTargetNames(source) # parse SVG + return (["$TARDIR/%s" % name for name in targetfiles], source) + + def IconCopy(env, source): + """Copy icon to corresponding icon dir. """ + subdir = getDirname(source) + return env.Install("$TARDIR/%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) + From 014c22b40aad03af017c2b7eca41acd98cb74f3a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 30 Jan 2011 15:27:21 +0100 Subject: [PATCH 21/32] SCons: rework build directory configuration. All customisations to LuimieraEnvironment --- SConstruct | 60 +++++++++++++++----------- admin/scons/BuilderDoxygen.py | 4 +- admin/scons/Buildhelper.py | 72 ++++++++++++++++--------------- admin/scons/LumieraEnvironment.py | 19 +++++--- src/tool/SConscript | 8 ++-- tests/SConscript | 10 ++--- 6 files changed, 94 insertions(+), 79 deletions(-) diff --git a/SConstruct b/SConstruct index 3711f489e..8cf377233 100644 --- a/SConstruct +++ b/SConstruct @@ -23,17 +23,29 @@ #-----------------------------------Configuration -OPTIONSCACHEFILE = 'optcache' -CUSTOPTIONSFILE = 'custom-options' +TARGDIR = 'target' +VERSION = '0.1+pre.01' +TOOLDIR = './admin/scons' +SCRIPTDIR = './admin' +OPTCACHE = 'optcache' +CUSTOPTFILE = 'custom-options' +####### SRCDIR = 'src' -TARDIR = 'target' -LIBDIR = 'target/modules' -MODULES = 'modules' TESTDIR = 'tests' ICONDIR = 'icons' -VERSION = '0.1+pre.01' -TOOLDIR = './admin/scons' -SCRIPTDIR = './admin' +MODULES = 'modules' +LIBDIR = 'target/modules' +####### +buildExe = '#$TARGDIR' +buildLib = '#$TARGDIR/modules' +buildIcon = '#$TARGDIR/icons' +buildConf = '#$TARGDIR/config' +installExe = '#$DESTDIR/lib/lumiera' +installLib = '#$DESTDIR/lib/lumiera/modules' +installIcon = '#$DESTDIR/share/lumiera/icons' +installConf = '#$DESTDIR/share/lumiera/config' + +localDefinitions = locals() #-----------------------------------Configuration # NOTE: scons -h for help. @@ -55,10 +67,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,21 +78,19 @@ def setupBasicEnvironment(): vars = defineCmdlineVariables() env = LumieraEnvironment(variables=vars ,toolpath = [TOOLDIR] - ,tools = ["default", "BuilderGCH", "BuilderDoxygen"] - ) - env.Tool("ToolDistCC") - env.Tool("ToolCCache") + ,pathConfig = extract_localPathDefs(localDefinitions) + ,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 - , TARDIR=TARDIR + env.Replace( SRCDIR=SRCDIR , LIBDIR=LIBDIR , MODULES=MODULES , ICONDIR=ICONDIR - , DESTDIR=env.subst('$INSTALLDIR/$PREFIX') , CPPPATH=["#"+SRCDIR] # used to find includes, "#" means always absolute to build-root , CPPDEFINES=['-DLUMIERA_VERSION='+VERSION ] # note: it's a list to append further defines , CCFLAGS='-Wall -Wextra ' @@ -102,7 +112,7 @@ def setupBasicEnvironment(): ,'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 +158,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') @@ -311,7 +321,7 @@ def definePackagingTargets(env, artifacts): """ build operations and targets to be done /before/ compiling. things like creating a source tarball or preparing a version header. """ - pass + pass ## currently none @@ -337,7 +347,7 @@ def defineBuildTargets(env, artifacts): artifacts['corelib'] = core artifacts['support'] = lLib - artifacts['lumiera'] = env.LumieraExe('$TARDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) + artifacts['lumiera'] = env.LumieraExe('$TARGDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) # building Lumiera Plugins envPlu = env.Clone() @@ -360,7 +370,7 @@ def defineBuildTargets(env, artifacts): objgui = srcSubtree(envGtk,'$SRCDIR/gui') guimodule = envGtk.LoadableModule('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') artifacts['gui'] = ( guimodule - + env.Install('$TARDIR', env.Glob('$SRCDIR/gui/*.rc')) + + env.Install('$TARGDIR', env.Glob('$SRCDIR/gui/*.rc')) + artifacts['icons'] ) artifacts['guimodule'] = guimodule ###TODO better organisation of GUI components @@ -405,7 +415,6 @@ def defineInstallTargets(env, artifacts): env.Install(dir = modDir, source=artifacts['guimodule']) lumi = env.Install(dir = lumDir, source=artifacts['lumiera']) tool = env.Install(dir = lumDir, source=artifacts['tools']) - print "Aufruf LINK DESTDIR=" + env.get('DESTDIR') env.SymLink(binDir+"lumiera",lumi,"../lib/lumiera/lumiera") env.Install(dir = shaDir, source="data/config/dummy_lumiera.ini") ### TODO should become a resource builder @@ -419,8 +428,7 @@ def defineInstallTargets(env, artifacts): ### === MAIN === #################################################### - -env = setupBasicEnvironment() +env = setupBasicEnvironment(localDefinitions) if not (isCleanupOperation(env) or isHelpRequest()): env = configurePlatform(env) 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 8e7356271..387e0fccb 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 @@ -151,7 +152,7 @@ def createPlugins(env, dir): """ 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.LumieraPlugin( '#$TARDIR/$MODULES/%s' % getDirname(tree) + return [env.LumieraPlugin( '#$TARGDIR/$MODULES/%s' % getDirname(tree) , srcSubtree(env, tree) , SHLIBPREFIX='', SHLIBSUFFIX='.lum' ) @@ -196,38 +197,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. - """ - - import render_icon as renderer # load Joel's python script for invoking the rsvg-convert (SVG render) - renderer.rsvgPath = env.subst("$TARDIR/rsvg-convert") - - def invokeRenderer(target, source, env): - source = str(source[0]) - targetdir = env.subst("$TARDIR") - renderer.main([source,targetdir]) - return 0 - - def createIconTargets(target,source,env): - """ parse the SVG to get the target file names """ - source = str(source[0]) - targetdir = os.path.basename(str(target[0])) - targetfiles = renderer.getTargetNames(source) # parse SVG - return (["$TARDIR/%s" % name for name in targetfiles], source) - - def IconCopy(env, source): - """Copy icon to corresponding icon dir. """ - subdir = getDirname(source) - return env.Install("$TARDIR/%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) +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 + """ + def __init__(self, defaults=None, **props): + if defaults: + defaults.update(props) + props = defaults + dict.__init__(self,props) + + def __getattr__(self,key): + if key=='__get__' or key=='__set__': + raise AttributeError + return self.setdefault(key) + + def __setattr__(self,key,val): + self[key] = val + + +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 + """ + def relevantPathDefs (mapping): + for (k,v) in mapping.items(): + if 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 a1e050156..fa1320451 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -38,9 +38,14 @@ 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") RegisterIcon_Builder(self) def Configure (self, *args, **kw): @@ -77,7 +82,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: @@ -196,11 +201,11 @@ def RegisterIcon_Builder(env): """ import render_icon as renderer # load Joel's python script for invoking the rsvg-convert (SVG render) - renderer.rsvgPath = env.subst("$TARDIR/rsvg-convert") + renderer.rsvgPath = env.subst("$TARGDIR/rsvg-convert") def invokeRenderer(target, source, env): source = str(source[0]) - targetdir = env.subst("$TARDIR") + targetdir = env.subst("$TARGDIR") renderer.main([source,targetdir]) return 0 @@ -209,12 +214,12 @@ def RegisterIcon_Builder(env): source = str(source[0]) targetdir = os.path.basename(str(target[0])) targetfiles = renderer.getTargetNames(source) # parse SVG - return (["$TARDIR/%s" % name for name in targetfiles], source) + return (["$TARGDIR/%s" % name for name in targetfiles], source) def IconCopy(env, source): """Copy icon to corresponding icon dir. """ subdir = getDirname(source) - return env.Install("$TARDIR/%s" % subdir, source) + return env.Install("$TARGDIR/%s" % subdir, source) buildIcon = env.Builder( action = Action(invokeRenderer, "rendering Icon: $SOURCE --> $TARGETS") diff --git a/src/tool/SConscript b/src/tool/SConscript index 725248ca8..bab7e6497 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.LumieraExe('#$TARDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs -rsvg = envSvg.LumieraExe('#$TARDIR/rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) +luidgen = env.LumieraExe('#$TARGDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs +rsvg = envSvg.LumieraExe('#$TARGDIR/rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) # build additional test and administrative tools.... -artifacts['tools'] = [ env.LumieraExe('#$TARDIR/hello-world','hello.c') #### hello world (checks C build) - + env.LumieraExe('#$TARDIR/try', 'try.cpp') #### to try out some feature... +artifacts['tools'] = [ env.LumieraExe('#$TARGDIR/hello-world','hello.c') #### hello world (checks C build) + + env.LumieraExe('#$TARGDIR/try', 'try.cpp') #### to try out some feature... # + luidgen + rsvg ] diff --git a/tests/SConscript b/tests/SConscript index b9e204676..a3c4d8a82 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -35,7 +35,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.LumieraExe('#$TARDIR/'+exeName, obj + core) + return env.LumieraExe('#$TARGDIR/'+exeName, obj + core) def testCollection(env,dir): @@ -44,7 +44,7 @@ def testCollection(env,dir): """ srcpatt = ['test-*.c'] exeName = lambda p: path.basename(path.splitext(p)[0]) - buildIt = lambda p: env.LumieraExe("#$TARDIR/"+exeName(p), [p] + core) + buildIt = lambda p: env.LumieraExe("#$TARGDIR/"+exeName(p), [p] + core) return [buildIt(f) for f in scanSubtree(dir,srcpatt)] @@ -67,7 +67,7 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] # for creating a Valgrind-Suppression file -vgsuppr = env.LumieraExe('#$TARDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms +vgsuppr = env.LumieraExe('#$TARGDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms artifacts['tools'] += [vgsuppr] Depends(ts,vgsuppr) @@ -103,10 +103,10 @@ if testsuites: testEnv['ENV']['TEST_CONF'] = env.File("test.conf").abspath -testDir = env.Dir('#$TARDIR') +testDir = env.Dir('#$TARGDIR') runTest = env.File("test.sh").abspath -runTs = testEnv.Command('#$TARDIR/,testlog', ts, runTest, chdir=testDir) +runTs = testEnv.Command('#$TARGDIR/,testlog', ts, runTest, chdir=testDir) From ab481a80b8b02ef4e0b98fa68a028758c684e0b5 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 30 Jan 2011 16:47:03 +0100 Subject: [PATCH 22/32] better implementation of Lumiera custom SCons builders, wrapping the predefined builders --- admin/scons/LumieraEnvironment.py | 92 +++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index fa1320451..b7d406ed8 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -47,6 +47,7 @@ class LumieraEnvironment(Environment): self.Tool("ToolDistCC") self.Tool("ToolCCache") RegisterIcon_Builder(self) + register_LumieraCustomBuilders(self) def Configure (self, *args, **kw): kw['env'] = self @@ -229,3 +230,94 @@ def RegisterIcon_Builder(env): env.Append(BUILDERS = {'IconRender' : buildIcon}) env.AddMethod(IconCopy) + + + +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 + """ + customisedEnv = self.getCustomEnvironment(env, target=target, **kw) # defined in subclasses + return self.get().__call__ (customisedEnv, target, source, **kw) + + +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 + + +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 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 + + +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 = lumiEnv['BUILDERS']['Program'] + libraryBuilder = lumiEnv['BUILDERS']['SharedLibrary'] + smoduleBuilder = lumiEnv['BUILDERS']['LoadableModule'] + + programBuilder = LumieraExeBuilder (programBuilder) + libraryBuilder = LumieraModuleBuilder (libraryBuilder) + smoduleBuilder = LumieraModuleBuilder (smoduleBuilder) + + lumiEnv['BUILDERS']['Program'] = programBuilder lumiEnv['BUILDERS']['SharedLibrary'] = libraryBuilder lumiEnv['BUILDERS']['LoadableModule'] = smoduleBuilder + + \ No newline at end of file From 609873d90bfa852ccd1dd7fb111d4dc4d9c9264a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 30 Jan 2011 17:00:15 +0100 Subject: [PATCH 23/32] switch to use the new (better) builder implementation especially this means to use the common well-known names again, like "Program" "SharedLibrary". The customisation now happens invisible in LumieraEnvironment. --- SConstruct | 14 +++---- admin/scons/LumieraEnvironment.py | 61 +------------------------------ src/tool/SConscript | 8 ++-- tests/SConscript | 6 +-- 4 files changed, 15 insertions(+), 74 deletions(-) diff --git a/SConstruct b/SConstruct index 8cf377233..4cceb8331 100644 --- a/SConstruct +++ b/SConstruct @@ -338,16 +338,16 @@ def defineBuildTargets(env, artifacts): - lLib = env.LumieraLibrary('$LIBDIR/lumiera', srcSubtree(env,'$SRCDIR/lib')) - lApp = env.LumieraLibrary('$LIBDIR/lumieracommon', srcSubtree(env,'$SRCDIR/common'), LIBS=lLib) - lBack = env.LumieraLibrary('$LIBDIR/lumierabackend', srcSubtree(env,'$SRCDIR/backend')) - lProc = env.LumieraLibrary('$LIBDIR/lumieraproc', srcSubtree(env,'$SRCDIR/proc')) + lLib = env.SharedLibrary('$LIBDIR/lumiera', srcSubtree(env,'$SRCDIR/lib')) + lApp = env.SharedLibrary('$LIBDIR/lumieracommon', srcSubtree(env,'$SRCDIR/common'), LIBS=lLib) + lBack = env.SharedLibrary('$LIBDIR/lumierabackend', srcSubtree(env,'$SRCDIR/backend')) + lProc = env.SharedLibrary('$LIBDIR/lumieraproc', srcSubtree(env,'$SRCDIR/proc')) core = lLib+lApp+lBack+lProc artifacts['corelib'] = core artifacts['support'] = lLib - artifacts['lumiera'] = env.LumieraExe('$TARGDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) + artifacts['lumiera'] = env.Program('$TARGDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) # building Lumiera Plugins envPlu = env.Clone() @@ -368,7 +368,7 @@ def defineBuildTargets(env, artifacts): envGtk.Append(CPPDEFINES='LUMIERA_PLUGIN', LIBS=core) objgui = srcSubtree(envGtk,'$SRCDIR/gui') - guimodule = envGtk.LoadableModule('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') + guimodule = envGtk.LumieraPlugin('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') artifacts['gui'] = ( guimodule + env.Install('$TARGDIR', env.Glob('$SRCDIR/gui/*.rc')) + artifacts['icons'] @@ -441,8 +441,6 @@ 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) defineBuildTargets(env, artifacts) diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index b7d406ed8..4e3a590f4 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -109,65 +109,6 @@ class LumieraEnvironment(Environment): action = Action(makeLink,reportLink) self.Command (target,source, action) - - def defineSoname (self, *args,**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: - if len(args) > 0: - pathname = args[0] - elif 'target' in kw: - pathname = kw['target'] - else: - raise SyntaxError("Library builder requires target spec. Arguments: %s %s" % (args,kw)) - (dirprefix, libname) = path.split(pathname) - if not libname: - raise ValueError("Library name missing. Only got a directory: "+pathname) - - libname = "${SHLIBPREFIX}%s$SHLIBSUFFIX" % libname - soname = self.subst(libname) # else: use the library filename as DT_SONAME - assert soname - return soname - - - def LumieraLibrary (self, *args,**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 - """ - subEnv = self.Clone() - subEnv.Append(LINKFLAGS = "-Wl,-soname="+self.defineSoname(*args,**kw)) - - libBuilder = self.get_builder('SharedLibrary') - return libBuilder(subEnv, *args,**kw); # invoke the predefined builder on the augmented environment - - - def LumieraPlugin (self, *args,**kw): - """ builds a shared library, autmented by some defaults for lumiera plugins. - """ - subEnv = self.Clone() - subEnv.Append(LINKFLAGS = "-Wl,-soname="+self.defineSoname(*args,**kw)) - - libBuilder = self.get_builder('LoadableModule') - return libBuilder(subEnv, *args,**kw); # invoke the predefined builder on the augmented environment - - - def LumieraExe (self, *args,**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 - """ - subEnv = self.Clone() - subEnv.Append( LINKFLAGS = "-Wl,-rpath=\\$$ORIGIN/$MODULES,--enable-new-dtags" ) - - programBuilder = self.get_builder('Program') - return programBuilder (subEnv, *args,**kw); @@ -317,7 +258,9 @@ def register_LumieraCustomBuilders (lumiEnv): programBuilder = LumieraExeBuilder (programBuilder) libraryBuilder = LumieraModuleBuilder (libraryBuilder) smoduleBuilder = LumieraModuleBuilder (smoduleBuilder) + lpluginBuilder = LumieraModuleBuilder (smoduleBuilder) lumiEnv['BUILDERS']['Program'] = programBuilder lumiEnv['BUILDERS']['SharedLibrary'] = libraryBuilder lumiEnv['BUILDERS']['LoadableModule'] = smoduleBuilder + lumiEnv['BUILDERS']['LumieraPlugin'] = lpluginBuilder \ No newline at end of file diff --git a/src/tool/SConscript b/src/tool/SConscript index bab7e6497..e1ca2394b 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.LumieraExe('#$TARGDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs -rsvg = envSvg.LumieraExe('#$TARGDIR/rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) +luidgen = env.Program('#$TARGDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs +rsvg = envSvg.Program('#$TARGDIR/rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) # build additional test and administrative tools.... -artifacts['tools'] = [ env.LumieraExe('#$TARGDIR/hello-world','hello.c') #### hello world (checks C build) - + env.LumieraExe('#$TARGDIR/try', 'try.cpp') #### to try out some feature... +artifacts['tools'] = [ env.Program('#$TARGDIR/hello-world','hello.c') #### hello world (checks C build) + + env.Program('#$TARGDIR/try', 'try.cpp') #### to try out some feature... # + luidgen + rsvg ] diff --git a/tests/SConscript b/tests/SConscript index a3c4d8a82..f9079f404 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -35,7 +35,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.LumieraExe('#$TARGDIR/'+exeName, obj + core) + return env.Program('#$TARGDIR/'+exeName, obj + core) def testCollection(env,dir): @@ -44,7 +44,7 @@ def testCollection(env,dir): """ srcpatt = ['test-*.c'] exeName = lambda p: path.basename(path.splitext(p)[0]) - buildIt = lambda p: env.LumieraExe("#$TARGDIR/"+exeName(p), [p] + core) + buildIt = lambda p: env.Program("#$TARGDIR/"+exeName(p), [p] + core) return [buildIt(f) for f in scanSubtree(dir,srcpatt)] @@ -67,7 +67,7 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] # for creating a Valgrind-Suppression file -vgsuppr = env.LumieraExe('#$TARGDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms +vgsuppr = env.Program('#$TARGDIR/vgsuppression','tool/vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms artifacts['tools'] += [vgsuppr] Depends(ts,vgsuppr) From abf1bc776b21f87fc0682adc1ec3efa97b13c4e6 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 30 Jan 2011 18:56:51 +0100 Subject: [PATCH 24/32] SCons: remove all explicit target and install specifications now superfluous, because our custom builder handles that automatically --- SConstruct | 33 ++++++------- admin/scons/Buildhelper.py | 6 +-- admin/scons/LumieraEnvironment.py | 80 ++++++++++++++++++++++++------- src/tool/SConscript | 8 ++-- tests/SConscript | 6 +-- 5 files changed, 86 insertions(+), 47 deletions(-) diff --git a/SConstruct b/SConstruct index 4cceb8331..011fc6996 100644 --- a/SConstruct +++ b/SConstruct @@ -38,10 +38,12 @@ LIBDIR = 'target/modules' ####### buildExe = '#$TARGDIR' buildLib = '#$TARGDIR/modules' +buildPlug = '#$TARGDIR/modules' buildIcon = '#$TARGDIR/icons' buildConf = '#$TARGDIR/config' installExe = '#$DESTDIR/lib/lumiera' installLib = '#$DESTDIR/lib/lumiera/modules' +installPlug = '#$DESTDIR/lib/lumiera/modules' installIcon = '#$DESTDIR/share/lumiera/icons' installConf = '#$DESTDIR/share/lumiera/config' @@ -338,16 +340,16 @@ def defineBuildTargets(env, artifacts): - lLib = env.SharedLibrary('$LIBDIR/lumiera', srcSubtree(env,'$SRCDIR/lib')) - lApp = env.SharedLibrary('$LIBDIR/lumieracommon', srcSubtree(env,'$SRCDIR/common'), LIBS=lLib) - lBack = env.SharedLibrary('$LIBDIR/lumierabackend', srcSubtree(env,'$SRCDIR/backend')) - lProc = env.SharedLibrary('$LIBDIR/lumieraproc', srcSubtree(env,'$SRCDIR/proc')) + lLib = env.SharedLibrary('lumiera', srcSubtree(env,'$SRCDIR/lib'), install=True) + lApp = env.SharedLibrary('lumieracommon', srcSubtree(env,'$SRCDIR/common'), install=True, LIBS=lLib) + lBack = env.SharedLibrary('lumierabackend', srcSubtree(env,'$SRCDIR/backend'),install=True) + lProc = env.SharedLibrary('lumieraproc', srcSubtree(env,'$SRCDIR/proc'), install=True) core = lLib+lApp+lBack+lProc artifacts['corelib'] = core artifacts['support'] = lLib - artifacts['lumiera'] = env.Program('$TARGDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) + artifacts['lumiera'] = env.Program('lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core, install=True) # building Lumiera Plugins envPlu = env.Clone() @@ -365,10 +367,10 @@ def defineBuildTargets(env, artifacts): # 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.LumieraPlugin('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') + guimodule = envGtk.LumieraPlugin('gtk_gui', objgui, install=True) artifacts['gui'] = ( guimodule + env.Install('$TARGDIR', env.Glob('$SRCDIR/gui/*.rc')) + artifacts['icons'] @@ -404,20 +406,13 @@ def definePostBuildTargets(env, artifacts): def defineInstallTargets(env, artifacts): - """ define 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 """ - binDir = '$DESTDIR/bin/' - lumDir = '$DESTDIR/lib/lumiera/' - modDir = '$DESTDIR/lib/lumiera/$MODULES/' - shaDir = '$DESTDIR/share/lumiera/' - env.Install(dir = modDir, source=artifacts['corelib']) - env.Install(dir = modDir, source=artifacts['plugins']) - env.Install(dir = modDir, source=artifacts['guimodule']) - lumi = env.Install(dir = lumDir, source=artifacts['lumiera']) - tool = env.Install(dir = lumDir, source=artifacts['tools']) - env.SymLink(binDir+"lumiera",lumi,"../lib/lumiera/lumiera") + env.SymLink('$DESTDIR/bin/lumiera',env.path.installExe+'lumiera',"../lib/lumiera/lumiera") - env.Install(dir = shaDir, source="data/config/dummy_lumiera.ini") ### TODO should become a resource builder + env.Install(dir = env.path.installConf, source="data/config/dummy_lumiera.ini") ### TODO should become a resource builder # env.Install(dir = '$DESTDIR/share/doc/lumiera$VERSION/devel', source=artifacts['doxydoc']) ##################################################################### diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index 387e0fccb..f491f03a0 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -148,13 +148,13 @@ def getDirname(dir): -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.LumieraPlugin( '#$TARGDIR/$MODULES/%s' % getDirname(tree) + return [env.LumieraPlugin( getDirname(tree) , srcSubtree(env, tree) - , SHLIBPREFIX='', SHLIBSUFFIX='.lum' + , **kw ) for tree in findSrcTrees(dir) ] diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index 4e3a590f4..b32f1af1f 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -43,7 +43,7 @@ class LumieraEnvironment(Environment): self.path = Record (pathConfig) self.libInfo = {} self.Tool("BuilderGCH") - self.Tool("BuilderDoxygen") + self.Tool("BuilderDoxygen") self.Tool("ToolDistCC") self.Tool("ToolCCache") RegisterIcon_Builder(self) @@ -108,7 +108,6 @@ class LumieraEnvironment(Environment): action = Action(makeLink,reportLink) self.Command (target,source, action) - @@ -133,7 +132,8 @@ class LumieraConfigContext(ConfigBase): -###### Lumiera custom tools and builders ######################## +############################################################################### +####### Lumiera custom tools and builders ##################################### def RegisterIcon_Builder(env): @@ -163,12 +163,12 @@ def RegisterIcon_Builder(env): subdir = getDirname(source) return env.Install("$TARGDIR/%s" % subdir, source) - + buildIcon = env.Builder( action = Action(invokeRenderer, "rendering Icon: $SOURCE --> $TARGETS") , single_source = True - , emitter = createIconTargets + , emitter = createIconTargets ) - env.Append(BUILDERS = {'IconRender' : buildIcon}) + env.Append(BUILDERS = {'IconRender' : buildIcon}) env.AddMethod(IconCopy) @@ -190,7 +190,31 @@ class WrappedStandardExeBuilder(SCons.Util.Proxy): and then pass on the call to the wrapped original builder """ customisedEnv = self.getCustomEnvironment(env, target=target, **kw) # defined in subclasses - return self.get().__call__ (customisedEnv, target, source, **kw) + buildTarget = self.buildLocation(customisedEnv, target) + buildTarget = self.invokeOriginalBuilder (customisedEnv, buildTarget, source, **kw) + return buildTarget + self.installTarget(customisedEnv, buildTarget, **kw) + + + 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): @@ -207,6 +231,11 @@ class LumieraExeBuilder(WrappedStandardExeBuilder): 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): @@ -219,6 +248,9 @@ class LumieraModuleBuilder(WrappedStandardExeBuilder): 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 @@ -246,21 +278,33 @@ class LumieraModuleBuilder(WrappedStandardExeBuilder): 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 = lumiEnv['BUILDERS']['Program'] - libraryBuilder = lumiEnv['BUILDERS']['SharedLibrary'] - smoduleBuilder = lumiEnv['BUILDERS']['LoadableModule'] + programBuilder = LumieraExeBuilder (lumiEnv['BUILDERS']['Program']) + libraryBuilder = LumieraModuleBuilder (lumiEnv['BUILDERS']['SharedLibrary']) + smoduleBuilder = LumieraModuleBuilder (lumiEnv['BUILDERS']['LoadableModule']) + lpluginBuilder = LumieraPluginBuilder (lumiEnv['BUILDERS']['LoadableModule']) - programBuilder = LumieraExeBuilder (programBuilder) - libraryBuilder = LumieraModuleBuilder (libraryBuilder) - smoduleBuilder = LumieraModuleBuilder (smoduleBuilder) - lpluginBuilder = LumieraModuleBuilder (smoduleBuilder) - - lumiEnv['BUILDERS']['Program'] = programBuilder lumiEnv['BUILDERS']['SharedLibrary'] = libraryBuilder lumiEnv['BUILDERS']['LoadableModule'] = smoduleBuilder + lumiEnv['BUILDERS']['Program'] = programBuilder + lumiEnv['BUILDERS']['SharedLibrary'] = libraryBuilder + lumiEnv['BUILDERS']['LoadableModule'] = smoduleBuilder lumiEnv['BUILDERS']['LumieraPlugin'] = lpluginBuilder - - \ No newline at end of file diff --git a/src/tool/SConscript b/src/tool/SConscript index e1ca2394b..4fe3a17c4 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('#$TARGDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for generating Lumiera-UIDs -rsvg = envSvg.Program('#$TARGDIR/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('#$TARGDIR/hello-world','hello.c') #### hello world (checks C build) - + env.Program('#$TARGDIR/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') #### to try out some feature... # + luidgen + rsvg ] diff --git a/tests/SConscript b/tests/SConscript index f9079f404..ac00d1f13 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -35,7 +35,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('#$TARGDIR/'+exeName, obj + core) + return env.Program(exeName, obj + core) def testCollection(env,dir): @@ -44,7 +44,7 @@ def testCollection(env,dir): """ srcpatt = ['test-*.c'] exeName = lambda p: path.basename(path.splitext(p)[0]) - buildIt = lambda p: env.Program("#$TARGDIR/"+exeName(p), [p] + core) + buildIt = lambda p: env.Program(exeName(p), [p] + core) return [buildIt(f) for f in scanSubtree(dir,srcpatt)] @@ -67,7 +67,7 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] # for creating a Valgrind-Suppression file -vgsuppr = env.Program('#$TARGDIR/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) From daef6c767625fa1ddd93db2f76a413688593a406 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 30 Jan 2011 19:20:02 +0100 Subject: [PATCH 25/32] SCons: remove unnecessary indirections $SRCDIR, $MODULES, $ICONDIR etc these don't create real flexibility and make definitions less readable --- SConstruct | 58 +++++++++++++------------------ admin/scons/Buildhelper.py | 2 +- admin/scons/LumieraEnvironment.py | 2 +- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/SConstruct b/SConstruct index 011fc6996..ae291d2d3 100644 --- a/SConstruct +++ b/SConstruct @@ -29,13 +29,9 @@ TOOLDIR = './admin/scons' SCRIPTDIR = './admin' OPTCACHE = 'optcache' CUSTOPTFILE = 'custom-options' -####### -SRCDIR = 'src' -TESTDIR = 'tests' -ICONDIR = 'icons' -MODULES = 'modules' -LIBDIR = 'target/modules' -####### + +srcIcon = 'icons' +srcConf = 'data/config' buildExe = '#$TARGDIR' buildLib = '#$TARGDIR/modules' buildPlug = '#$TARGDIR/modules' @@ -89,11 +85,7 @@ def setupBasicEnvironment(localDefinitions): env.Append ( CCCOM=' -std=gnu99') env.Append ( SHCCCOM=' -std=gnu99') # workaround for a bug: CCCOM currently doesn't honour CFLAGS, only CCFLAGS - env.Replace( SRCDIR=SRCDIR - , LIBDIR=LIBDIR - , MODULES=MODULES - , 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' @@ -108,8 +100,8 @@ def setupBasicEnvironment(localDefinitions): appendVal(env,'DEBUG', 'CCFLAGS', val=' -ggdb') # setup search path for Lumiera plugins - appendCppDefine(env,'PKGLIBDIR','LUMIERA_PLUGIN_PATH=\\"$PKGLIBDIR/:./$MODULES\\"' - ,'LUMIERA_PLUGIN_PATH=\\"$DESTDIR/lib/lumiera/:./$MODULES\\"') + appendCppDefine(env,'PKGLIBDIR','LUMIERA_PLUGIN_PATH=\\"$PKGLIBDIR/:./modules\\"' + ,'LUMIERA_PLUGIN_PATH=\\"$DESTDIR/lib/lumiera/:./modules\\"') appendCppDefine(env,'PKGDATADIR','LUMIERA_CONFIG_PATH=\\"$PKGLIBDIR/:.\\"' ,'LUMIERA_CONFIG_PATH=\\"$DESTDIR/share/lumiera/:.\\"') @@ -198,10 +190,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: """ @@ -334,22 +324,22 @@ 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') # ) - lLib = env.SharedLibrary('lumiera', srcSubtree(env,'$SRCDIR/lib'), install=True) - lApp = env.SharedLibrary('lumieracommon', srcSubtree(env,'$SRCDIR/common'), install=True, LIBS=lLib) - lBack = env.SharedLibrary('lumierabackend', srcSubtree(env,'$SRCDIR/backend'),install=True) - lProc = env.SharedLibrary('lumieraproc', srcSubtree(env,'$SRCDIR/proc'), install=True) + 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['corelib'] = core artifacts['support'] = lLib - artifacts['lumiera'] = env.Program('lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core, install=True) + artifacts['lumiera'] = env.Program('lumiera', ['src/lumiera/main.cpp'], LIBS=core, install=True) # building Lumiera Plugins envPlu = env.Clone() @@ -357,8 +347,8 @@ def defineBuildTargets(env, artifacts): artifacts['plugins'] = [] # currently none # render and install Icons - vector_icon_dir = env.subst('$ICONDIR/svg') - prerendered_icon_dir = env.subst('$ICONDIR/prerendered') + vector_icon_dir = env.path.srcIcon+'svg' + prerendered_icon_dir = env.path.srcIcon+'prerendered' artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])] + [env.IconCopy(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])] ) @@ -369,17 +359,17 @@ def defineBuildTargets(env, artifacts): envGtk.mergeConf(['gtkmm-2.4','gthread-2.0','cairomm-1.0','gdl','xv','xext','sm']) envGtk.Append(LIBS=core) - objgui = srcSubtree(envGtk,'$SRCDIR/gui') + objgui = srcSubtree(envGtk,'src/gui') guimodule = envGtk.LumieraPlugin('gtk_gui', objgui, install=True) artifacts['gui'] = ( guimodule - + env.Install('$TARGDIR', env.Glob('$SRCDIR/gui/*.rc')) + + env.Install('$TARGDIR', env.Glob('src/gui/*.rc')) + artifacts['icons'] ) artifacts['guimodule'] = guimodule ###TODO better organisation of GUI components # call subdir SConscript(s) for independent components - SConscript(dirs=[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 envPlu artifacts core') @@ -396,13 +386,13 @@ def definePostBuildTargets(env, artifacts): env.Default('build') # additional files to be cleaned when cleaning 'build' env.Clean ('build', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log' ]) - env.Clean ('build', [ '$SRCDIR/pre.gch' ]) + 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']) - allbu = env.Alias('allbuild', build+artifacts['testsuite']+doxydoc) + allbu = env.Alias('all', build+artifacts['testsuite']+doxydoc) def defineInstallTargets(env, artifacts): @@ -410,9 +400,9 @@ def defineInstallTargets(env, artifacts): @note: we use customised SCons builders defining install targets for all executables automatically. see LumieraEnvironment.py """ - env.SymLink('$DESTDIR/bin/lumiera',env.path.installExe+'lumiera',"../lib/lumiera/lumiera") + env.SymLink('$DESTDIR/bin/lumiera',env.path.installExe+'lumiera','../lib/lumiera/lumiera') - env.Install(dir = env.path.installConf, source="data/config/dummy_lumiera.ini") ### TODO should become a resource builder + env.Install(dir = env.path.installConf, source=env.path.srcConf+'dummy_lumiera.ini') ### TODO should become a resource builder # env.Install(dir = '$DESTDIR/share/doc/lumiera$VERSION/devel', source=artifacts['doxydoc']) ##################################################################### diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index f491f03a0..2c5156863 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -227,7 +227,7 @@ def extract_localPathDefs (localDefs): """ def relevantPathDefs (mapping): for (k,v) in mapping.items(): - if k.startswith('build') or k.startswith('install') and Util.is_String(v): + 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) diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index b32f1af1f..c4bf30172 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -229,7 +229,7 @@ class LumieraExeBuilder(WrappedStandardExeBuilder): which results in LD_LIBRARY_PATH being searched *before* the RPATH """ custEnv = lumiEnv.Clone() - custEnv.Append( LINKFLAGS = "-Wl,-rpath=\\$$ORIGIN/$MODULES,--enable-new-dtags" ) + custEnv.Append( LINKFLAGS = "-Wl,-rpath=\\$$ORIGIN/modules,--enable-new-dtags" ) return custEnv def getBuildDestination(self, lumiEnv): return lumiEnv.path.buildExe From 9cb03c7015352ddce33dbcb26529fe2bc1ffacb3 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 30 Jan 2011 19:43:51 +0100 Subject: [PATCH 26/32] Fix installation triggered already by build target --- SConstruct | 7 ++----- admin/scons/LumieraEnvironment.py | 9 ++++++--- tests/SConscript | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/SConstruct b/SConstruct index ae291d2d3..95797748d 100644 --- a/SConstruct +++ b/SConstruct @@ -377,11 +377,6 @@ 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') - id = env.Alias('install-dat', '$DESTDIR/share') - env.Alias('install', [ib, il, id]) - build = env.Alias('build', artifacts['lumiera']+artifacts['gui']+artifacts['plugins']+artifacts['tools']) env.Default('build') # additional files to be cleaned when cleaning 'build' @@ -404,6 +399,8 @@ def defineInstallTargets(env, artifacts): env.Install(dir = env.path.installConf, source=env.path.srcConf+'dummy_lumiera.ini') ### TODO should become a resource builder # env.Install(dir = '$DESTDIR/share/doc/lumiera$VERSION/devel', source=artifacts['doxydoc']) + + env.Alias('install', '$DESTDIR') ##################################################################### diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index c4bf30172..12f5dbcc7 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -187,12 +187,15 @@ class WrappedStandardExeBuilder(SCons.Util.Proxy): 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 + 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) - return buildTarget + self.installTarget(customisedEnv, buildTarget, **kw) + buildTarget = self.invokeOriginalBuilder (customisedEnv, buildTarget, source, **kw) + self.installTarget(customisedEnv, buildTarget, **kw) + return buildTarget def invokeOriginalBuilder(self, env, target, source, **kw): diff --git a/tests/SConscript b/tests/SConscript index ac00d1f13..cc6078878 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -23,8 +23,8 @@ envPlu.Append(CPPPATH='#/.') 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 From d9f90c2c0419cc6ff01f38c8652d58d83ab38eab Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 30 Jan 2011 22:12:55 +0100 Subject: [PATCH 27/32] SCons: finish reworking buildsystem to rely on custom builders. All target paths and install targets now defined automatically, most of the buildscript just using plain sourcefile names --- SConstruct | 67 ++++++++++++----------- admin/scons/Buildhelper.py | 15 ++++-- admin/scons/LumieraEnvironment.py | 90 ++++++++++++++++++++----------- tests/SConscript | 6 +-- 4 files changed, 108 insertions(+), 70 deletions(-) diff --git a/SConstruct b/SConstruct index 95797748d..6eadc765b 100644 --- a/SConstruct +++ b/SConstruct @@ -22,35 +22,39 @@ ##################################################################### +# NOTE: scons -h for help. +# Read more about the SCons build system at: http://www.scons.org +# Basically, this script just /defines/ the components and how they +# fit together. SCons will derive the necessary build steps. + + #-----------------------------------Configuration TARGDIR = 'target' VERSION = '0.1+pre.01' -TOOLDIR = './admin/scons' +TOOLDIR = './admin/scons' # SCons plugins SCRIPTDIR = './admin' OPTCACHE = 'optcache' CUSTOPTFILE = 'custom-options' +# these are accessible via env.path.xxxx srcIcon = 'icons' srcConf = 'data/config' buildExe = '#$TARGDIR' buildLib = '#$TARGDIR/modules' buildPlug = '#$TARGDIR/modules' buildIcon = '#$TARGDIR/icons' +buildUIRes = '#$TARGDIR/' buildConf = '#$TARGDIR/config' installExe = '#$DESTDIR/lib/lumiera' installLib = '#$DESTDIR/lib/lumiera/modules' installPlug = '#$DESTDIR/lib/lumiera/modules' installIcon = '#$DESTDIR/share/lumiera/icons' -installConf = '#$DESTDIR/share/lumiera/config' +installUIRes = '#$DESTDIR/share/lumiera/' +installConf = '#$DESTDIR/lib/lumiera/config' localDefinitions = locals() #-----------------------------------Configuration -# NOTE: scons -h for help. -# Read more about the SCons build system at: http://www.scons.org -# Basically, this script just /defines/ the components and how they -# fit together. SCons will derive the necessary build steps. - import os @@ -76,7 +80,7 @@ def setupBasicEnvironment(localDefinitions): vars = defineCmdlineVariables() env = LumieraEnvironment(variables=vars ,toolpath = [TOOLDIR] - ,pathConfig = extract_localPathDefs(localDefinitions) + ,pathConfig = extract_localPathDefs(localDefinitions) # e.g. buildExe -> env.path.buildExe ,TARGDIR = TARGDIR ,DESTDIR = '$INSTALLDIR/$PREFIX' ,VERSION = VERSION @@ -239,10 +243,10 @@ def configurePlatform(env): conf.env.mergeConf('nobugmt') if not conf.CheckCXXHeader('tr1/memory'): - problems.append('We rely on the std::tr1 proposed standard extension for shared_ptr.') + problems.append('We rely on the std::tr1 standard C++ extension for shared_ptr.') if not conf.CheckCXXHeader('boost/config.hpp'): - problems.append('We need the C++ boost-lib.') + problems.append('We need the C++ boost-libraries.') else: if not conf.CheckCXXHeader('boost/shared_ptr.hpp'): problems.append('We need boost::shared_ptr (shared_ptr.hpp).') @@ -264,16 +268,16 @@ def configurePlatform(env): conf.env.mergeConf('gavl') if not conf.CheckPkgConfig('gtkmm-2.4', 2.8): - problems.append('Unable to configure GTK--, exiting.') + problems.append('Unable to configure GTK--') if not conf.CheckPkgConfig('glibmm-2.4', '2.16'): - problems.append('Unable to configure Lib glib--, exiting.') + problems.append('Unable to configure Lib glib--') if not conf.CheckPkgConfig('gthread-2.0', '2.12.4'): problems.append('Need gthread support lib for glib-- based thread handling.') if not conf.CheckPkgConfig('cairomm-1.0', 0.6): - problems.append('Unable to configure Cairo--, exiting.') + problems.append('Unable to configure Cairo--') verGDL = '2.27.1' if not conf.CheckPkgConfig('gdl-lum', verGDL, alias='gdl'): @@ -309,7 +313,7 @@ def configurePlatform(env): -def definePackagingTargets(env, artifacts): +def defineSetupTargets(env, artifacts): """ build operations and targets to be done /before/ compiling. things like creating a source tarball or preparing a version header. """ @@ -339,20 +343,19 @@ def defineBuildTargets(env, artifacts): artifacts['corelib'] = core artifacts['support'] = lLib - artifacts['lumiera'] = env.Program('lumiera', ['src/lumiera/main.cpp'], LIBS=core, install=True) + artifacts['lumiera'] = ( env.Program('lumiera', ['src/lumiera/main.cpp'], LIBS=core, install=True) + + env.ConfigData(env.path.srcConf+'dummy_lumiera.ini') + ) # building Lumiera Plugins - envPlu = env.Clone() - envPlu.Append(CPPDEFINES='LUMIERA_PLUGIN') artifacts['plugins'] = [] # currently none # render and install Icons vector_icon_dir = env.path.srcIcon+'svg' prerendered_icon_dir = env.path.srcIcon+'prerendered' - artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])] - + [env.IconCopy(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])] + artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])] + + [env.IconResource(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])] ) - ##TODO make that into a resource builder # the Lumiera GTK GUI envGtk = env.Clone() @@ -362,14 +365,13 @@ def defineBuildTargets(env, artifacts): objgui = srcSubtree(envGtk,'src/gui') guimodule = envGtk.LumieraPlugin('gtk_gui', objgui, install=True) artifacts['gui'] = ( guimodule - + env.Install('$TARGDIR', env.Glob('src/gui/*.rc')) + + [env.GuiResource(f) for f in env.Glob('src/gui/*.rc')] + artifacts['icons'] ) - artifacts['guimodule'] = guimodule ###TODO better organisation of GUI components - + # call subdir SConscript(s) for independent components - SConscript(dirs=['src/tool'], exports='env artifacts core') - SConscript(dirs=['tests'], exports='env envPlu artifacts core') + SConscript(dirs=['src/tool'], exports='env artifacts core') + SConscript(dirs=['tests'], exports='env artifacts core') @@ -377,8 +379,11 @@ def definePostBuildTargets(env, artifacts): """ define further actions after the core build (e.g. Documentaion). define alias targets to trigger the installing. """ - build = env.Alias('build', artifacts['lumiera']+artifacts['gui']+artifacts['plugins']+artifacts['tools']) - env.Default('build') + build = env.Alias('build', ( artifacts['lumiera'] + + artifacts['plugins'] + + artifacts['tools'] + + artifacts['gui'] + )) # additional files to be cleaned when cleaning 'build' env.Clean ('build', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log' ]) env.Clean ('build', [ 'src/pre.gch' ]) @@ -387,7 +392,9 @@ def definePostBuildTargets(env, artifacts): env.Alias ('doc', doxydoc) env.Clean ('doc', doxydoc + ['doc/devel/,doxylog','doc/devel/warnings.txt']) - allbu = env.Alias('all', build+artifacts['testsuite']+doxydoc) + env.Alias ('all', build+artifacts['testsuite']+doxydoc) + env.Default('build') + # SCons default target def defineInstallTargets(env, artifacts): @@ -396,8 +403,6 @@ def defineInstallTargets(env, artifacts): for all executables automatically. see LumieraEnvironment.py """ env.SymLink('$DESTDIR/bin/lumiera',env.path.installExe+'lumiera','../lib/lumiera/lumiera') - - env.Install(dir = env.path.installConf, source=env.path.srcConf+'dummy_lumiera.ini') ### TODO should become a resource builder # env.Install(dir = '$DESTDIR/share/doc/lumiera$VERSION/devel', source=artifacts['doxydoc']) env.Alias('install', '$DESTDIR') @@ -424,7 +429,7 @@ artifacts = {} # 'plugins' : plugin shared lib # 'tools' : small tool applications (e.g mpegtoc) -definePackagingTargets(env, artifacts) +defineSetupTargets(env, artifacts) defineBuildTargets(env, artifacts) definePostBuildTargets(env, artifacts) defineInstallTargets(env, artifacts) diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index 2c5156863..aed9c07da 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -99,7 +99,7 @@ def findSrcTrees(location, patterns=SRCPATTERNS): After having initially expanded the given location with #globRootdirs, each directory is examined depth first, until encountering a directory containing source files, which then yields a result. Especially, this can be used to traverse - an organisational directory structure and find out all possible source trees of + an organisational directory structure and find out all possible source trees to be built into packages, plugins, individual tool executables etc. @return: the relative path names of all source root dirs found (generator function). """ @@ -138,12 +138,19 @@ def filterNodes(nlist, removeName=None): -def getDirname(dir): - """ extract directory name without leading path """ +def getDirname(dir, basePrefix=None): + """ extract directory name without leading path, + or without the explicitly given basePrefix + """ dir = os.path.realpath(dir) if not os.path.isdir(dir): dir,_ = os.path.split(dir) - _, name = os.path.split(dir) + if basePrefix: + basePrefix = os.path.realpath(basePrefix) + if str(dir).startswith(basePrefix): + name = str(dir)[len(basePrefix):] + else: + _, name = os.path.split(dir) return name diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index 12f5dbcc7..82a89b6ae 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -46,7 +46,7 @@ class LumieraEnvironment(Environment): self.Tool("BuilderDoxygen") self.Tool("ToolDistCC") self.Tool("ToolCCache") - RegisterIcon_Builder(self) + register_LumieraResourceBuilder(self) register_LumieraCustomBuilders(self) def Configure (self, *args, **kw): @@ -89,25 +89,6 @@ class LumieraEnvironment(Environment): if alias: self.libInfo[alias] = libInfo return libInfo - - - def SymLink(self, target, source, linktext=None): - """ use python to create a symlink - """ - def makeLink(target,source,env): - if linktext: - dest = linktext - else: - dest = str(source[0]) - link = str(target[0]) - os.symlink(dest, link) - def reportLink(target,source,env): - dest = str(source[0]) - link = str(target[0]) - return "Install link %s -> %s" % (link,dest) - - action = Action(makeLink,reportLink) - self.Command (target,source, action) @@ -136,7 +117,7 @@ class LumieraConfigContext(ConfigBase): ####### Lumiera custom tools and builders ##################################### -def RegisterIcon_Builder(env): +def register_LumieraResourceBuilder(env): """ Registers Custom Builders for generating and installing Icons. Additionally you need to build the tool (rsvg-convert.c) used to generate png from the svg source using librsvg. @@ -147,21 +128,39 @@ def RegisterIcon_Builder(env): def invokeRenderer(target, source, env): source = str(source[0]) - targetdir = env.subst("$TARGDIR") + targetdir = env.subst(env.path.buildIcon) + if targetdir.startswith('#'): targetdir = targetdir[1:] renderer.main([source,targetdir]) return 0 def createIconTargets(target,source,env): """ parse the SVG to get the target file names """ source = str(source[0]) - targetdir = os.path.basename(str(target[0])) + targetdir = env.path.buildIcon targetfiles = renderer.getTargetNames(source) # parse SVG - return (["$TARGDIR/%s" % name for name in targetfiles], source) + return ([targetdir+name for name in targetfiles], source) - def IconCopy(env, source): - """Copy icon to corresponding icon dir. """ - subdir = getDirname(source) - return env.Install("$TARGDIR/%s" % subdir, source) + def IconResource(env, source): + """Copy icon pixmap to corresponding icon dir. """ + subdir = getDirname(str(source)) + toBuild = env.path.buildIcon+subdir + toInstall = env.path.installIcon+subdir + env.Install (toInstall, source) + return env.Install(toBuild, source) + + def GuiResource(env, source): + subdir = getDirname(str(source)) + toBuild = env.path.buildUIRes+subdir + toInstall = env.path.installUIRes+subdir + env.Install (toInstall, source) + return env.Install(toBuild, source) + + def ConfigData(env, source): + subdir = getDirname(str(source), env.path.srcConf) # removes source location path prefix + toBuild = env.path.buildConf+subdir + toInstall = env.path.installConf+subdir + env.Install (toInstall, source) + return env.Install(toBuild, source) buildIcon = env.Builder( action = Action(invokeRenderer, "rendering Icon: $SOURCE --> $TARGETS") @@ -169,7 +168,9 @@ def RegisterIcon_Builder(env): , emitter = createIconTargets ) env.Append(BUILDERS = {'IconRender' : buildIcon}) - env.AddMethod(IconCopy) + env.AddMethod(IconResource) + env.AddMethod(GuiResource) + env.AddMethod(ConfigData) @@ -191,9 +192,9 @@ class WrappedStandardExeBuilder(SCons.Util.Proxy): Automatically define installation targets for build results. @note only returning the build targets, not the install targets """ - customisedEnv = self.getCustomEnvironment(env, target=target, **kw) # defined in subclasses + customisedEnv = self.getCustomEnvironment(env, target=target, **kw) # defined in subclasses buildTarget = self.buildLocation(customisedEnv, target) - buildTarget = self.invokeOriginalBuilder (customisedEnv, buildTarget, source, **kw) + buildTarget = self.invokeOriginalBuilder(customisedEnv, buildTarget, source, **kw) self.installTarget(customisedEnv, buildTarget, **kw) return buildTarget @@ -297,6 +298,9 @@ class LumieraPluginBuilder(LumieraModuleBuilder): + + + def register_LumieraCustomBuilders (lumiEnv): """ install the customised builder versions tightly integrated with our buildsystem. Especially, these builders automatically add the build and installation locations @@ -311,3 +315,27 @@ def register_LumieraCustomBuilders (lumiEnv): lumiEnv['BUILDERS']['SharedLibrary'] = libraryBuilder lumiEnv['BUILDERS']['LoadableModule'] = smoduleBuilder lumiEnv['BUILDERS']['LumieraPlugin'] = lpluginBuilder + + + def SymLink(env, target, source, linktext=None): + """ use python to create a symlink + """ + def makeLink(target,source,env): + if linktext: + dest = linktext + else: + dest = str(source[0]) + link = str(target[0]) + os.symlink(dest, link) + + if linktext: srcSpec=linktext + else: srcSpec='$SOURCE' + action = Action(makeLink, "Install link: $TARGET -> "+srcSpec) + env.Command (target,source, action) + + # adding SymLink direclty as method on the environment object + # Probably that should better be a real builder, but I couldn't figure out + # how to get the linktext through literally, which is necessary for relative links. + # Judging from the sourcecode of SCons.Builder.BuilderBase, there seems to be no way + # to set the executor_kw, which are passed through to the action object. + lumiEnv.AddMethod(SymLink) diff --git a/tests/SConscript b/tests/SConscript index cc6078878..2e7980c68 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -12,13 +12,11 @@ from Buildhelper import scanSubtree from Buildhelper import globRootdirs from Buildhelper import createPlugins -Import('env','envPlu','artifacts','core') +Import('env','artifacts','core') # temp fix to add test.h -- wouldn't it be better to put this header be into src/lib ? env = env.Clone() env.Append(CPPPATH='#/.') # add Rootdir to Includepath, so test/test.h is found -envPlu = envPlu.Clone() -envPlu.Append(CPPPATH='#/.') # temp fix------------- def testExecutable(env,tree, exeName=None, obj=None): @@ -59,7 +57,7 @@ moduledirs = globRootdirs('*') artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['bugs'] ] # was: ['lib','components'] + [ testCollection(env, dir) for dir in moduledirs if not dir in specials] - + createPlugins(envPlu, 'plugin') + + createPlugins(env, 'plugin') + env.File(glob('*.tests')) # depending on the test definition files for test.sh ) From 29e2233e6aed3f1bacbf21183c8c825341abf534 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 31 Jan 2011 05:35:43 +0100 Subject: [PATCH 28/32] an exercise: how to get the path of the current executable Note: this is a non-portable Linux solution --- src/tool/SConscript | 2 +- src/tool/try.cpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/tool/SConscript b/src/tool/SConscript index 4fe3a17c4..82b20d96f 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -17,7 +17,7 @@ rsvg = envSvg.Program('rsvg-convert','rsvg-convert.c') # build additional test and administrative tools.... artifacts['tools'] = [ env.Program('hello-world','hello.c', install=True) #### hello world (checks C build) - + env.Program('try', 'try.cpp') #### to try out some feature... + + 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 16ad0dad2..112aafaaa 100644 --- a/src/tool/try.cpp +++ b/src/tool/try.cpp @@ -15,15 +15,45 @@ // 6/09 - investigating how to build a mixin template providing an operator bool() // 12/9 - tracking down a strange "warning: type qualifiers ignored on function return type" // 1/10 - can we determine at compile time the presence of a certain function (for duck-typing)? +// 1/11 - how to fetch the path of the own executable -- at least under Linux? #include "include/nobugcfg.h" #include +#include + +extern "C" { +#include +} +//#include "lib/error.hpp" +//#include "lib/symbol.hpp" using std::string; using std::cout; +//using lib::Literal; +//using lib::STRING_MAX_RELEVANT; +const size_t STRING_MAX_RELEVANT = 1000; + +//namespace error = lumiera::error; + +//Literal GET_PATH_TO_EXECUTABLE ("/proc/self/exe"); +const char * const GET_PATH_TO_EXECUTABLE ("/proc/self/exe"); + +string +catchMyself () +{ + 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; +} int @@ -32,6 +62,7 @@ main (int, char**) //(int argc, char* argv[]) NOBUG_INIT; + cout << "\n\nich bin :" << catchMyself(); cout << "\n.gulp.\n"; return 0; From 208b5529556824127afcbe91de7870f77fb9209f Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 1 Feb 2011 05:10:45 +0100 Subject: [PATCH 29/32] Demonstration how the application could resolve the module loading location The real application likely will consult the configuration file to search alternative module installation locations. --- SConstruct | 12 +++-- src/common/dummy-func.cpp | 111 +++++++++++++++++++++++++++++++++----- src/common/dummy-func.hpp | 15 ++++++ 3 files changed, 122 insertions(+), 16 deletions(-) diff --git a/SConstruct b/SConstruct index 6eadc765b..c176dd6f3 100644 --- a/SConstruct +++ b/SConstruct @@ -104,8 +104,8 @@ def setupBasicEnvironment(localDefinitions): appendVal(env,'DEBUG', 'CCFLAGS', val=' -ggdb') # setup search path for Lumiera plugins - appendCppDefine(env,'PKGLIBDIR','LUMIERA_PLUGIN_PATH=\\"$PKGLIBDIR/:./modules\\"' - ,'LUMIERA_PLUGIN_PATH=\\"$DESTDIR/lib/lumiera/:./modules\\"') + 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/:.\\"') @@ -248,10 +248,14 @@ def configurePlatform(env): if not conf.CheckCXXHeader('boost/config.hpp'): 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).') diff --git a/src/common/dummy-func.cpp b/src/common/dummy-func.cpp index b6250ee75..3892e6737 100644 --- a/src/common/dummy-func.cpp +++ b/src/common/dummy-func.cpp @@ -1,42 +1,129 @@ /* - dummy-func.cpp - placeholder with dummy functions to demonstrate building shared modules + dummy-func.cpp - placeholder with dummy functions to demonstrate building/loading shared modules -* ******************************************************************************************/ +* *************************************************************************************************/ + + + +#ifndef LUMIERA_PLUGIN_PATH +#error please define the plugin search path as -DLUMIERA_PLUGIN_PATH, e.g. as $INSTALL_PREFIX/lib/lumiera +#endif #include "common/dummy-func.hpp" +extern "C" { +#include +} #include #include - - - +#include +#include +#include namespace lumiera { - - const char * const GUI_MODULE_NAME = "modules/gtk_gui.lum"; - typedef void (*VoidFunc)(void); + using std::string; + using boost::regex; + using boost::smatch; + using boost::regex_search; + + namespace fsys = boost::filesystem; + + namespace { // Implementation helpers + + const size_t STRING_MAX_RELEVANT = 1000; + + const char * const GUI_MODULE_TO_LOAD = "gtk_gui"; + const char * const GET_PATH_TO_EXECUTABLE = "/proc/self/exe"; + + regex EXTRACT_RELATIVE_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 () + { + 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)) + dieHard ("unable to discover path of running executable"); + + buff.resize(chars_read); + return buff; + } + + + /** extract from the PLUGIN_PATH a path specification + * given relative to the location of the executable, + * as denoted by the 'ORIGIN' token + */ + string + getRelativeModuleLocation() + { + smatch match; + if (regex_search (string(LUMIERA_PLUGIN_PATH), match, EXTRACT_RELATIVE_PATHSPEC)) + return (match[1]); + else + dieHard ("no valid module loading location relative to executable defined in LUMIERA_PLUGIN_PATH"); + } + }//(End) implementation helpers + + + + + void loadDummyGui() { - void* handle = dlopen (GUI_MODULE_NAME, RTLD_LAZY|RTLD_LOCAL); + string moduleLocation = resolveModulePath (GUI_MODULE_TO_LOAD); + + 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) - ERROR (lumiera, "unable to resolve the entry point symbol after loading the GUI module."); + dieHard ("unable to resolve the entry point symbol after loading the GUI module."); else - (*entryPoint) (); + (*entryPoint) (); // activate loaded module } else - ERROR (lumiera, "unable to load %s", GUI_MODULE_NAME); + dieHard ("unable to load "+moduleLocation); } + string + resolveModulePath (string moduleName) + { + fsys::path exePathName (catchMyself()); + fsys::path modPathName (exePathName.remove_leaf() / getRelativeModuleLocation() / (moduleName+".lum") ); + + if (!fsys::exists (modPathName)) + dieHard ("Module "+modPathName.string()+" doesn't exist."); + + INFO (config, "found module %s", modPathName.string().c_str()); + return modPathName.string(); + } + + + } // namespace lumiera diff --git a/src/common/dummy-func.hpp b/src/common/dummy-func.hpp index cbf3a96bb..dde394a6b 100644 --- a/src/common/dummy-func.hpp +++ b/src/common/dummy-func.hpp @@ -4,11 +4,18 @@ * ******************************************************************************************/ +#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 @@ -16,5 +23,13 @@ namespace lumiera { */ void loadDummyGui(); + /** 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); } // namespace lumiera +#endif From a42e6a5a8f803d9c47eec59197b3face6f96b4e8 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 3 Feb 2011 17:34:24 +0100 Subject: [PATCH 30/32] draft solution loading an INI file for module path resolution this would remove the need to compile any path into the EXE --- src/common/dummy-func.cpp | 176 +++++++++++++++++++++++++++++++++----- src/common/dummy-func.hpp | 9 +- 2 files changed, 154 insertions(+), 31 deletions(-) diff --git a/src/common/dummy-func.cpp b/src/common/dummy-func.cpp index 3892e6737..47250def3 100644 --- a/src/common/dummy-func.cpp +++ b/src/common/dummy-func.cpp @@ -17,28 +17,37 @@ extern "C" { } #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; namespace fsys = boost::filesystem; - + namespace opt = boost::program_options; + namespace { // Implementation helpers const size_t STRING_MAX_RELEVANT = 1000; - const char * const GUI_MODULE_TO_LOAD = "gtk_gui"; + const char * const BOOTSTRAP_INI = "$ORIGIN/setup.ini"; + const char * const GUI_MODULE_TO_LOAD = "gtk_gui.lum"; const char * const GET_PATH_TO_EXECUTABLE = "/proc/self/exe"; regex EXTRACT_RELATIVE_PATHSPEC ("\\$?ORIGIN/([^:]+)"); + regex EXTRACT_PATHSPEC ("(\\$?ORIGIN)?([^:]+)"); /** the real application would throw a custom exception... */ @@ -56,13 +65,16 @@ namespace lumiera { string catchMyself () { - 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)) - dieHard ("unable to discover path of running executable"); - - buff.resize(chars_read); + static string buff(STRING_MAX_RELEVANT+1, '\0' ); + if (!buff.size()) + { + 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; } @@ -80,6 +92,134 @@ namespace lumiera { else dieHard ("no valid module loading location relative to executable defined in LUMIERA_PLUGIN_PATH"); } + + class SearchPathSplitter + : boost::noncopyable + { + sregex_iterator pos_, + end_; + + public: + SearchPathSplitter (string searchPath) + : pos_(searchPath.begin(),searchPath.end(), EXTRACT_PATHSPEC) + , end_() + { } + + bool + hasNext() + { + return pos_ != end_; + } + + string + next() + { + ++pos_; + if (!hasNext()) + dieHard ("Search path exhausted."); + + return resolveRelative(); + } + + private: + /** maybe resolve a path spec given relative to + * the current Executable location ($ORIGIN) */ + string + resolveRelative () + { + if (containsORIGINToken()) + return asAbsolutePath(); + else + return getFullPath(); + } + + smatch::value_type 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 an existing directory"); + + return modPathName.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.hasNext()) + modulePathName = fsys::path() / searchLocation.next() / moduleName; + else + dieHard ("Module \""+moduleName+"\" not found" + + (searchPath.empty()? ".":" in search path: "+searchPath)); + } + } + + + + 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 (resolveModulePath (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(); + } + }; + }//(End) implementation helpers @@ -91,7 +231,10 @@ namespace lumiera { void loadDummyGui() { - string moduleLocation = resolveModulePath (GUI_MODULE_TO_LOAD); + 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) @@ -111,19 +254,6 @@ namespace lumiera { } - string - resolveModulePath (string moduleName) - { - fsys::path exePathName (catchMyself()); - fsys::path modPathName (exePathName.remove_leaf() / getRelativeModuleLocation() / (moduleName+".lum") ); - - if (!fsys::exists (modPathName)) - dieHard ("Module "+modPathName.string()+" doesn't exist."); - - INFO (config, "found module %s", modPathName.string().c_str()); - return modPathName.string(); - } - } // namespace lumiera diff --git a/src/common/dummy-func.hpp b/src/common/dummy-func.hpp index dde394a6b..d15383b88 100644 --- a/src/common/dummy-func.hpp +++ b/src/common/dummy-func.hpp @@ -19,17 +19,10 @@ namespace lumiera { /** 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 demonstarte that the SCons build system is working. + * is to demonstrate that the SCons build system is working. */ void loadDummyGui(); - /** 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); } // namespace lumiera #endif From babbe33d1d2190548ab3e5a36562837b6c98788b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 4 Feb 2011 16:10:59 +0100 Subject: [PATCH 31/32] Demonstration of complete bootstrap, loading INI and resolving GUI module path --- SConstruct | 1 + data/config/dummy_lumiera.ini | 8 +-- data/config/setup.ini | 20 ++++++++ src/common/dummy-func.cpp | 91 +++++++++++++++++++---------------- src/common/dummy-func.hpp | 11 +++++ 5 files changed, 86 insertions(+), 45 deletions(-) create mode 100644 data/config/setup.ini diff --git a/SConstruct b/SConstruct index c176dd6f3..99ee764bb 100644 --- a/SConstruct +++ b/SConstruct @@ -348,6 +348,7 @@ def defineBuildTargets(env, artifacts): 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') ) diff --git a/data/config/dummy_lumiera.ini b/data/config/dummy_lumiera.ini index cfe91da1e..a8408c41b 100644 --- a/data/config/dummy_lumiera.ini +++ b/data/config/dummy_lumiera.ini @@ -1,4 +1,4 @@ -/* This is an dummy Lumiera config file - * - * Actually Lumiera can't yet load any config, as of 1/2011 - */ +# 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/dummy-func.cpp b/src/common/dummy-func.cpp index 47250def3..e4ed350b2 100644 --- a/src/common/dummy-func.cpp +++ b/src/common/dummy-func.cpp @@ -5,10 +5,6 @@ -#ifndef LUMIERA_PLUGIN_PATH -#error please define the plugin search path as -DLUMIERA_PLUGIN_PATH, e.g. as $INSTALL_PREFIX/lib/lumiera -#endif - #include "common/dummy-func.hpp" @@ -35,19 +31,22 @@ namespace lumiera { 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/setup.ini"; - const char * const GUI_MODULE_TO_LOAD = "gtk_gui.lum"; + const char * const BOOTSTRAP_INI = "$ORIGIN/config/setup.ini"; const char * const GET_PATH_TO_EXECUTABLE = "/proc/self/exe"; - regex EXTRACT_RELATIVE_PATHSPEC ("\\$?ORIGIN/([^:]+)"); - regex EXTRACT_PATHSPEC ("(\\$?ORIGIN)?([^:]+)"); + regex EXTRACT_PATHSPEC ("(\\$?ORIGIN/)?([^:]+)"); /** the real application would throw a custom exception... */ @@ -66,7 +65,7 @@ namespace lumiera { catchMyself () { static string buff(STRING_MAX_RELEVANT+1, '\0' ); - if (!buff.size()) + if (!buff[0]) { ssize_t chars_read = readlink (GET_PATH_TO_EXECUTABLE, &buff[0], STRING_MAX_RELEVANT); @@ -79,20 +78,16 @@ namespace lumiera { } - /** extract from the PLUGIN_PATH a path specification - * given relative to the location of the executable, - * as denoted by the 'ORIGIN' token - */ - string - getRelativeModuleLocation() - { - smatch match; - if (regex_search (string(LUMIERA_PLUGIN_PATH), match, EXTRACT_RELATIVE_PATHSPEC)) - return (match[1]); - else - dieHard ("no valid module loading location relative to executable defined in LUMIERA_PLUGIN_PATH"); - } + /** + * 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 { @@ -100,25 +95,26 @@ namespace lumiera { end_; public: - SearchPathSplitter (string searchPath) + SearchPathSplitter (string const& searchPath) : pos_(searchPath.begin(),searchPath.end(), EXTRACT_PATHSPEC) , end_() { } bool - hasNext() + isValid() const { return pos_ != end_; } string - next() + fetch () { - ++pos_; - if (!hasNext()) + if (!isValid()) dieHard ("Search path exhausted."); - return resolveRelative(); + string currentPathElement = resolveRelative(); + ++pos_; + return currentPathElement; } private: @@ -133,7 +129,7 @@ namespace lumiera { return getFullPath(); } - smatch::value_type found(int group=0) { return (*pos_)[group]; } + SubMatch found(int group=0) { return (*pos_)[group]; } bool containsORIGINToken() { return found(1).matched; } string getRelativePath() { return found(2); } @@ -146,13 +142,13 @@ namespace lumiera { 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 an existing directory"); + dieHard ("Error in search path: component \""+modPathName.string()+"\" is not a directory"); - return modPathName.string(); + 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 @@ -174,22 +170,26 @@ namespace lumiera { } // try / continue search path - if (searchLocation.hasNext()) - modulePathName = fsys::path() / searchLocation.next() / moduleName; + 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") @@ -203,8 +203,8 @@ namespace lumiera { "May us $ORIGIN to refer to the EXE location") ; - ifstream configIn (resolveModulePath (bootstrapIni).c_str()); - + ifstream configIn (resolve(bootstrapIni).c_str()); + opt::parsed_options parsed = opt::parse_config_file (configIn, syntax); @@ -218,6 +218,15 @@ namespace lumiera { { 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 @@ -233,7 +242,7 @@ namespace lumiera { { Config appConfig(BOOTSTRAP_INI); string guiModule = appConfig["BuildsystemDemo.gui"]; - string moduleSearch = appConfig["BuildsystemDemo.modulepath"]; + string moduleSearch = appConfig["BuildsystemDemo.modulepath"]; string moduleLocation = resolveModulePath (guiModule, moduleSearch); void* handle = dlopen (moduleLocation.c_str(), RTLD_LAZY|RTLD_LOCAL); diff --git a/src/common/dummy-func.hpp b/src/common/dummy-func.hpp index d15383b88..43e43726a 100644 --- a/src/common/dummy-func.hpp +++ b/src/common/dummy-func.hpp @@ -20,6 +20,17 @@ namespace lumiera { * 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(); From 0ac014913765177dbfdd09f8f5f9bf002b08aefa Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 4 Feb 2011 22:19:25 +0100 Subject: [PATCH 32/32] Define first preview version number 0.pre.01 Rewrite README, INSTALL and AUTHORS as foundation for the Debian package --- AUTHORS | 168 ++++++++++++++++++++++++++++++----------- INSTALL | 218 +++++++++++++++++++++++++++++++++++++++-------------- README | 75 ++++++++++++------ SConstruct | 2 +- 4 files changed, 336 insertions(+), 127 deletions(-) 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 3ecc05196..e2c2dbf39 100644 --- a/INSTALL +++ b/INSTALL @@ -1,46 +1,71 @@ -Running / Installing Lumiera Prototype -====================================== - -From: -http://www.pipapo.org/pipawiki/Lumiera/NewbiesTutorials - - Newbies Tutorials +================= -This page contains some tutorials for beginners that want to help to the -developers of Lumiera. +This page contains some tutorials for beginners interested in Lumiera development. -Trying the Lumiera GUI from Joel -You need to have: +Building Lumiera from source +---------------------------- +Currently, after building the application, you can try out the Lumiera GUI +and you can run the testsuite. - * libboost - * libtool - * git - * libgavl - * nobug(see below) +For building Lumiera, besides the GNU C/C++ compiler (Version 4.X), you'll need: -For Ubuntu Hardy also: + * 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) - * libglade2-dev - * libgdl-1-dev - * libgtkmm-2.4-dev - * libxv-dev +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` -also check http://gnuradio.org/trac/wiki/UbuntuInstall#InstallationOptions to -see that all your installations options are met. +.Notes for Ubuntu: -Installing nobug from git +On Hardy you need also: -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: + * libglade2-dev + * libgtkmm-2.4-dev + * libxv-dev +For most Debian based systems, e.g. Ubuntu Intrepid and Jaunty, you can install these dependencies with: + +------------------------------------------------------------ +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 +------------------------------------------------------------ + + +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. + +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 @@ -48,11 +73,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 @@ -60,40 +152,52 @@ 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: +NOTE: you can't _install_ Lumiera currently. Don't try it, it won't work. +Just run it from the build directory. -./lumigui +After the build has finished successfully, you should be able to start Lumiera. +Currently, this will bring up the GUI, without any further functionality -[NewbiesTut] + * for autotools build: issue `./lumiera` (from within the `build` subdirectory) + * for scons build: ++ +------------------- +cd bin +./lumiera +------------------- -Contibuting +you should see something like (screenshot from 1/2009): -Nothing is easier, follow the basic instructions at http://www.kernel.org/pub/ -software/scm/git/docs/gittutorial.html, notably the +image:http://www.pipapo.org/pipawiki/Lumiera/GuiBrainstorming?action=AttachFile&do=get&target=screenshot090124-resources.jpg[] + + +Contributing +------------ + +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 7913094ee..3d62663eb 100644 --- a/README +++ b/README @@ -1,44 +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, ...) - . - 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. +************************************************************* +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, ...) -For more information about Lumiera visit http://lumiera.org/ -For more information about Cinelerra visit http://cinelerra.org/ +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. +More Informations at http://lumiera.org/[Lumiera.org] +**************************************************************** ----------------------------- -"Lumiera" prototype code ----------------------------- +Lumiera pre-Alpha Versions +-------------------------- -**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". +**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''. -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 his ancestor "Cinelerra" +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, +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 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 ------------------ -*to be written* +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+ diff --git a/SConstruct b/SConstruct index 99ee764bb..aa382f2c8 100644 --- a/SConstruct +++ b/SConstruct @@ -30,7 +30,7 @@ #-----------------------------------Configuration TARGDIR = 'target' -VERSION = '0.1+pre.01' +VERSION = '0.pre.01' TOOLDIR = './admin/scons' # SCons plugins SCRIPTDIR = './admin' OPTCACHE = 'optcache'