WAF: simplify wscripts using the new chained uselib_local dependencies feature of WAF SVN; now build all samples and examples; add --disable-rpath configure option; add WAF build instructions.
authorGustavo J. A. M. Carneiro <gjcarneiro@gmail.com>
Sun, 13 May 2007 12:46:18 +0100
changeset 600 fd944dbf33c6
parent 538 3cc417842b5f
child 601 776f776d10d9
WAF: simplify wscripts using the new chained uselib_local dependencies feature of WAF SVN; now build all samples and examples; add --disable-rpath configure option; add WAF build instructions.
BUILD.WAF
examples/wscript
samples/wscript
src/applications/wscript
src/common/wscript
src/core/wscript
src/devices/p2p/wscript
src/devices/wscript
src/internet-node/wscript
src/node/wscript
src/simulator/wscript
src/wscript
utils/wscript
wscript
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BUILD.WAF	Sun May 13 12:46:18 2007 +0100
@@ -0,0 +1,82 @@
+WAF is an alternative build system, similar to SCons.  NS-3 now is
+able to build with WAF, in parallel to SCons.
+
+Note: the WAF build scripts are experimental at this stage.
+
+
+=== Building with WAF ===
+
+To build NS-3 with waf type the commands:
+ 1. ./waf configure [options]
+ 2. ./waf
+
+[ Note: if ./waf does not exist, see the section "Note for developers" below ]
+
+To see valid configure options, type ./waf --help.  The most important
+option is -d <debug level>.  Valid debug levels (which are listed in
+./waf --help) are: ultradebug, debug, release, and optimized.
+
+The resulting binaries are placed in build/<debuglevel>/srcpath.
+
+Other waf usages include:
+
+ 1. ./waf check
+    Runs the unit tests
+
+ 2. ./waf --doxygen
+    Run doxygen to generate documentation
+
+ 3. ./waf --lcov-report
+    Run code coverage analysis (assuming the project was configured
+with --enable-gcov)
+
+=== Extending NS-3 ===
+
+To add new modules:
+  1. Create the module directory under src (or src/devices, or whatever);
+  2. Add the source files to it;
+  3. Add a 'wscript' describing it;
+  4. Add the module subdirectory name to the all_modules list in src/wscript.
+
+A module's wscript file is basically a regular WAF script.  A NS-3
+module is created as a cpp/shlib object, like this:
+
+def build(bld):
+    obj = bld.create_obj('cpp', 'shlib')
+
+    ## set module name; by convention it starts with ns3-
+    obj.name = 'ns3-mymodule'
+    obj.target = obj.name 
+
+    ## list dependencies to other modules
+    obj.uselib_local = ['ns3-core'] 
+
+    ## list source files (private or public header files excluded)
+    obj.source = [
+        'mymodule.cc',
+    ]
+
+    ## list module public header files
+    headers = bld.create_obj('ns3header')
+    headers.source = [
+        'mymodule-header.h',
+    ]
+
+
+=== Note for developers ===
+
+The NS-3 code repository does not contain the waf script.  Instead,
+developers should check it out from a subversion repository:
+
+  svn checkout http://waf.googlecode.com/svn/trunk/ waf
+
+Then it can be installed system-wide with 'sudo ./waf-light install'.
+When preparing a distribution, the resulting 'waf' script, which is
+self contained (no external files needed), can be easily included in
+the tarball so that users downloading NS-3 can easily build it without
+having WAF installed (although Python >= 2.3 is still needed).
+
+The command 'waf dist' can be used to create a distribution tarball.
+It includes all files in the source directory, except some particular
+extensions that are blacklisted, such as back files (ending in ~).
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/wscript	Sun May 13 12:46:18 2007 +0100
@@ -0,0 +1,13 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+import Params
+
+def build(bld):
+    def create_ns_prog(name, source, deps=['core', 'common', 'simulator']):
+        obj = bld.create_obj('cpp', 'program')
+        obj.target = name
+        obj.uselib_local = ["ns3-%s" % dep for dep in deps]
+        obj.source = source
+        return obj
+        
+    obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['p2p', 'internet-node'])
+
--- a/samples/wscript	Fri May 11 10:37:01 2007 -0400
+++ b/samples/wscript	Sun May 13 12:46:18 2007 +0100
@@ -5,26 +5,20 @@
     def create_ns_prog(name, source, deps=['core', 'common', 'simulator']):
         obj = bld.create_obj('cpp', 'program')
         obj.target = name
-        obj.uselib_local = ' '.join(["ns3-%s" % dep for dep in deps])
+        obj.uselib_local = ["ns3-%s" % dep for dep in deps]
         obj.source = source
-        for module in deps:
-            obj.env.append_value('RPATH', r'-Wl,--rpath=\$ORIGIN/../src/%s' % (module,))
         return obj
         
