pkgconfig + better protobuf support
diff --git a/libsync.pc.in b/libsync.pc.in
new file mode 100644
index 0000000..0f8ad64
--- /dev/null
+++ b/libsync.pc.in
@@ -0,0 +1,10 @@
+prefix=@PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: libsync 
+Description: Chronos library
+Version: @VERSION@
+Libs: -L${libdir} -lsync
+Cflags: -I${includedir}/sync
+
diff --git a/sync-state.proto b/model/sync-state.proto
similarity index 100%
rename from sync-state.proto
rename to model/sync-state.proto
diff --git a/waf-tools/protobuf.py b/waf-tools/protobuf.py
index 71d8bdf..684a945 100644
--- a/waf-tools/protobuf.py
+++ b/waf-tools/protobuf.py
@@ -1,3 +1,5 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
 #! /usr/bin/env python
 # encoding: utf-8
 
@@ -5,72 +7,66 @@
 
 When using this tool, the wscript will look like:
 
-	def options(opt):
-	        opt.tool_options('protobuf', tooldir=["waf-tools"])
+def options(opt):
+   opt.tool_options("protobuf", tooldir=["waf-tools"])
 
-	def configure(conf):
-		conf.load('compiler_cxx protobuf')
+def configure(conf):
+   conf.load("compiler_cxx protobuf")
 
-	def build(bld):
-		bld(source='main.cpp', target='app', use='PROTOBUF')
+def build(bld):
+   bld(source="main.cpp", target="app", use="PROTOBUF")
 
 Options are generated, in order to specify the location of protobuf includes/libraries.
 
