senfutil
helps setting up projects which utilize SENF. It will configure all necessary compiler and linker options and additionally sets up some useful defaults and utilities.
senfutil
really serves three roles
senfutil
you need to do two things:
SConstruct
filesenfutil.py
to site_scons
SConstruct
file
import senfutil env = Environment() senfutil.SetupForSENF(env) senfutil.DefaultOptions(env) env.SetDefault( PROJECTNAME = 'Example project', PROJECTEMAIL = 'developer@domain.com', DOCLINKS = [ ('Homepage', 'http://www.domain.com') ] ) sources, tests = senfutil.Glob(env, exclude=['main.cc']) objects = env.Object(sources) example = env.Program('example', objects + ['main.cc']) test = env.BoostUnitTest('test', objects + tests) env.Default(example) senfutil.Doxygen(env) senfutil.CleanGlob('all', [ '*~', '#*#' ])
This simple sample already enables a lot of functionality:
$ scons
$ scons doc test
$ scons -c all
$ scons CXXFLAGS+=-Wextra
senfutil.py
is not on the standard python
or SCons
path, some extra steps are needed to find it.
sys.path
before importing senfutil:
import sys sys.path.extend(('/usr/local/lib/senf/site_scons', '/usr/lib/senf/site_scons')) import senfutil
site_scons/senfutil.py
into your project. This script will search for site_scons/senfutil.py
in a list of directories and then load the real senfutil.py
on top of itself. The directories searched include: the current directory and all parents, subdirectories named senf/
, Senf/
or SENF/
thereof, and /usr/local/lib/senf/
and /usr/lib/senf/
def findsenf(sysdirs = ('/usr/local/lib/senf','/usr/lib/senf'), subdirs = ('', 'senf', 'Senf', 'SENF')): import os, itertools def ancestors(d): p = d.split(os.path.sep) return (os.path.join(p[0]+os.path.sep,*p[1:i]) for i in range(len(p),0,-1)) for d in itertools.chain(ancestors(os.getcwd()),sysdirs): for s in subdirs: py = os.path.join(d,s,'site_scons/senfutil.py') if os.path.exists(py) and not os.path.samefile(py,__file__): return py raise ImportError, 'senfutil not found' # replace module with real senfutil import sys, os __file__ = findsenf() sys.path.append(os.path.dirname(__file__)) del sys, os, findsenf execfile(__file__, locals(), globals())
senfutil
utility for SCons helps setting up a project to compile against SENF:
senfutil
adds all necessary libraries to link againstsenfutil
will set necessary compile options.senfutil
supports normal, debug and final project build optionssenfutil
adds support for Boost unit testssenfutil
implements a very simple to use enhanced doxygen build with SENF symbol cross-referencesenfutil
allows specifying variables on the scons command linesenfutil
supports more readable compile-time SENF loglevel configurationimport sys sys.path.extend(('senf/site_scons','/usr/lib/senf/site_scons')) import glob, senfutil env = Environment() senfutil.SetupForSENF(env) # senfutil.DefaultOptions(env) # Set or change SCons environment variables with env.Append, env.Replace or env.SetDefault env.Append( CXXFLAGS = [ '-Wall', '-Woverloaded-virtual' ], CXXFLAGS_final = [ '-O2' ], CXXFLAGS_normal = [ '-O0', '-g' ], CXXFLAGS_debug = [ '$CXXFLAGS_normal' ], LINKFLAGS_normal = [ '-Wl,-S' ], LOGLEVELS_debug = [ 'senf::log::Debug||VERBOSE' ], PROJECTNAME = 'Example project', PROJECTEMAIL = 'developer@domain.com', DOCLINKS = [ ('Homepage', 'http://www.domain.com') ] ) # Create a list of sources and tests. Sources are all *.cc files, test are *.test.cc sources, tests = senfutil.Glob(env, exclude=['main.cc'] ) # Build objects from sources objects = env.Object(sources) # Build main binary env.Default( env.Program( target='example', source=objects + ['main.cc'] ) ) # Build a boost unit-test from additional test sources env.BoostUnitTest( 'test', source=objects + tests) # Build a documentation, autogenerates a Doxyfile senfutil.Doxygen(env)
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 globally installed SENF.
senfutil
supports the debug=1
or final=1
build options. These parameters select one of the build configurations 'debug', 'normal' or 'final'. The following variables are supported each with separate values for all three configurations:
CXXFLAGS
CPPDEFINES
LINKFLAGS
LOGLEVELS
senfutil
will detect the type of SENF library used (final or not) and set the correct compile options.
LOGLEVELS
(and it's build configuration specific variants) may be set. This variable will be parsed and converted into the correct SENF_LOG_CONF
definition. The LOGLEVELS
Syntax is
senf::log::Debug
) and level is the loglevel. There must be no whitespace in a single specification, multiple specifications are either specified using an array or separated with whitespace.
senfutil.DefaultOptions(env)
is provided. This function is identical to:
senfutil.DefaultOptions(env) => env.Append( CXXFLAGS = [ '-Wall', '-Woverloaded-virtual' ], CXXFLAGS_final = [ '-O2' ], CXXFLAGS_normal = [ '-O0', '-g' ], CXXFLAGS_debug = [ '$CXXFLAGS_normal' ], LINKFLAGS_normal = [ '-Wl,-S' ], )
Thus above example can be simplified to
import sys sys.path.extend(('senf/site_scons','/usr/lib/senf/site_scons')) import glob, senfutil env = Environment() senfutil.SetupForSENF(env) senfutil.DefaultOptions(env) env.Append( LOGLEVELS_debug = [ 'senf::log::Debug||VERBOSE' ], PROJECTNAME = 'Example project', PROJECTEMAIL = 'developer@domain.com', DOCLINKS = [ ('Homepage', 'http://www.domain.com') ] ) sources, tests = senfutil.Glob(env, exclude=['main.cc'] ) objects = env.Object(sources) env.Default( env.Program( target='example', source=objects + ['main.cc'] ) ) env.BoostUnitTest( 'test', source=objects + tests) senfutil.Doxygen(env)
# Generate list of sources and tests (sources=*.cc, tests=*.test.cc) extra_sources = ['main.cc'] sources, tests = senfutil.Glob(env, exclude=extra_sources) # Build object files needed for both main target and unit tests objects = env.Object(sources) # Build main target, e.g. a Binary with additional sources which are not part of the unit test env.Program('example', objects+extra_sources) # Build unit tests including additional test sources env.BoostUnitTest('test', objects+tests)
It is important to exclude the main
function from the unit-test build since the boost unit test library provides it's own.
senfutil.Doxygen
utility
env.Append( PROJECTNAME = "Example project", PROJECTEMAIL = "coder@example.com", COPYRIGHT = "The Master Coders", DOCLINKS = [ ('Homeage', 'http://www.example.com') ], REVISION = 'r'+os.popen('svnversion').read().strip().lower() ) senfutil.Doxygen(env)
The senfutil.Doxygen
utility autogenerates a Doxyfile
.
The utility will search for a SENF documentation in the senfdoc
and senf
subdirectories as well as via the senfutil module directory and some other standard locations. If SENF documentation is found, the SENF tagfiles will automatically be added. Links will be resolved to the documentation found.
senfutil.Doxygen
takes some additional optional keyword arguments:
doxyheader:
Path of an alternative HTML headerdoxyfooter:
Path of an alternative HTML footerdoxycss:
Path on an alternative CSS filemydoxyfile:
If set to True
, don't generate or clean the Doxyfile\
senfdoc_path:
List of additional directories to search for SENF documentationsenfutil
automatically parses SCons command line arguments into the SCons build environment. This allows specifying any parameter on the command line:
$ scons CXX=myg++ CXXFLAGS+=-mtune=geodeYou may either set variables unconditionally using '=' or append values to the end of a list using '+='.