+    obj = create_ns_prog('main-debug', ['main-debug.cc', 'main-debug-other.cc'])
     obj = create_ns_prog('main-callback', 'main-callback.cc')
+    obj = create_ns_prog('main-ptr', 'main-ptr.cc')
+    #obj = create_ns_prog('main-trace', 'main-trace.cc')
     obj = create_ns_prog('main-simulator', 'main-simulator.cc')
     obj = create_ns_prog('main-packet', 'main-packet.cc')
-    #obj = create_ns_prog('main-trace', 'main-trace.cc')
     obj = create_ns_prog('main-test', 'main-test.cc')
-    obj = create_ns_prog('main-ptr', 'main-ptr.cc')
-
-    #obj = create_ns_prog('main-p2p-net-device-if', 'main-p2p-net-device-if.cc',
-    #                     deps=['core', 'common', 'simulator', 'node', 'p2p'])
+    obj = create_ns_prog('main-simple', 'main-simple.cc',
+                         deps=['node', 'internet-node', 'applications'])
+    #obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc', deps=['node', 'p2p'])
+    obj = create_ns_prog('main-default-value', 'main-default-value.cc',
+                         deps=['core', 'simulator', 'node', 'p2p'])
 
-    obj = create_ns_prog('main-simple', 'main-simple.cc',
-                         deps=['core', 'common', 'simulator',
-                               'node', 'internet-node', 'applications'])
-
-    #obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc',
-    #                     deps=['core', 'common', 'simulator', 'node', 'p2p'])
-
--- a/src/applications/wscript	Fri May 11 10:37:01 2007 -0400
+++ b/src/applications/wscript	Sun May 13 12:46:18 2007 +0100
@@ -5,7 +5,7 @@
     obj = bld.create_obj('cpp', 'shlib')
     obj.name = 'ns3-applications'
     obj.target = obj.name
