Setup debian package build environment in 'debian/'
g0dil [Tue, 28 Aug 2007 15:29:13 +0000 (15:29 +0000)]
Add 'install_all' scons target
Packets: Fix unit tests in final=1 build
Socket/Protocols/INet: Fix final=1 build
Add 'deb' scons target

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@412 270642c3-0616-0410-b53a-bc976706d245

21 files changed:
Makefile
Packets/PacketImpl.test.cc
SConstruct
Socket/Protocols/INet/INetAddressing.cc
control [deleted file]
debian/README [new file with mode: 0644]
debian/changelog.template [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/dirs [new file with mode: 0644]
debian/index.html [new file with mode: 0644]
debian/libsenf-doc.install [new file with mode: 0644]
debian/libsenf-packets-dev.install [new file with mode: 0644]
debian/libsenf-ppi-dev.install [new file with mode: 0644]
debian/libsenf-scheduler-dev.install [new file with mode: 0644]
debian/libsenf-socket-dev.install [new file with mode: 0644]
debian/libsenf-utils.dev.install [new file with mode: 0644]
debian/rules [new file with mode: 0755]
doclib/SConscript
senfscons/SENFSCons.py

index 0c860c4..89b9254 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ build:
        $(SCONS)
 
 clean:
-       $(SCONS) --clean
+       $(SCONS) --clean all
 
 all_docs all_tests:
        $(SCONS) $@
@@ -17,7 +17,7 @@ all_docs all_tests:
 #----------------------------------------------------------------------
 # Subversion stuff
 #----------------------------------------------------------------------
-SVN_REVISION = $(shell svn info|grep '^Revision: '|awk '{print $$2}')
+SVN_REVISION = $(shell svnversion)
 
 svn_version:
        @echo $(SVN_REVISION)
@@ -50,47 +50,5 @@ DEB_LIB = $(DEB_TOP)/usr/lib/senf
 DEB_INC = $(DEB_TOP)/usr/include/senf
 DEB_DOC = $(DEB_TOP)/usr/share/doc/senf
 
-#----------------------------------------------------------------------
-# Debian package content
-#----------------------------------------------------------------------
-SENF_LIBS = *.a
-SENF_HDRS = $$(find -path './XXXdebian' -prune \
-                 -o -iname \*.h \
-                 -o -iname \*.hh \
-                 -o -iname \*.ih \
-                 -o -iname \*.c \
-                 -o -iname \*.cc \
-                 -o -iname \*.ct \
-                 -o -iname \*.cci \
-                 -o -iname \*.cti \
-                 -o -iname \*.mpp \
-)
-
-package: $(PKG_FILE)
-$(PKG_FILE): build
-       rm -rf $(DEB_TOP)
-       mkdir -p $(DEB_CTL) $(DEB_INC) $(DEB_LIB) $(DEB_DOC)
-       find $(DEB_TOP) -type d | xargs chmod 755
-       tar cf - $(SENF_HDRS) | (cd $(DEB_INC) && tar xf -)
-       tar cf - $(SENF_LIBS) | (cd $(DEB_LIB) && tar xf -)
-       sed -e 's,PKG_VERSION,$(PKG_VERS),' control > $(DEB_CTL)/control
-       $(MAKE) deb-doc
-       dpkg-deb --build debian $(PKG_FILE)
-
-#----------------------------------------------------------------------
-# Extract documentation files from source tree
-#----------------------------------------------------------------------
-deb-doc:
-       rsync -rz \
-               --filter="- debian/*" \
-               --filter="- .svn" \
-               --filter="+ */" \
-               --filter="+ *.html" \
-               --filter="+ *.css" \
-               --filter="+ *.png" \
-               --filter="+ *.php" \
-               --filter="+ *.idx" \
-               --filter="+ *.log" \
-               --filter="- *" \
-               . $(DEB_DOC)
-
+package:
+       $(SCONS) deb
index e4e5bcb..8f6fe56 100644 (file)
@@ -48,8 +48,10 @@ BOOST_AUTO_UNIT_TEST(packetImpl_mem)
     BOOST_CHECK_EQUAL(p->refcount(), 0);
     p->add_ref();
     BOOST_CHECK_EQUAL(p->refcount(), 1);
+#ifndef NDEBUG
     BOOST_CHECK_EQUAL(
         senf::pool_alloc_mixin<senf::detail::PacketImpl>::allocCounter(), 1u);
+#endif
     // From now on, the object should stay alive since I manually incremented the
     // refcount ..
 
@@ -65,8 +67,10 @@ BOOST_AUTO_UNIT_TEST(packetImpl_mem)
                 p,p->begin(),p->end(), senf::PacketInterpreterBase::Append));
         // Hmm ... this check works as long as sizeof(PacketInterpreterBase> !=
         // sizeof(PacketImpl) ... !!
