From: g0dil Date: Mon, 7 Apr 2008 10:20:32 +0000 (+0000) Subject: senfscons: Add additional very simple build-helper for externel projects using SENF X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=f2cc6f8a4ca99301f9f26156803e541ec2dff66b;hp=22e56fa8ef4cea3fd55c9463ecd2af8a6fbd213d;p=senf.git senfscons: Add additional very simple build-helper for externel projects using SENF Make wording on SENF_DEBUG more clear (hopefully ...) git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@788 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Mainpage.dox b/Mainpage.dox index 77611d1..036a1e6 100644 --- a/Mainpage.dox +++ b/Mainpage.dox @@ -87,14 +87,13 @@ \section senf_compiler_options Compiler and Linker Options - If SENF is compiled in debug mode (SENF_DEBUG is defined), exception messages will - automatically include a stack backtrace. For this to work, you need to add the -rdynamic option - to all link commands. This feature depends on gcc and the GNU-libc. - - It is very important that both the SENF library and the application using it are either - compiled with or without this compiler switch (-DSENF_DEBUG). Otherwise, the compiler will emit - error messages which might be hard to debug. + If SENF is compiled in debug mode (SENF_DEBUG is defined), exception messages will automatically + include a stack backtrace. For this to work, you need to add the -rdynamic option to all link + commands. This feature depends on gcc and the GNU-libc. + It is very important that both the SENF library and the application using it are compiled + \e both either with or without this compiler switch (-DSENF_DEBUG). Otherwise, the compiler will + emit error messages which might be hard to debug. */ /** \page senf_build Building the SENF framework @@ -152,7 +151,7 @@ svn:externals for this) or a symbolic link to your SENF checkout. \code - import os.path, glob + import glob env = Environment( @@ -161,40 +160,18 @@ ) - # If we have a symbolic link 'senf' pointing to our own senf build, use it (and assume - # it's in debug mode) - if os.path.exists('senf'): - print "\nUsing SENF in 'senf'\n" - env.Append( - - CPPDEFINES = [ 'SENF_DEBUG' ], - LIBPATH = [ 'senf' ], - CPPPATH = [ 'senf/include' ], - CXXFLAGS = [ '-O0', '-g', '-fno-inline' ], - LINKFLAGS = [ '-g', '-rdynamic' ], - - ) - env.Execute([ 'scons -C senf libsenf.a' ]) - else: - print "\nUsing system installed SENF\n" - - # replace 'mytarget' with the name of your target executable env.Program( target = 'mytarget', source = glob.glob('*.cc'), ); \endcode - This script automatically set's up the build correctly when using a self-compiled SENF in debug - mode (which is the default mode): - \li It links in all the required libraries in the correct order: First \c libsenf, then the - other needed libraries \c liberty, \c libboost_regex and \c libboost_iostreams. - \li It defines the SENF_DEBUG preprocessor symbol correctly - \li It correctly sets the include and library path - \li It adds sensible debug flags - \li It adds -rdynamic to the link command. This is needed to get a nice backtrace from - exceptions. - \li It automatically rebuilds SENF if needed + When building against a self-built SENF which will probably be in debug mode, the '-DSENF_DEBUG' + option must be added to the compile command. + + The most simple way to build using SENF is to use a very simple SCons helper which automatically + supports debug and final builds, uses SENF either centrally installed or locally built and has + some other nice features. See \ref senfutil for more info and an example for this utility. \see \ref senf_components \n \ref senf_overview @@ -210,7 +187,7 @@ \section libPPI libPPI: Packet Processing Infrastructure The Packet Processing Infrastructure implements a modular framework for implementing packet - oriented network applications. The library provides a larget set of pre-defined modules as well + oriented network applications. The library provides a large set of pre-defined modules as well as the necessary helpers to implement application specific processing modules. \see libPPI API reference @@ -249,7 +226,7 @@ \li senf::intrusive_refcount to simplify the implementation of classes usable with boost::intrusive_ptr \li boost::bind extensions - \li An interface to the \c g++ demangler integrated with type_info + \li An interface to the \c g++ de-mangler integrated with type_info \li Typedefs and rudimentary methods to simplify handling high-resolution time values \see libUtils API reference @@ -297,7 +274,7 @@ \li To interpret low level network packets, use the Packets library. This library will provide efficient and convenient access to all protocol fields. It supports parsing as well as - modifying and creating packets. It has default support for the most important internet + modifying and creating packets. It has default support for the most important Internet protocols and is highly extensible with new protocols. \li Go over the Utils library. It contains small helpers to simplify tasks like daemonization, exception handling, debugging and so on. @@ -412,10 +389,10 @@ */ +// :vim:textwidth=100 // Local Variables: // mode: c++ // fill-column: 100 -// :vim:textwidth=100 // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" diff --git a/Scheduler/ClockService.hh b/Scheduler/ClockService.hh index 255fcbe..e0e3939 100644 --- a/Scheduler/ClockService.hh +++ b/Scheduler/ClockService.hh @@ -84,6 +84,13 @@ namespace senf { in the normal case (no clock skew) and still encapsulate the dependency on legacy C headers. Using the senf::singleton mixin ensures, that the instance is constructed before main even when instance() is not called. + + \bug There is a deadlock condition between ClockService and the streaming of Boost.DateTime + values: Boost.DateTime seems to call tzset() whenever writing a date/time value (ugh) + and since tzset changes basic date/time values, it seems to block gettimeofday() which + leads to the SIGLARM handler blocking indefinitely. Resolution either a) find out, why + tzset() of all functions is called or b) move the ClockService heartbeat functionality + into the Scheduler. */ class ClockService : singleton diff --git a/senf.dict b/senf.dict index 00e57e0..755321b 100644 --- a/senf.dict +++ b/senf.dict @@ -39,9 +39,11 @@ bund calculateChecksum callback callbacks +CapitalziedLettersToSeparateWords catched cb cc +cci cd cerr cfi @@ -64,8 +66,14 @@ ConnectedCommunicationPolicy ConnectedRawV ConnectedUDPv const +CPPDEFINES +CPPPATH createAfter createBefore +ct +cti +CXXFLAGS +daemonization DatagramSection DataPacket dd @@ -89,6 +97,7 @@ dontinclude dox doxyfile doxygen +DSENF DSMCCSection dt ElementParser @@ -98,6 +107,7 @@ endif endl ENOFILE enum +env eof EPIPE epoll @@ -139,6 +149,7 @@ findPrev fixme fixvariant flurgle +fno fokus foo fooCallback @@ -178,6 +189,8 @@ html http iana ias +iberty +IDE IdleEvent ietf ifndef @@ -190,6 +203,7 @@ init initHeadSize initSize inline +inlines InputConnector inputSocket Institut @@ -202,6 +216,7 @@ IOEvent IOEventInfo ios iostream +iostreams ip IpChecksum IpTypes @@ -212,13 +227,22 @@ IPX isock iterator jens +jkaeber join key li +libboost libc libcwd libPacket libPackets +LIBPATH +libPPI +libScheduler +libsenf +libSocket +libUtils +LINKFLAGS LinkScope ListB ListN @@ -232,6 +256,7 @@ mainpage mixin mkdir MPEGDVBBundle +mpp multicast mycommand mydir @@ -241,6 +266,7 @@ MyNodeType MyParser myserver MySpecialObject +mytarget MyVariant MyVariantPolicy MyVector @@ -261,6 +287,7 @@ NodeCreateTraits noinit noroute nothrow +nUsing ob ObjectDirectory offene @@ -287,6 +314,7 @@ PacketData PacketImpl PacketInterpreter PacketInterpreterBase +packetized packetparser PacketParser PacketParserBase @@ -348,6 +376,7 @@ RawINetProtocol RawV rdynamic refcount +regex registerEvent registerPacket registerPacketType @@ -364,6 +393,7 @@ Satelitenkommunikation SConfig scons SCons +SConstruct ScopedDirectory ScopeId screenshot @@ -491,6 +521,8 @@ Ver vlanId VLanId VoidPacketParser +Wno +Woverloaded WrapException www xmlsoft diff --git a/senfscons/Mainpage.dox b/senfscons/Mainpage.dox index 9b915dc..5c81984 100644 --- a/senfscons/Mainpage.dox +++ b/senfscons/Mainpage.dox @@ -34,6 +34,61 @@ namespace senfscons { of pre- and postprocessing (which is integrated with the provided Doxygen builder) to fix some doxygen problems and generate a (IMHO) more readable layout. + \section senfutil Building Projects using SENF + + When building projects using senf, SENFSCons has a very simple helper module \ref senfutil to + make the building of libraries utilizing senf simpler: + \code + import sys + sys.path.extend(('senf/senfscons','/usr/lib/senf/senfscons')) + import os.path, glob, senfutil + + env = Environment() + + senfutil.SetupForSENF( env ) + + env.Append( + + LIBS = [ ], + CXXFLAGS = [ '-Wall', '-Woverloaded-virtual' ], + LINKFLAGS = [ ], + + CXXFLAGS_debug = [ ], + LINKFLAGS_debug = [ ], + LOGLEVELS_debug = [ 'senf::log::Debug||VERBOSE' ], + + CXXFLAGS_final = [ '-O3' ], + LINKFLAGS_final = [ ], + LOGLEVELS_final = [ ], + + SENF_BUILDOPTS = [ ], + + ) + + env.Default( + env.Program( target = 'udpforward', + source = glob.glob('*.cc') ) + ) + + env.Clean(DEFAULT_TARGETS, [ 'udpforward.log', 'udpforward.pid' ]) + \endcode + + This example builds a simple binary from a number of source files (all '.cc' files). It links + against the SENF library and automatically sets all the correct compiler options using + senfutil.SetupForSENF( env ). + + This script automatically uses a SENF installation either symlinked or imported into the current + project in directory 'senf' or, if this directory does not exist, a globaly installed SENF. A + locally installed SENF is automatically recompiled if needed. Parallel building is also + supported. + + This script automatically supports the \c final and \c LOGLEVELS command line parameters. The + LOGLEVELS parameter uses a much more readable syntax than SENF_LOG_CONF: +
+    $ scons -j2 final=1 \
+          LOGLEVELS='senf::log::Debug||IMPORTANT myapp::Transactions|mytrans::Area|VERBOSE'
+    
+ \section layout The Project Layout A Project using the SENFSCons infrastructure will always use a consistent directory layout. The diff --git a/senfscons/senfutil.py b/senfscons/senfutil.py new file mode 100644 index 0000000..a0954a8 --- /dev/null +++ b/senfscons/senfutil.py @@ -0,0 +1,59 @@ +import os.path +from SCons.Script import * + +########################################################################### +# This looks much more complicated than it is: We do three things here: +# a) switch between final or debug options +# b) parse the LOGLEVELS parameter into the correct SENF_LOG_CONF syntax +# c) check for a local SENF, set options accordingly and update that SENF if needed + +def SetupForSENF(env): + env.Append( LIBS = [ 'senf', 'iberty', 'boost_regex', 'boost_iostreams' ], + CXXFLAGS = [ '-Wno-long-long', + '${"$CXXFLAGS_"+(final and "final" or "debug")}' ], + LINKFLAGS = [ '${"$LINKFLAGS_"+(final and "final" or "debug")}' ], + SENF_BUILDOPTS = [ '-j%s' % (env.GetOption('num_jobs') or "1") ], + CXXFLAGS_debug = [ '-O0', '-g', '-fno-inline' ], + LINKFLAGS_debug = [ '-g', '-rdynamic' ], + ) + + # Parse LOGLEVELS parameter + def parseLogOption(value): + stream, area, level = ( x.strip() for x in value.strip().split('|') ) + stream = ''.join('(%s)' % x for x in stream.split('::') ) + if area : area = ''.join( '(%s)' % x for x in elts[1].split('::') ) + else : area = '(_)' + return '(( %s,%s,%s ))' % (stream,area,level) + + def expandLogOption(target, source, env, for_signature): + return ' '.join( parseLogOption(x) for x in env.subst('$LOGLEVELS').split() ) + + # Add command-line options: 'LOGLEVELS' and 'final' + opts = Options() + opts.Add( 'LOGLEVELS', 'Special log levels. Syntax: |[]| ...', + '${"$LOGLEVELS_"+(final and "final" or "debug")}' ) + opts.Add( BoolOption('final', 'Build final (optimized) build', False) ) + opts.Update(env) + + print env.subst('$LOGLEVELS') + + if env.subst('$LOGLEVELS'): + env.Append( expandLogOption=expandLogOption ) + env.Append( CPPDEFINES = { 'SENF_LOG_CONF': '$expandLogOption' } ) + + env.Help(opts.GenerateHelpText(env)) + + # If we have a symbolic link (or directory) 'senf', we use it as our + # senf repository + if os.path.exists('senf'): + print "\nUsing SENF in './senf'\n" + env.Append( LIBPATH = [ 'senf' ], + CPPPATH = [ 'senf/include' ], + SENF_BUILDOPTS = [ '${final and "final=1" or None}' ], + CPPDEFINES = [ '${not(final) and "SENF_DEBUG" or None}' ] ) + + env.Default( + env.AlwaysBuild( + env.Command('senf/libsenf.a', [], [ 'scons -C senf $SENF_BUILDOPTS libsenf.a' ]))) + else: + print '\nUsing global SENF\n'