\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 <B>very important</B> 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 <B>very important</B> 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
<tt>svn:externals</tt> for this) or a symbolic link to your SENF checkout.
\code
- import os.path, glob
+ import glob
env = Environment(
)
- # 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 <tt>SENF_DEBUG</tt> preprocessor symbol correctly
- \li It correctly sets the include and library path
- \li It adds sensible debug flags
- \li It adds <tt>-rdynamic</tt> 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
\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 <a href="../../PPI/doc/html/index.html">libPPI API reference</a>
\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 <a href="../../Utils/doc/html/index.html">libUtils API reference</a>
\li To interpret low level network packets, use the <a
href="../../Packets/doc/html/index.html">Packets library</a>. 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 <a href="../../Utils/doc/html/index.html">Utils library</a>. It contains small
helpers to simplify tasks like daemonization, exception handling, debugging and so on.
*/
\f
+// :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"
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<ClockService>
calculateChecksum
callback
callbacks
+CapitalziedLettersToSeparateWords
catched
cb
cc
+cci
cd
cerr
cfi
ConnectedRawV
ConnectedUDPv
const
+CPPDEFINES
+CPPPATH
createAfter
createBefore
+ct
+cti
+CXXFLAGS
+daemonization
DatagramSection
DataPacket
dd
dox
doxyfile
doxygen
+DSENF
DSMCCSection
dt
ElementParser
endl
ENOFILE
enum
+env
eof
EPIPE
epoll
fixme
fixvariant
flurgle
+fno
fokus
foo
fooCallback
http
iana
ias
+iberty
+IDE
IdleEvent
ietf
ifndef
initHeadSize
initSize
inline
+inlines
InputConnector
inputSocket
Institut
IOEventInfo
ios
iostream
+iostreams
ip
IpChecksum
IpTypes
isock
iterator
jens
+jkaeber
join
key
li
+libboost
libc
libcwd
libPacket
libPackets
+LIBPATH
+libPPI
+libScheduler
+libsenf
+libSocket
+libUtils
+LINKFLAGS
LinkScope
ListB
ListN
mixin
mkdir
MPEGDVBBundle
+mpp
multicast
mycommand
mydir
MyParser
myserver
MySpecialObject
+mytarget
MyVariant
MyVariantPolicy
MyVector
noinit
noroute
nothrow
+nUsing
ob
ObjectDirectory
offene
PacketImpl
PacketInterpreter
PacketInterpreterBase
+packetized
packetparser
PacketParser
PacketParserBase
RawV
rdynamic
refcount
+regex
registerEvent
registerPacket
registerPacketType
SConfig
scons
SCons
+SConstruct
ScopedDirectory
ScopeId
screenshot
vlanId
VLanId
VoidPacketParser
+Wno
+Woverloaded
WrapException
www
xmlsoft
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
+ <tt>senfutil.SetupForSENF( env )</tt>.
+
+ 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:
+ <pre>
+ $ scons -j2 final=1 \
+ LOGLEVELS='senf::log::Debug||IMPORTANT myapp::Transactions|mytrans::Area|VERBOSE'
+ </pre>
+
\section layout The Project Layout
A Project using the SENFSCons infrastructure will always use a consistent directory layout. The
--- /dev/null
+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: <stream>|[<area>]|<level> ...',
+ '${"$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'