+#ifndef NDEBUG
         BOOST_CHECK_EQUAL(
             senf::pool_alloc_mixin< senf::PacketInterpreter<VoidPacket> >::allocCounter(), 1u);
+#endif
         senf::PacketInterpreterBase::ptr pi2 (pi);
         BOOST_CHECK_EQUAL(p->refcount(), 3);
     }
@@ -78,8 +82,10 @@ BOOST_AUTO_UNIT_TEST(packetImpl_mem)
         p->truncateInterpreters(pi.get());
         BOOST_CHECK_EQUAL(p->refcount(),1);
     }
+#ifndef NDEBUG
     BOOST_CHECK_EQUAL(
         senf::pool_alloc_mixin<senf::PacketInterpreterBase>::allocCounter(), 0u);
+#endif
     BOOST_CHECK_EQUAL(p->refcount(),1);
 
 
@@ -87,8 +93,10 @@ BOOST_AUTO_UNIT_TEST(packetImpl_mem)
     // Therefore we can safely delete the object.
     BOOST_CHECK_EQUAL(p->refcount(), 1);
     p->release();
+#ifndef NDEBUG
     BOOST_CHECK_EQUAL(
         senf::pool_alloc_mixin<senf::detail::PacketImpl>::allocCounter(), 0u);
+#endif
 }
 
 BOOST_AUTO_UNIT_TEST(packetImpl_data)
@@ -191,8 +199,10 @@ BOOST_AUTO_UNIT_TEST(packetImpl_interpreters)
 
     BOOST_CHECK_EQUAL(p->refcount(), 1);
     p->release();
+#ifndef NDEBUG
     BOOST_CHECK_EQUAL(
         senf::pool_alloc_mixin<senf::detail::PacketImpl>::allocCounter(), 0u);
+#endif
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
index 50a148e..b3a6a52 100644 (file)
@@ -1,6 +1,6 @@
 # -*- python -*-
 
-import sys, glob, os.path, datetime
+import sys, glob, os.path, datetime, pwd, time
 sys.path.append('senfscons')
 import SENFSCons
 
@@ -18,7 +18,8 @@ env.Append(
    DOXY_XREF_TYPES = [ 'bug', 'fixme', 'todo', 'idea' ],
    DOXY_HTML_XSL = '#/doclib/html-munge.xsl',
    ENV = { 'TODAY' : str(datetime.date.today()),
-           'REVISION' : os.popen("svnversion").read().strip()
+           'REVISION' : os.popen("svnversion").read().strip(),
+           'LOGNAME' : os.environ['LOGNAME']
            },
 )
 
@@ -35,6 +36,30 @@ SENFSCons.DoxyXRef(env,
                    HTML_HEADER = '#/doclib/doxy-header-overview.html',
                    HTML_FOOTER = '#/doclib/doxy-footer.html')
 
+def updateRevision(target, source, env):
+    rev = env['ENV']['REVISION']
+    if ':' in rev:
+        print
+        print "Working copy not clean. Run 'svn update'"
+        print
+        return 1
+    if 'M' in rev:
+        print
+        print "Working copy contains local changes. Commit first"
+        print
+        return 1
+    if 'S' in rev or 'M' in rev:
+        rev = rev[:-1]
+    changelog = file('debian/changelog.template').read() % {
+        'rev': rev,
+        'user': pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0].strip(),
+        'date': time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) }
+    file('debian/changelog','w').write(changelog)
+
+env.AlwaysBuild(
+    env.Alias('deb', [], [ updateRevision,
+                           "dpkg-buildpackage -us -uc -rfakeroot" ]))
+
 # Create Doxyfile.local if not cleaning and the file does not exist
 # otherwise doxygen will barf on this non-existent file
 if not env.GetOption('clean') and not os.path.exists("Doxyfile.local"):