-
 '''
-import sys
-import re
+
+from waflib import Utils, TaskGen, Task, Logs
+
 from waflib import Utils,Logs,Errors
 from waflib.Configure import conf
-PROTOBUF_DIR=['/usr','/usr/local','/opt/local','/sw']
-PROTOBUF_VERSION_FILE='google/protobuf/stubs/common.h'
-PROTOBUF_VERSION_CODE='''
-#include <iostream>
-#include <google/protobuf/stubs/common.h>
-int main() { std::cout << GOOGLE_PROTOBUF_VERSION ;}
-'''
 
 def options(opt):
-	opt.add_option('--protobuf',type='string',default='',dest='protobuf_dir',help='''path to where protobuf is installed, e.g. /usr/local''')
-@conf
-def __protobuf_get_version_file(self,dir):
-	try:
-		return self.root.find_dir(dir).find_node('%s/%s' % ('include', PROTOBUF_VERSION_FILE))
-	except:
-		return None
-@conf
-def protobuf_get_version(self,dir):
-	val=self.check_cxx(fragment=PROTOBUF_VERSION_CODE,includes=['%s/%s' % (dir, 'include')], execute=True, define_ret = True, mandatory=True)
-	return val
-@conf
-def protobuf_get_root(self,*k,**kw):
-	root=k and k[0]or kw.get('path',None)
-	# Logs.pprint ('RED', '   %s' %root)
-	if root and self.__protobuf_get_version_file(root):
-		return root
-	for dir in PROTOBUF_DIR:
-		if self.__protobuf_get_version_file(dir):
-			return dir
-	if root:
-		self.fatal('Protobuf not found in %s'%root)
-	else:
-		self.fatal('Protobuf not found, please provide a --protobuf argument (see help)')
-@conf
-def check_protobuf(self,*k,**kw):
-	if not self.env['CXX']:
-		self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
+    pass
 
-	var=kw.get('uselib_store','PROTOBUF')
-	self.start_msg('Checking Protocol Buffer')
-	root = self.protobuf_get_root(*k,**kw);
-	self.env.PROTOBUF_VERSION=self.protobuf_get_version(root)
+def configure(conf):
+    """
+    """
+    conf.check_cfg(package='protobuf', args=['--cflags', '--libs'], uselib_store='PROTOBUF', mandatory=True)
 
-	self.env['INCLUDES_%s'%var]= '%s/%s' % (root, "include");
-	self.env['LIB_%s'%var] = "protobuf"
-	self.env['LIBPATH_%s'%var] = '%s/%s' % (root, "lib")
+    conf.find_program ('protoc', var='PROTOC', path_list = conf.env['PATH'], mandatory = True)
 
-	self.end_msg(self.env.PROTOBUF_VERSION)
-	if Logs.verbose:
-		Logs.pprint('CYAN','	Protocol Buffer include : %s'%self.env['INCLUDES_%s'%var])
-		Logs.pprint('CYAN','	Protocol Buffer lib     : %s'%self.env['LIB_%s'%var])
-		Logs.pprint('CYAN','	Protocol Buffer libpath : %s'%self.env['LIBPATH_%s'%var])
+@TaskGen.extension('.proto')
+def add_proto(self, node):
+    """
+    Compile PROTOBUF protocol specifications
+    """
+    prototask = self.create_task ("protobuf", node, node.change_ext (".pb"))
+    try:
+        self.compiled_tasks.append (prototask)
+    except AttributeError:
+        self.compiled_tasks = [prototask]
+
+class protobuf(Task.Task):
+    """
+    Task for compiling PROTOBUF protocol specifications
+    """
+    run_str = '${PROTOC} --cpp_out ${TGT[0].parent.abspath()} --proto_path ${SRC[0].parent.abspath()} ${SRC[0].abspath()} -o${TGT[0].abspath()}'
+    color   = 'BLUE'
+
+@TaskGen.feature('cxxshlib')
+@TaskGen.before_method('process_source')
+def dynamic_post(self):
+    if not getattr(self, 'dynamic_source', None):
+        return
+    self.source = Utils.to_list(self.source)
+
+    src = self.bld.path.get_bld().ant_glob (Utils.to_list(self.dynamic_source))
+
+    for cc in src:
+        # Signature for the source
+        cc.sig = Utils.h_file (cc.abspath())
+        # Signature for the header
+        h = cc.change_ext (".h")
+        h.sig = Utils.h_file (h.abspath())
+
+    self.source.extend (src)
diff --git a/wscript b/wscript
index c87bf89..ddba0d8 100644
--- a/wscript
+++ b/wscript
@@ -3,6 +3,8 @@
 VERSION='0.0.1'
 APPNAME='sync'
 
+from waflib import Build, Logs
+
 def options(opt):
     opt.add_option('--debug',action='store_true',default=False,dest='debug',help='''debugging mode''')
     opt.add_option('--log4cxx', action='store_true',default=False,dest='log4cxx',help='''Compile with log4cxx/native NS3 logging support''')
@@ -13,10 +15,12 @@
     opt.load('compiler_cxx')
     opt.load('boost')
     opt.load('doxygen')
-    opt.load('ccnx protobuf ns3', tooldir=["waf-tools"])
+    opt.load('gnu_dirs')
+    opt.load('ccnx ns3 protobuf', tooldir=["waf-tools"])
 
 def configure(conf):
     conf.load("compiler_cxx")
+    conf.load('gnu_dirs')
 
     if not conf.check_cfg(package='openssl', args=['--cflags', '--libs'], uselib_store='SSL', mandatory=False):
       libcrypto = conf.check_cc(lib='crypto',
@@ -62,19 +66,22 @@
         pass
 
     conf.load('protobuf')
-    conf.check_protobuf (path=conf.options.protobuf_dir)
-                   
-
-def pre(bld):
-  bld.exec_command('protoc --cpp_out=. sync-state.proto')
-  bld.exec_command('mv sync-state.pb.h include/')
-  bld.exec_command('mv sync-state.pb.cc model/')
 
 def build (bld):
-    bld.add_pre_fun(pre)
+    bld.post_mode = Build.POST_LAZY
+
+    bld.add_group ("protobuf")
+
+    x = bld (
+        features = ["protobuf"],
+        source = ["model/sync-state.proto"],
+        target = ["model/sync-state.pb"],
+        )
+
+    bld.add_group ("code")
 
     if bld.get_define ("NS3_MODULE"):
-        sync_ns3 = bld.shlib (
+        libsync = bld.shlib (
             target = "sync-ns3",
             features=['cxx', 'cxxshlib'],
             source =  [
@@ -99,18 +106,20 @@
                 'model/sync-seq-no.cc',
                 'model/sync-state.cc',
                 'model/sync-std-name-info.cc',
+                ],
+            dynamic_source = [
                 'model/sync-state.pb.cc',
                 ],
             use = 'BOOST BOOST_IOSTREAMS SSL PROTOBUF ' + ' '.join (['ns3_'+dep for dep in ['core', 'network', 'internet', 'NDNabstraction']]).upper (),
-            includes = ['include', 'include/ns3', 'helper'],
+            includes = ['include', 'model', 'include/ns3', 'helper'],
             )
 
         example = bld.program (
             target = "sync-example",
             features=['cxx', 'cxxprogram'],
             source = ['examples/sync-example.cc'],
-            use = 'sync-ns3',
-            includes = ['include', 'include/ns3', 'helper'],
+            use = 'libsync',
+            includes = ['include', 'model', 'include/ns3', 'helper'],
             )
 
         sync_eval = bld.program (
@@ -120,15 +129,15 @@
                       'evaluation/standard-muc.cc',
                       'evaluation/sync-muc.cc',
                       ],
-            use = 'sync-ns3',
-            includes = ['include', 'include/ns3', 'helper'],
+            use = 'libsync',
+            includes = ['include', 'model', 'include/ns3', 'helper'],
             )
         # from waflib import Utils,Logs,Errors
         # Logs.pprint ('CYAN', program.use)
         
     else:
-        libsync = bld.shlib (
-            target=APPNAME, 
+        libsync = bld (
+            target=APPNAME,
             features=['cxx', 'cxxshlib'],
             source =  [
                 'ccnx/sync-ccnx-wrapper.cc',
@@ -148,10 +157,12 @@
                 'model/sync-seq-no.cc',
                 'model/sync-state.cc',
                 'model/sync-std-name-info.cc',
+                ],
+            dynamic_source = [
                 'model/sync-state.pb.cc',
                 ],
             use = 'BOOST BOOST_IOSTREAMS BOOST_THREAD SSL PROTOBUF CCNX',
-            includes = ['include', 'helper'],
+            includes = ['include', 'model', 'helper'],
             )
         
         # Unit tests
@@ -161,13 +172,27 @@
               source = bld.path.ant_glob(['test/**/*.cc']),
               features=['cxx', 'cxxprogram'],
               use = 'BOOST_TEST sync',
-              includes = ['include', 'helper'],
+              includes = ['include', 'model', 'helper'],
               )
 
         if bld.get_define ("HAVE_LOG4CXX"):
             libsync.use += ' LOG4CXX'
             unittests.use += ' LOG4CXX'
 
+        headers = bld.path.ant_glob(['include/*.h'])
+        headers.extend (bld.path.get_bld().ant_glob(['model/sync-state.pb.h']))
+        bld.install_files ("%s/sync" % bld.env['INCLUDEDIR'], headers)
+
+        pc = bld (
+            features = "subst",
+            source='libsync.pc.in',
+            target='libsync.pc',
+            install_path = '${LIBDIR}/pkgconfig',
+            PREFIX       = bld.env['PREFIX'],
+            INCLUDEDIR   = "%s/sync" % bld.env['INCLUDEDIR'],
+            VERSION      = VERSION,
+            )
+
 # doxygen docs
 from waflib.Build import BuildContext
 class doxy (BuildContext):