--- a/doc/tutorial/source/getting-started.rst Tue Feb 04 14:04:01 2014 -0500
+++ b/doc/tutorial/source/getting-started.rst Tue Feb 04 16:14:44 2014 -0800
@@ -33,8 +33,8 @@
copies of |ns3|. We'll walk through both examples since the tools
involved are slightly different.
-Downloading ns-3
-****************
+Downloading |ns3|
+*****************
The |ns3| system as a whole is a fairly complex system and has a
number of dependencies on other components. Along with the systems you will
@@ -72,8 +72,8 @@
downloading and building of various subsystems of |ns3| for you. We
recommend that you begin your |ns3| work in this environment.
-Downloading ns-3 Using a Tarball
-++++++++++++++++++++++++++++++++
+Downloading |ns3| Using a Tarball
++++++++++++++++++++++++++++++++++
A tarball is a particular format of software archive where multiple
files are bundled together and the archive possibly compressed.
@@ -85,27 +85,24 @@
directory called ``workspace``.
If you adopt the ``workspace`` directory approach, you can
get a copy of a release by typing the following into your Linux shell
-(substitute the appropriate version numbers, of course):
-
-::
+(substitute the appropriate version numbers, of course)::
$ cd
$ mkdir workspace
$ cd workspace
- $ wget http://www.nsnam.org/releases/ns-allinone-3.17.tar.bz2
- $ tar xjf ns-allinone-3.17.tar.bz2
+ $ wget http://www.nsnam.org/releases/ns-allinone-3.20.tar.bz2
+ $ tar xjf ns-allinone-3.20.tar.bz2
-If you change into the directory ``ns-allinone-3.17`` you should see a
-number of files:
+If you change into the directory ``ns-allinone-3.20`` you should see a
+number of files::
-::
-
- bake constants.py ns-3.17 README
+ $ ls
+ bake constants.py ns-3.20 README
build.py netanim-3.103 pybindgen-0.16.0.825 util.py
You are now ready to build the |ns3| distribution.
-Downloading ns-3 Using Bake
+Downloading |ns3| Using Bake
++++++++++++++++++++++++++++
Bake is a tool for distributed integration and building,
@@ -119,9 +116,7 @@
Any directory name will do, but we'll assume that ``workspace`` is used
herein (note: ``repos`` may also be used in some documentation as
an example directory name). You can get a copy of ``bake`` by typing the
-following into your Linux shell (assuming you have installed Mercurial):
-
-::
+following into your Linux shell (assuming you have installed Mercurial)::
$ cd
$ mkdir workspace
@@ -133,6 +128,7 @@
::
+ ...
destination directory: bake
requesting all changes
adding changesets
@@ -143,10 +139,9 @@
45 files updated, 0 files merged, 0 files removed, 0 files unresolved
After the clone command completes, you should have a directory called
-``bake``, the contents of which should look something like the following:
+``bake``, the contents of which should look something like the following::
-::
-
+ $ ls
bake bakeconf.xml doc generate-binary.py TODO
bake.py examples test
@@ -157,10 +152,10 @@
There are a few configuration targets available:
-1. ``ns-3.17``: the module corresponding to the release; it will download
+1. ``ns-3.20``: the module corresponding to the release; it will download
components similar to the release tarball.
2. ``ns-3-dev``: a similar module but using the development code tree
-3. ``ns-allinone-3.17``: the module that includes other optional features
+3. ``ns-allinone-3.20``: the module that includes other optional features
such as click routing, openflow for |ns3|, and the Network Simulation
Cradle
4. ``ns-3-allinone``: similar to the released version of the allinone
@@ -178,7 +173,7 @@
`"ns-3 Releases"
<http://www.nsnam.org/releases>`_
web page and clicking on the latest release link. We'll proceed in
-this tutorial example with ``ns-3.17``.
+this tutorial example with ``ns-3.20``.
We are now going to use the bake tool to pull down the various pieces of
|ns3| you will be using. First, we'll say a word about running bake.
@@ -187,9 +182,7 @@
and installing libraries into a build directory. bake can be run
by referencing the binary, but if one chooses to run bake from
outside of the directory it was downloaded into, it is advisable
-to put bake into your path, such as follows (Linux bash shell example):
-
-::
+to put bake into your path, such as follows (Linux bash shell example)::
$ export BAKE_HOME=`pwd`/bake
$ export PATH=$PATH:$BAKE_HOME
@@ -199,16 +192,12 @@
complete this tutorial, so we'll call bake directly by specifying the path
to it in our shell commands.
-Step into the workspace directory and type the following into your shell:
+Step into the workspace directory and type the following into your shell::
-::
-
- $ ./bake.py configure -e ns-3.17
+ $ ./bake.py configure -e ns-3.20
Next, we'l ask bake to check whether we have enough tools to download
-various components. Type:
-
-::
+various components. Type::
$ ./bake.py check
@@ -240,15 +229,11 @@
are our principal concerns at this point, since they allow us to fetch
the code. Please install missing tools at this stage if you are able to.
-Next, try to download the software:
-
-::
+Next, try to download the software::
- ./bake.py download
+ $ ./bake.py download
-should yield something like:
-
-::
+should yield something like::
>> Searching for system dependency pygoocanvas - OK
>> Searching for system dependency python-dev - OK
@@ -257,22 +242,21 @@
>> Searching for system dependency g++ - OK
>> Searching for system dependency qt4 - OK
>> Downloading netanim-3.103 - OK
- >> Downloading ns-3.17 - OK
+ >> Downloading ns-3.20 - OK
The above suggests that three sources have been downloaded. Check the
-``source`` directory now and type ``ls``; one should see:
+``source`` directory now and type ``ls``; one should see::
-::
-
- netanim-3.103 ns-3.17 pybindgen-0.16.0.825
+ $ ls
+ netanim-3.103 ns-3.20 pybindgen-0.16.0.825
You are now ready to build the |ns3| distribution.
-Building ns-3
-*************
+Building |ns3|
+**************
-Building with build.py
-++++++++++++++++++++++
+Building with ``build.py``
+++++++++++++++++++++++++++
When working from a released tarball, the first time you build the
|ns3| project you can build using a convenience program found in the
``allinone`` directory. This program is called ``build.py``. This
@@ -283,10 +267,8 @@
If you downloaded
using a tarball you should have a directory called something like
-``ns-allinone-3.17`` under your ``~/workspace`` directory.
-Type the following:
-
-::
+``ns-allinone-3.20`` under your ``~/workspace`` directory.
+Type the following::
$ ./build.py --enable-examples --enable-tests
@@ -299,11 +281,9 @@
You will see lots of typical compiler output messages displayed as the build
script builds the various pieces you downloaded. Eventually you should see the
-following magic words:
+following magic words::
-::
-
- Waf: Leaving directory `/path/to/workspace/ns-allinone-3.17/ns-3.17/build'
+ Waf: Leaving directory `/path/to/workspace/ns-allinone-3.20/ns-3.20/build'
'build' finished successfully (6m25.032s)
Modules built:
@@ -325,17 +305,15 @@
brite click openflow
visualizer
- Leaving directory `./ns-3.17'
+ Leaving directory `./ns-3.20'
-Regarding the portion about modules not built:
-
-::
+Regarding the portion about modules not built::
Modules not built (see ns-3 tutorial for explanation):
brite click openflow
visualizer
-This just means that some ns-3 modules that have dependencies on
+This just means that some |ns3| modules that have dependencies on
outside libraries may not have been built, or that the configuration
specifically asked not to build them. It does not mean that the
simulator did not build successfully or that it will provide wrong
@@ -351,20 +329,16 @@
$ ./bake.py build
-and you should see something like:
-
-::
+and you should see something like::
>> Building pybindgen-0.16.0.825 - OK
>> Building netanim-3.103 - OK
- >> Building ns-3.17 - OK
+ >> Building ns-3.20 - OK
*Hint: you can also perform both steps, download and build by calling 'bake.py deploy'.*
If there happens to be a failure, please have a look at what the following
-command tells you; it may give a hint as to a missing dependency:
-
-::
+command tells you; it may give a hint as to a missing dependency::
$ ./bake.py show
@@ -390,83 +364,96 @@
your project to build the debug version. Let's tell the project to
make an optimized build. To explain to Waf that it should do optimized
builds that include the examples and tests, you will need to execute the
-following commands,
-
-::
+following commands::
$ ./waf clean
- $ ./waf -d optimized --enable-examples --enable-tests configure
+ $ ./waf --build-profile=optimized --enable-examples --enable-tests configure
This runs Waf out of the local directory (which is provided as a convenience
for you). The first command to clean out the previous build is not
-typically strictly necessary but is good practice; it will remove the
+typically strictly necessary but is good practice (but see `Build Profiles`_,
+below); it will remove the
previously built libraries and object files found in directory ``build/``.
When the project is reconfigured and the build system checks for various
dependencies, you should see
-output that looks similar to the following,
-
-::
+output that looks similar to the following::
- Checking for program g++ : ok /usr/bin/g++
- Checking for program cpp : ok /usr/bin/cpp
- Checking for program ar : ok /usr/bin/ar
- Checking for program ranlib : ok /usr/bin/ranlib
- Checking for g++ : ok
- Checking for program pkg-config : ok /usr/bin/pkg-config
- Checking for -Wno-error=deprecated-declarations support : yes
- Checking for -Wl,--soname=foo support : yes
- Checking for header stdlib.h : ok
- Checking for header signal.h : ok
- Checking for header pthread.h : ok
- Checking for high precision time implementation : 128-bit integer
- Checking for header stdint.h : ok
- Checking for header inttypes.h : ok
- Checking for header sys/inttypes.h : not found
- Checking for library rt : ok
- Checking for header netpacket/packet.h : ok
- Checking for pkg-config flags for GSL : ok
- Checking for header linux/if_tun.h : ok
- Checking for pkg-config flags for GTK_CONFIG_STORE : ok
- Checking for pkg-config flags for LIBXML2 : ok
- Checking for library sqlite3 : ok
- Checking for NSC location : ok ../nsc (guessed)
- Checking for library dl : ok
- Checking for NSC supported architecture x86_64 : ok
- Checking for program python : ok /usr/bin/python
- Checking for Python version >= 2.3 : ok 2.5.2
- Checking for library python2.5 : ok
- Checking for program python2.5-config : ok /usr/bin/python2.5-config
- Checking for header Python.h : ok
- Checking for -fvisibility=hidden support : yes
- Checking for pybindgen location : ok ../pybindgen (guessed)
- Checking for Python module pybindgen : ok
- Checking for pybindgen version : ok 0.10.0.640
- Checking for Python module pygccxml : ok
- Checking for pygccxml version : ok 0.9.5
- Checking for program gccxml : ok /usr/local/bin/gccxml
- Checking for gccxml version : ok 0.9.0
- Checking for program sudo : ok /usr/bin/sudo
- Checking for program hg : ok /usr/bin/hg
- Checking for program valgrind : ok /usr/bin/valgrind
+ Setting top to : .
+ Setting out to : build
+ Checking for 'gcc' (c compiler) : /usr/bin/gcc
+ Checking for cc version : 4.2.1
+ Checking for 'g++' (c++ compiler) : /usr/bin/g++
+ Checking boost includes : 1_46_1
+ Checking boost libs : ok
+ Checking for boost linkage : ok
+ Checking for click location : not found
+ Checking for program pkg-config : /sw/bin/pkg-config
+ Checking for 'gtk+-2.0' >= 2.12 : yes
+ Checking for 'libxml-2.0' >= 2.7 : yes
+ Checking for type uint128_t : not found
+ Checking for type __uint128_t : yes
+ Checking high precision implementation : 128-bit integer (default)
+ Checking for header stdint.h : yes
+ Checking for header inttypes.h : yes
+ Checking for header sys/inttypes.h : not found
+ Checking for header sys/types.h : yes
+ Checking for header sys/stat.h : yes
+ Checking for header dirent.h : yes
+ Checking for header stdlib.h : yes
+ Checking for header signal.h : yes
+ Checking for header pthread.h : yes
+ Checking for header stdint.h : yes
+ Checking for header inttypes.h : yes
+ Checking for header sys/inttypes.h : not found
+ Checking for library rt : not found
+ Checking for header netpacket/packet.h : not found
+ Checking for header sys/ioctl.h : yes
+ Checking for header net/if.h : not found
+ Checking for header net/ethernet.h : yes
+ Checking for header linux/if_tun.h : not found
+ Checking for header netpacket/packet.h : not found
+ Checking for NSC location : not found
+ Checking for 'mpic++' : yes
+ Checking for 'sqlite3' : yes
+ Checking for header linux/if_tun.h : not found
+ Checking for program sudo : /usr/bin/sudo
+ Checking for program valgrind : /sw/bin/valgrind
+ Checking for 'gsl' : yes
+ Checking for compilation flag -Wno-error=deprecated-d... support : ok
+ Checking for compilation flag -Wno-error=deprecated-d... support : ok
+ Checking for compilation flag -fstrict-aliasing... support : ok
+ Checking for compilation flag -fstrict-aliasing... support : ok
+ Checking for compilation flag -Wstrict-aliasing... support : ok
+ Checking for compilation flag -Wstrict-aliasing... support : ok
+ Checking for program doxygen : /usr/local/bin/doxygen
---- Summary of optional NS-3 features:
- Threading Primitives : enabled
- Real Time Simulator : enabled
- Emulated Net Device : enabled
- GNU Scientific Library (GSL) : enabled
- Tap Bridge : enabled
+ Build profile : debug
+ Build directory : build
+ Python Bindings : enabled
+ BRITE Integration : not enabled (BRITE not enabled (see option --with-brite))
+ NS-3 Click Integration : not enabled (nsclick not enabled (see option --with-nsclick))
GtkConfigStore : enabled
XmlIo : enabled
+ Threading Primitives : enabled
+ Real Time Simulator : enabled (librt is not available)
+ Emulated Net Device : enabled (<netpacket/packet.h> include not detected)
+ File descriptor NetDevice : enabled
+ Tap FdNetDevice : not enabled (needs linux/if_tun.h)
+ Emulation FdNetDevice : not enabled (needs netpacket/packet.h)
+ PlanetLab FdNetDevice : not enabled (PlanetLab operating system not detected (see option --force-planetlab))
+ Network Simulation Cradle : not enabled (NSC not found (see option --with-nsc))
+ MPI Support : enabled
+ NS-3 OpenFlow Integration : not enabled (Required boost libraries not found, missing: system, signals, filesystem)
SQlite stats data output : enabled
- Network Simulation Cradle : enabled
- Python Bindings : enabled
- Python API Scanning Support : enabled
+ Tap Bridge : not enabled (<linux/if_tun.h> include not detected)
+ PyViz visualizer : enabled
Use sudo to set suid bit : not enabled (option --enable-sudo not selected)
Build tests : enabled
Build examples : enabled
- Static build : not enabled (option --enable-static not selected)
- 'configure' finished successfully (2.870s)
+ GNU Scientific Library (GSL) : enabled
+ 'configure' finished successfully (1.944s)
-Note the last part of the above output. Some ns-3 options are not enabled by
+Note the last part of the above output. Some |ns3| options are not enabled by
default or require support from the underlying system to work properly.
For instance, to enable XmlTo, the library libxml-2.0 must be found on the
system. If this library were not found, the corresponding |ns3| feature
@@ -479,7 +466,7 @@
::
$ ./waf clean
- $ ./waf -d debug --enable-examples --enable-tests configure
+ $ ./waf --build-profile=debug --enable-examples --enable-tests configure
The build system is now configured and you can build the debug versions of
the |ns3| programs by simply typing
@@ -492,72 +479,146 @@
but now you know how to change the configuration and build optimized code.
Here are a few more introductory tips about Waf.
-Some waf commands are meaningful during the build phase and some commands are valid
-in the configuration phase. For example, if you wanted to use the emulation
+
+Configure vs. Build
+===================
+
+Some Waf commands are only meaningful during the configure phase and some commands are valid
+in the build phase. For example, if you wanted to use the emulation
features of |ns3|, you might want to enable setting the suid bit using
sudo as described above. This turns out to be a configuration-time command, and so
-you could reconfigure using the following command that also includes the examples and tests
+you could reconfigure using the following command that also includes the examples and tests.
::
- $ ./waf configure -d debug --enable-sudo --enable-examples --enable-tests
+ $ ./waf configure --enable-sudo --enable-examples --enable-tests
-If you do this, waf will have run sudo to change the socket creator programs of the
-emulation code to run as root. There are many other configure- and build-time options
-available in waf. To explore these options, type:
+If you do this, Waf will have run sudo to change the socket creator programs of the
+emulation code to run as root.
-::
+There are many other configure- and build-time options
+available in Waf. To explore these options, type::
$ ./waf --help
We'll use some of the testing-related commands in the next section.
-Finally, as an aside, it is possible to specify that waf builds the
-project in
-a directory different than the default ``build/`` directory by passing
-the ``-o`` option to configure; e.g.
+Build Profiles
+==============
+
+We already saw how you can configure Waf for ``debug`` or ``optimized`` builds::
+
+ $ ./waf --build-profile=debug
+
+There is also an intermediate build profile, ``release``. ``-d`` is a
+synonym for ``--build-profile``.
+
+By default Waf puts the build artifacts in the ``build`` directory.
+You can specify a different output directory with the ``--out``
+option, e.g.
::
- $ ./waf configure -d debug -o build/debug --enable-examples --enable-tests
+ $ ./waf configure --out=foo
+
+Combining this with build profiles lets you switch between the different
+compile options in a clean way::
+
+ $ ./waf configure --build-profile=debug --out=build/debug
+ $ ./waf build
+ ...
+ $ ./waf configure --build-profile=optimized --out=build/optimized
+ $ ./waf build
+ ...
+
+This allows you to work with multiple builds rather than always
+overwriting the last build. When you switch, Waf will only compile
+what it has to, instead of recompiling everything.
-This allows users to work with multiple builds rather than always
-overwriting the last build.
+When you do switch build profiles like this, you have to be careful
+to give the same configuration parameters each time. It may be convenient
+to define some environment variables to help you avoid mistakes::
+
+ $ export NS3CONFIG="--enable-examples --enable-tests"
+ $ export NS3DEBUG="--build-profile=debug --out=build/debug"
+ $ export NS3OPT=="--build-profile=optimized --out=build/optimized"
-In the examples above, waf uses GCC C++ compiler, command ``g++``, for
-building ns-3. However, it's possible to change C++ compiler used by waf.
-Say one wants to use Clang C++ compiler, command ``clang++``; it's done by
+ $ ./waf configure $NS3CONFIG $NS3DEBUG
+ $ ./waf build
+ ...
+ $ ./waf configure $NS3CONFIG $NS3OPT
+ $ ./waf build
+
+Compilers
+=========
+
+In the examples above, Waf uses the GCC C++ compiler, ``g++``, for
+building |ns3|. However, it's possible to change the C++ compiler used by Waf
+by defining the ``CXX`` environment variable.
+For example, to use the Clang C++ compiler, ``clang++``,
::
$ CXX="clang++" ./waf configure
$ ./waf build
-One can also set up waf to do distributed compilation with ``distcc`` in
-a similar way:
-
-::
+One can also set up Waf to do distributed compilation with ``distcc`` in
+a similar way::
$ CXX="distcc g++" ./waf configure
$ ./waf build
-More info on distcc and distributed compilation can be found on it's
+More info on ``distcc`` and distributed compilation can be found on it's
`project page
<http://code.google.com/p/distcc/>`_
under Documentation section.
-Testing ns-3
-************
+One Waf
+=======
+
+There is only one Waf script, at the top level of the |ns3| source tree.
+As you work, you may find yourself spending a lot of time in ``scratch/``,
+or deep in ``src/...``, and needing to invoke Waf. You could just
+remember where you are, and invoke Waf like this::
+
+ $ ../../../waf ...
+
+but that get's tedious, and error prone, and there are better solutions.
+
+If you have the full |ns3| repository this little gem is a start::
+
+ $ cd $(hg root) && ./waf ...
+
+Even better is to define this as a shell function::
+
+ $ function waff { cd $(hg root) && ./waf $* ; }
+
+ $ waff build
+
+If you only have the tarball, an environment variable can help::
+
+ $ export NS3DIR="$PWD"
+ $ function waff { cd $NS3DIR && ./waf $* ; }
+
+ $ cd scratch
+ $ waff build
+
+It might be tempting in a module directory to add a trivial ``waf``
+script along the lines of ``exec ../../waf``. Please don't. It's
+confusing to new-comers, and when done poorly it leads to subtle build
+errors. The solutions above are the way to go.
+
+
+Testing |ns3|
+*************
You can run the unit tests of the |ns3| distribution by running the
-"./test.py -c core" script,
-
-::
+``./test.py -c core`` script::
$ ./test.py -c core
-These tests are run in parallel by waf. You should eventually
-see a report saying that,
+These tests are run in parallel by Waf. You should eventually
+see a report saying that
::
@@ -565,9 +626,8 @@
This is the important message.
-You will also see output from the test runner and the output will actually look something like,
-
-::
+You will also see the summary output from Waf and the test runner
+executing each test, which will actually look something like::
Waf: Entering directory `/path/to/workspace/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/path/to/workspace/ns-3-allinone/ns-3-dev/build'
@@ -590,34 +650,26 @@
PASS: TestSuite ns3-wifi-interference
PASS: TestSuite histogram
- PASS: TestSuite sample
- PASS: TestSuite ipv4-address-helper
- PASS: TestSuite devices-wifi
- PASS: TestSuite propagation-loss-model
...
- PASS: TestSuite attributes
- PASS: TestSuite config
- PASS: TestSuite global-value
- PASS: TestSuite command-line
- PASS: TestSuite basic-random-number
PASS: TestSuite object
PASS: TestSuite random-number-generators
92 of 92 tests passed (92 passed, 0 failed, 0 crashed, 0 valgrind errors)
This command is typically run by users to quickly verify that an
-|ns3| distribution has built correctly.
+|ns3| distribution has built correctly. (Note the order of the ``PASS: ...``
+lines can vary, which is okay. What's important is that the summary line at
+the end report that all tests passed; none failed or crashed.)
Running a Script
****************
+
We typically run scripts under the control of Waf. This allows the build
system to ensure that the shared library paths are set correctly and that
the libraries are available at run time. To run a program, simply use the
``--run`` option in Waf. Let's run the |ns3| equivalent of the
-ubiquitous hello world program by typing the following:
-
-::
+ubiquitous hello world program by typing the following::
$ ./waf --run hello-simulator
@@ -629,28 +681,26 @@
Hello Simulator
-*Congratulations. You are now an ns-3 user.*
+Congratulations! You are now an ns-3 user!
-*What do I do if I don't see the output?*
+**What do I do if I don't see the output?**
-If you see ``waf`` messages indicating that the build was
+If you see Waf messages indicating that the build was
completed successfully, but do not see the "Hello Simulator" output,
-chances are that you have switched your build mode to "optimized" in
-the "Building with Waf" section, but have missed the change back to
-"debug" mode. All of the console output used in this tutorial uses a
+chances are that you have switched your build mode to ``optimized`` in
+the `Building with Waf`_ section, but have missed the change back to
+``debug`` mode. All of the console output used in this tutorial uses a
special |ns3| logging component that is useful for printing
user messages to the console. Output from this component is
automatically disabled when you compile optimized code -- it is
"optimized out." If you don't see the "Hello Simulator" output,
-type the following,
+type the following::
-::
+ $ ./waf configure --build-profile=debug --enable-examples --enable-tests
- $ ./waf configure -d debug --enable-examples --enable-tests
-
-to tell ``waf`` to build the debug versions of the |ns3|
+to tell Waf to build the debug versions of the |ns3|
programs that includes the examples and tests. You must still build
-the actual debug version of the code by typing,
+the actual debug version of the code by typing
::
@@ -659,7 +709,80 @@
Now, if you run the ``hello-simulator`` program, you should see the
expected output.
-If you want to run programs under another tool such as gdb or valgrind,
-see this `wiki entry
-<http://www.nsnam.org/wiki/User_FAQ#How_to_run_NS-3_programs_under_another_tool>`_.
+Program Arguments
++++++++++++++++++
+
+To feed command line arguments to an |ns3| program use this pattern::
+
+ $ ./waf --run <ns3-program> --command-template="%s <args>"
+
+Substitute your program name for ``<ns3-program>``, and the arguments
+for ``<args>``. The ``--command-template`` argument to Waf is
+basically a recipe for constructing the actual command line Waf should use
+to execute the program. Waf checks that the build is complete,
+sets the shared library paths, then invokes the executable
+using the provided command line template,
+inserting the program name for the ``%s`` placeholder.
+(I admit this is a bit awkward, but that's the way it is. Patches welcome!)
+
+Another particularly useful example is to run the ``mytest`` test suite
+by itself. Above, we used the ``./test.py`` script to run a whole slew of
+tests in parallel, by repeatedly invoking the real testing program,
+``test-runner``. To invoke ``test-runner`` directly for a single test::
+
+ $ ./waf --run test-runner --command-template="% --suite=mytest --verbose"
+
+This passes the arguments to the ``test-runner`` program. To print the
+available ``test-runner`` options::
+
+ $ ./waf --run test-runner --command-template="% --help"
+
+Debugging
++++++++++
+
+To run |ns3| programs under the control of another utility, such as
+a debugger (*e.g.* ``gdb``) or memory checker (*e.g.* ``valgrind``),
+you use a similar ``--command-template="..."`` form.
+
+For example, to run your |ns3| program ``mysim`` with the arguments
+``<args>`` under the ``gdb`` debugger::
+ $ ./waf --run=hello-simulator --command-template="gdb %s --args <args>"
+
+Notice that the |ns3| program name goes with the ``--run`` argument,
+and the control utility (here ``gdb``) is the first token
+in the ``--commmand-template`` argument. The ``--args`` tells ``gdb``
+that the remainder of the command line belongs to the "inferior" program.
+(Some ``gdb``'s don't understand the ``--args`` feature. In this case,
+omit the program arguments from the ``--command-template``,
+and use the ``gdb`` command ``set args``.)
+
+We can combine this recipe and the previous one to run a test under the
+debugger::
+
+ $ ./waf --run test-runner --command-template="gdb %s --args --suite=mytest --verbose"
+
+Working Directory
++++++++++++++++++
+
+Waf needs to run from it's location at the top of the |ns3| tree.
+This becomes the working directory where output files will be written.
+But what if you want to keep those ouf to the |ns3| source tree? Use
+the ``--cwd`` argument::
+
+ $ ./waf --cwd=...
+
+It may be more convenient to start with your working directory where
+you want the output files, in which case a little indirection can help::
+
+ $ function waff {
+ CWD="$PWD"
+ cd $NS3DIR >/dev/null
+ ./waf --cwd="$CWD" $*
+ cd - >/dev/null
+ }
+
+This embellishment of the previous version saves the current working directory,
+``cd``'s to the Waf directory, then instructs Waf to change the working
+directory *back* to the saved current working directory before running the
+program.