index a54cc1c..88f8f5b 100644 (file)
@@ -129,7 +129,11 @@ prefix_ std::string senf::INet6SocketAddress::iface()
     if (sockaddr_.sin6_scope_id == 0)
         return "";
     char buffer[IFNAMSIZ];
+#ifndef NDEBUG
     BOOST_ASSERT( if_indextoname(sockaddr_.sin6_scope_id,buffer) );
+#else
+    if_indextoname(sockaddr_.sin6_scope_id,buffer);
+#endif
     return std::string(buffer);
 }
 
diff --git a/control b/control
deleted file mode 100644 (file)
index 1bc1977..0000000
--- a/control
+++ /dev/null
@@ -1,11 +0,0 @@
-Package: senf-dev
-Version: PKG_VERSION
-Section: base
-Priority: optional
-Architecture: i386
-Depends:libboost-dev, libboost-date-time-dev, libboost-regex-dev,
-        libboost-thread-dev
-Maintainer: Joachim Kaeber <joachim.kaeber@fokus.fraunhofer.de>
-Description: The SENF Extensible Network Framework
-  The SENF Framework is a collection of loosely coupled modules
-  for writing network oriented applications in C++.
diff --git a/debian/README b/debian/README
new file mode 100644 (file)
index 0000000..472daf2
--- /dev/null
@@ -0,0 +1,27 @@
+SENF: The Simple and Extensible Network Framework
+-------------------------------------------------
+
+The SENF Simple and Extensible Network Framework aims to be a complete
+set of libraries to facilitate the development of network applications
+focusing on network protocols on the layers below the application
+layer. However, the framework includes many general purpose utilities
+and will be expedient to use well beyond its primary objective.
+
+Goals
+-----
+
+The main goals of this library are (in no particular order): 
+
+ - modular framework design
+ - utilizing the power of modern C++
+ - very low overhead for frequently called members
+ - extensible design
+ - concise interface
+
+Getting started
+---------------
+
+Information on using the library including some extensively documented
+examples are found in the 'libsenf-doc' package.
+
+ -- Stefan Bund <senf-dev@lists.berlios.de>  Tue, 28 Aug 2007 10:02:23 +0200
diff --git a/debian/changelog.template b/debian/changelog.template
new file mode 100644 (file)
index 0000000..9ba62d6
--- /dev/null
@@ -0,0 +1,5 @@
+libsenf (0.0r%(rev)s) unstable; urgency=low
+
+  * Packaging revision %(rev)s
+
+ -- %(user)s <senf-dev@lists.berlios.de>  %(date)s
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..0062ea8
--- /dev/null
@@ -0,0 +1,77 @@
+Source: libsenf
+Priority: extra
+Maintainer: Stefan Bund <senf-dev@lists.berlios.de>
+Build-Depends: debhelper (>= 5), scons, libboost-dev, libboost-test-dev, libboost-date-time-dev, libboost-regex-dev, libboost-thread-dev, doxygen, dia, tidy, xsltproc, graphviz
+Standards-Version: 3.7.2
+Section: libs
+
+Package: libsenf-ppi-dev
+Section: libdevel
+Architecture: any
+Depends: libsenf-scheduler-dev (= ${Source-Version}), libsenf-packets-dev (= ${Source-Version}), ${shlibs:Depends}, ${misc:Depends}
+Description: SENF Extensible Network Framework, Packet Processing Infrastructure
+ The SENF Simple and Extensible Network Framework aims to be a
+ complete set of libraries to facilitate the development of network
+ applications focusing on network protocols on the layers below the
+ application layer. However, the framework includes many general
+ purpose utilities and will be expedient to use well beyond its primary
+ objective.
+
+Package: libsenf-packets-dev
+Section: libdevel
+Architecture: any
+Depends: libsenf-socket-dev (= ${Source-Version}), libsenf-utils-dev (= ${Source-Version}), ${shlibs:Depends}, ${misc:Depends}
+Description: SENF Extensible Network Framework, Packets library
+ The SENF Simple and Extensible Network Framework aims to be a
+ complete set of libraries to facilitate the development of network
+ applications focusing on network protocols on the layers below the
+ application layer. However, the framework includes many general
+ purpose utilities and will be expedient to use well beyond its primary
+ objective.
+
+Package: libsenf-scheduler-dev
+Section: libdevel
+Architecture: any
+Depends: libsenf-socket-dev (= ${Source-Version}), libsenf-utils-dev (= ${Source-Version}), ${shlibs:Depends}, ${misc:Depends}
+Description: SENF Extensible Network Framework, Scheduler, development files
+ The SENF Simple and Extensible Network Framework aims to be a
+ complete set of libraries to facilitate the development of network
+ applications focusing on network protocols on the layers below the
+ application layer. However, the framework includes many general
+ purpose utilities and will be expedient to use well beyond its primary
+ objective.
+
+Package: libsenf-socket-dev
+Section: libdevel
+Architecture: any
+Depends: libsenf-utils-dev (= ${Source-Version}), ${shlibs:Depends}, ${misc:Depends}
+Description: SENF Extensible Network Framework, Socket library, development files
+ The SENF Simple and Extensible Network Framework aims to be a
+ complete set of libraries to facilitate the development of network
+ applications focusing on network protocols on the layers below the
+ application layer. However, the framework includes many general
+ purpose utilities and will be expedient to use well beyond its primary
+ objective.
+
+Package: libsenf-utils-dev
+Section: libdevel
+Architecture: any
+Depends: binutils-dev, libboost-dev, libboost-regex-dev, libboost-date-time-dev, libboost-thread-dev, ${shlibs:Depends}, ${misc:Depends}
+Description: SENF Extensible Network Framework, Utilities, development files
+ The SENF Simple and Extensible Network Framework aims to be a
+ complete set of libraries to facilitate the development of network
+ applications focusing on network protocols on the layers below the
+ application layer. However, the framework includes many general
+ purpose utilities and will be expedient to use well beyond its primary
+ objective.
+
+Package: libsenf-doc
+Section: doc
+Architecture: all
+Description: SENF Extensible Network Framework, Documentation and Examples
+ The SENF Simple and Extensible Network Framework aims to be a
+ complete set of libraries to facilitate the development of network
+ applications focusing on network protocols on the layers below the
+ application layer. However, the framework includes many general
+ purpose utilities and will be expedient to use well beyond its primary
+ objective.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..d4e7766
--- /dev/null
@@ -0,0 +1,28 @@
+This is libsenf, written and maintained by Stefan Bund <senf-dev@lists.berlios.de>
+on Tue, 28 Aug 2007 10:02:23 +0200.
+
+The original source can always be found at:
+  http://senf.berlios.de
+
+Copyright Holder:
+  Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+  Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+
+License:
+
+  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 package; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.
diff --git a/debian/dirs b/debian/dirs
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/debian/index.html b/debian/index.html
new file mode 100644 (file)
index 0000000..fcf4f9e
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta http-equiv="refresh" content="0; URL=doc/html/index.html">
+   <title>SENF - Simple and Extensible Network Framework</title>
+</head>
+<body>
+    <h2>SENF - Simple and Extensible Network Framework</h2>
+    <p>
+      <a href="doc/html/index.html">SENF Manual</a>
+    </p>
+</body>
+</html>
diff --git a/debian/libsenf-doc.install b/debian/libsenf-doc.install
new file mode 100644 (file)
index 0000000..98ad065
--- /dev/null
@@ -0,0 +1,3 @@
+debian/tmp/usr/share/doc/libsenf-doc
+debian/README usr/share/doc/libsenf-doc
+debian/index.html usr/share/doc/libsenf-doc
diff --git a/debian/libsenf-packets-dev.install b/debian/libsenf-packets-dev.install
new file mode 100644 (file)
index 0000000..5057285
--- /dev/null
@@ -0,0 +1,5 @@
+debian/tmp/usr/lib/libPackets.a
+debian/tmp/usr/lib/libPackets_*.a
+debian/tmp/usr/lib/*.o usr/lib/Packets
+debian/tmp/usr/include/Packets
+debian/README usr/share/doc/libsenf-packets-dev
diff --git a/debian/libsenf-ppi-dev.install b/debian/libsenf-ppi-dev.install
new file mode 100644 (file)
index 0000000..1f5ac66
--- /dev/null
@@ -0,0 +1,3 @@
+debian/tmp/usr/lib/libPPI.a
+debian/tmp/usr/include/PPI
+debian/README usr/share/doc/libsenf-ppi-dev
diff --git a/debian/libsenf-scheduler-dev.install b/debian/libsenf-scheduler-dev.install
new file mode 100644 (file)
index 0000000..8c95c57
--- /dev/null
@@ -0,0 +1,3 @@
+debian/tmp/usr/lib/libScheduler.a
+debian/tmp/usr/include/Scheduler
+debian/README usr/share/doc/libsenf-scheduler-dev
diff --git a/debian/libsenf-socket-dev.install b/debian/libsenf-socket-dev.install
new file mode 100644 (file)
index 0000000..f1d6c8d
--- /dev/null
@@ -0,0 +1,3 @@
+debian/tmp/usr/lib/libSocket.a
+debian/tmp/usr/include/Scheduler
+debian/README usr/share/doc/libsenf-scheduler-dev
diff --git a/debian/libsenf-utils.dev.install b/debian/libsenf-utils.dev.install
new file mode 100644 (file)
index 0000000..a1c3e5d
--- /dev/null
@@ -0,0 +1,3 @@
+debian/tmp/usr/lib/libUtils.a
+debian/tmp/usr/include/Utils
+debian/README usr/share/doc/libsenf-utils-dev
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..15682ff
--- /dev/null
@@ -0,0 +1,109 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -O0
+else
+       CFLAGS += -O2
+endif
+
+# shared library versions, option 1
+version=2.0.5
+major=2
+# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
+#version=`ls src/.libs/lib*.so.* | \
+# awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
+#major=`ls src/.libs/lib*.so.* | \
+# awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
+
+destdir=$(CURDIR)/debian/tmp
+
+configure: configure-stamp
+configure-stamp:
+       dh_testdir
+#      # Add here commands to configure the package.
+       touch configure-stamp
+
+
+build: build-stamp
+build-stamp: configure-stamp 
+       dh_testdir
+#      # Add here commands to compile the package.
+       scons all final=1
+       touch $@
+
+clean:
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp configure-stamp
+#      # Add here commands to clean up after the build process.
+       -scons -c all
+       dh_clean 
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k 
+       dh_installdirs
+#      # Add here commands to install the package into debian/tmp
+       scons install_all final=1\
+               PREFIX='$(destdir)/usr' \
+               DOCINSTALLDIR='$$PREFIX/share/doc/libsenf-doc'
+#       We need to install the example sourcecode
+       find Examples \( -name "*.hh" -o -name "*.cc" \) -printf "%P\n" | \
+               while read src; do \
+                       dir="$(destdir)/usr/share/doc/libsenf-doc/examples/$$(dirname "$$src")"; \
+                       mkdir -p "$$dir"; \
+                       cp "Examples/$$src" "$$dir"; \
+               done
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+       dh_installchangelogs 
+       dh_installdocs
+       dh_installexamples
+       dh_install
+#      dh_installmenu
+#      dh_installdebconf       
+#      dh_installlogrotate
+#      dh_installemacsen
+#      dh_installpam
+#      dh_installmime
+#      dh_installinit
+#      dh_installcron
+#      dh_installinfo
+       dh_installman
+       dh_link
+       dh_strip
+       dh_compress
+       dh_fixperms
+#      dh_perl
+#      dh_python
+#      dh_makeshlibs
+       dh_installdeb
+       dh_shlibdeps
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
index 3712380..e45344d 100644 (file)
@@ -178,3 +178,11 @@ env.Alias('all_docs',
 env.Alias('all_docs',
           env.Command('search_paths.php', 'SConscript', writeTemplate,
                       TEMPLATE = Literal(SEARCH_PATHS_PHP)))
+
+env.Alias('install_all',
+          env.Install( '$DOCINSTALLDIR/doclib', [ 'favicon.ico',
+                                                  'logo-head.png',
+                                                  'search.php',
+                                                  'search_functions.php',
+                                                  'search_paths.php',
+                                                  'senf.css' ] ))
index c281919..7c193c4 100644 (file)
@@ -68,6 +68,14 @@ def InitOpts():
     opts.Add('EXTRA_DEFINES', 'Additional preprocessor defines', '')
     opts.Add('EXTRA_LIBS', 'Additional libraries to link against', '')
     opts.Add(SCons.Options.BoolOption('final','Enable optimization',0))
+    opts.Add('PREFIX', 'Installation prefix', '/usr/local')
+    opts.Add('LIBINSTALLDIR', 'Library install dir', '$PREFIX/lib')
+    opts.Add('BININSTALLDIR', 'Executable install dir', '$PREFIX/bin')
+    opts.Add('INCLUDEINSTALLDIR', 'Include-file install dir', '$PREFIX/include')
+    opts.Add('OBJINSTALLDIR', 'Static object file install dir', '$LIBINSTALLDIR')
+    opts.Add('DOCINSTALLDIR', 'Documentation install dir', '$PREFIX/doc')
+    opts.Add('CPP_INCLUDE_EXTENSIONS', 'File extensions to include in source install',
+             [ '.h', '.hh', '.ih', '.mpp', '.cci', '.ct', '.cti', '.mpp' ])
 
 # A finalizer is any callable object. All finalizers will be called
 # in MakeEnvironment. We use them so every finalizer has knowledge of
@@ -205,6 +213,9 @@ def MakeEnvironment():
     global opts, finalizers
     InitOpts()
     env = SCons.Environment.Environment(options=opts)
+    for opt in opts.options:
+        if SCons.Script.SConscript.Arguments.get(opt.key):
+            env[opt.key] = SCons.Script.SConscript.Arguments.get(opt.key)
     if SCons.Script.SConscript.Arguments.get('final'):
         env['final'] = 1
     env.Help(opts.GenerateHelpText(env))
@@ -332,6 +343,30 @@ def Objects(env, sources, testSources = None, LIBS = [], OBJECTS = []):
 
     return objects
 
+def InstallWithSources(env, targets, dir, sources, testSources = []):
+    if type(sources) is type(()):
+        sources = sources[0] + sources[1]
+    if testSources:
+        sources += testSources
+    if type(sources) is not type([]):
+        sources = [ sources ]
+
+    installs = []
+    installs.append( env.Install(dir, targets) )
+
+    for source in sources:
+        l = len(env.Dir('#').abspath)
+        source = str(source)
+        while '.' in source:
+            source = os.path.splitext(source)[0]
+        for ext in env['CPP_INCLUDE_EXTENSIONS']:
+            f = env.File(source+ext)
+            if f.exists():
+                installs.append(env.Install(
+                    '$INCLUDEINSTALLDIR' + f.dir.abspath[l:], f))
+
+    return installs
+
 ## \brief Build documentation with doxygen
 #
 # The doxygen target helper will build software documentation using
@@ -444,12 +479,22 @@ def Doxygen(env, doxyfile = "Doxyfile", extra_sources = []):
 
     if not htmlnode and not xmlnode:
         env.Depends(docs, extra_sources)
-        
+
     for doc in docs :
         env.Alias('all_docs', doc)
         env.Clean('all_docs', doc)
         env.Clean('all', doc)
 
+    l = len(env.Dir('#').abspath)
+    if htmlnode:
+        env.Alias('install_all',
+                  env.Install( '$DOCINSTALLDIR' + htmlnode.dir.dir.abspath[l:],
+                               htmlnode.dir ))
+    if tagnode:
+        env.Alias('install_all',
+                  env.Install( '$DOCINSTALLDIR' + tagnode.dir.abspath[l:],
+                               tagnode ))
+
     return docs
 
 ## \brief Build combined doxygen cross-reference
@@ -530,6 +575,8 @@ def Lib(env, library, sources, testSources = None, LIBS = [], OBJECTS = []):
         lib = env.Library(env.File(LibPath(library)),objects)
         env.Default(lib)
         env.Append(ALLLIBS = library)
+        install = InstallWithSources(env, lib, '$LIBINSTALLDIR', sources)
+        env.Alias('install_all', install)
     return lib
 
 ## \brief Build Object from multiple sources
@@ -539,6 +586,8 @@ def Object(env, target, sources, testSources = None, LIBS = [], OBJECTS = []):
     if objects:
         ob = env.Command(target+".o", objects, "ld -r -o $TARGET $SOURCES")
         env.Default(ob)
+        install = InstallWithSources(env, ob, '$OBJINSTALLDIR', sources)
+        env.Alias('install_all', install)
     return ob
 
 ## \brief Build executable
@@ -560,4 +609,7 @@ def Binary(env, binary, sources, testSources = None, LIBS = [], OBJECTS = []):
         program = progEnv.Program(target=binary,source=objects+OBJECTS)
         env.Default(program)
         env.Depends(program, [ env.File(LibPath(x)) for x in LIBS ])
+        install = InstallWithSources(env, program, '$BININSTALLDIR',
+                                     sources, testSources)
+        env.Alias('install_all', install)
     return program