-    obj.deps = ['ns3-node']
+    obj.uselib_local = ['ns3-node']
     obj.source = [
         'application-list.cc',
         'application.cc',
--- a/src/common/wscript	Fri May 11 10:37:01 2007 -0400
+++ b/src/common/wscript	Sun May 13 12:46:18 2007 +0100
@@ -5,7 +5,7 @@
     common = bld.create_obj('cpp', 'shlib')
     common.name = 'ns3-common'
     common.target = common.name
-    common.deps = ['ns3-core', 'ns3-simulator']
+    common.uselib_local = ['ns3-core', 'ns3-simulator']
     common.source = [
         'buffer.cc',
         'header.cc',
--- a/src/core/wscript	Fri May 11 10:37:01 2007 -0400
+++ b/src/core/wscript	Sun May 13 12:46:18 2007 +0100
@@ -23,7 +23,6 @@
     core = bld.create_obj('cpp', 'shlib')
     core.name = 'ns3-core'
     core.target = core.name
-    core.deps = 'ns3-core-headers'
     core.source = [
         'reference-list-test.cc',
         'callback-test.cc',
@@ -52,7 +51,6 @@
             ])
     
     headers = bld.create_obj('ns3header')
-    headers.name = 'ns3-core-headers'
     headers.source = [
         'system-wall-clock-ms.h',
         'reference-list.h',
--- a/src/devices/p2p/wscript	Fri May 11 10:37:01 2007 -0400
+++ b/src/devices/p2p/wscript	Sun May 13 12:46:18 2007 +0100
@@ -5,14 +5,16 @@
     p2p = bld.create_obj('cpp', 'shlib')
     p2p.name = 'ns3-p2p'
     p2p.target = p2p.name
-    p2p.deps = ['ns3-node']
+    p2p.uselib_local = ['ns3-node']
     p2p.source = [
         'p2p-net-device.cc',
         'p2p-channel.cc',
+        'p2p-topology.cc',
         ]
     headers = bld.create_obj('ns3header')
     headers.source = [
         'p2p-net-device.h',
         'p2p-channel.h',
+        'p2p-topology.h',
         ]
 
--- a/src/devices/wscript	Fri May 11 10:37:01 2007 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-def build(bld):
-    bld.add_subdirs('p2p')
-    #bld.add_subdirs('p2p-gfr')
-
--- a/src/internet-node/wscript	Fri May 11 10:37:01 2007 -0400
+++ b/src/internet-node/wscript	Sun May 13 12:46:18 2007 +0100
@@ -5,7 +5,7 @@
     obj = bld.create_obj('cpp', 'shlib')
     obj.name = 'ns3-internet-node'
     obj.target = obj.name
-    obj.deps = ['ns3-node', 'ns3-applications']
+    obj.uselib_local = ['ns3-node', 'ns3-applications']
     obj.source = [
         'internet-node.cc',
         'l3-demux.cc',
--- a/src/node/wscript	Fri May 11 10:37:01 2007 -0400
+++ b/src/node/wscript	Sun May 13 12:46:18 2007 +0100
@@ -5,7 +5,7 @@
     node = bld.create_obj('cpp', 'shlib')
     node.name = 'ns3-node'
     node.target = node.name
-    node.deps = ['ns3-core', 'ns3-common', 'ns3-simulator']
+    node.uselib_local = ['ns3-core', 'ns3-common', 'ns3-simulator']
     node.source = [
         'node.cc',
         'ipv4-address.cc',
--- a/src/simulator/wscript	Fri May 11 10:37:01 2007 -0400
+++ b/src/simulator/wscript	Sun May 13 12:46:18 2007 +0100
@@ -48,7 +48,7 @@
     sim = bld.create_obj('cpp', 'shlib')
     sim.name = 'ns3-simulator'
     sim.target = sim.name
-    sim.deps = 'ns3-simulator-headers ns3-core-headers'
+    sim.uselib_local = ['ns3-core']
 
     sim.source = [
         'high-precision.cc',
@@ -63,7 +63,6 @@
         'simulator.cc',
         ]
     headers = bld.create_obj('ns3header')
-    headers.name = 'ns3-simulator-headers'
     headers.source = [
         'high-precision.h',
         'nstime.h',
--- a/src/wscript	Fri May 11 10:37:01 2007 -0400
+++ b/src/wscript	Sun May 13 12:46:18 2007 +0100
@@ -1,13 +1,43 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
+import Params
+
+all_modules = [
+    'core',
+    'common',
+    'simulator',
+    'node',
+    'internet-node',
+    'devices/p2p',
+    'applications',
+    ]
+
+
 def set_options(opt):
     opt.sub_options('simulator')
+    opt.add_option('--disable-rpath',
+                   help=("Don't link programs with rpath"),
+                   action="store_true", default=False,
+                   dest='disable_rpath')
+
 
 def configure(conf):
     conf.sub_config('core')
     conf.sub_config('simulator')
 
+    conf.env['DISABLE_RPATH'] = Params.g_options.disable_rpath
+
+
 def build(bld):
-    bld.add_subdirs('core common simulator')
-    bld.add_subdirs('node internet-node devices applications')
 
+    ## Add a global RPATH pointing to each module, so that programs can find the libs
+    ## Note: this is slightly evil; we get away because our programs
+    ## and libs are not supposed to be installed system wide.
+    env = bld.env_of_name('default')
+    if not env['DISABLE_RPATH']:
+        for module in all_modules:
+            node = bld.m_curdirnode.find_build(module)
+            env.append_value('RPATH', '-Wl,--rpath=%s' % (node.abspath(env),))
+    
+    bld.add_subdirs(all_modules)
+
--- a/utils/wscript	Fri May 11 10:37:01 2007 -0400
+++ b/utils/wscript	Sun May 13 12:46:18 2007 +0100
@@ -2,21 +2,19 @@
 import sys
 import Params
 
+
 def build(bld):
 
     def create_ns_prog(name, source):
         obj = bld.create_obj('cpp', 'program')
         obj.target = name
-        obj.deps = "ns3-core ns3-common ns3-simulator"
         obj.uselib_local = "ns3-core ns3-common ns3-simulator"
         obj.source = source
-        for module in ['core', 'common', 'simulator']:
-            obj.env.append_value('RPATH', r'-Wl,--rpath=\$ORIGIN/../src/%s' % (module,))
         return obj
 
     unit_tests = create_ns_prog('run-tests', 'run-tests.cc')
-    unit_tests.install_var  = 0 #do not install
-    unit_tests.unit_test    = 1
+    unit_tests.install_var  = 0 # do not install
+    unit_tests.unit_test    = 1 # runs on 'waf check'
     
     #if sys.platform != 'win32':
     obj = create_ns_prog('bench-simulator', 'bench-simulator.cc')
--- a/wscript	Fri May 11 10:37:01 2007 -0400
+++ b/wscript	Sun May 13 12:46:18 2007 +0100
@@ -19,7 +19,7 @@
 blddir = 'build'
 
 class Ns3Header(Object.genobj):
-    """A public NS-3 header file"""
+    """A set of NS-3 header files"""
     def __init__(self, env=None):
         Object.genobj.__init__(self, 'other')
         self.inst_var = 'INCLUDEDIR'
@@ -132,7 +132,7 @@
     bld.m_allenvs['default'] = variant_env # switch to the active variant
     # process subfolders from here
     bld.add_subdirs('src')
-    bld.add_subdirs('samples utils')
+    bld.add_subdirs('samples utils examples')
 
 
 def shutdown():