[tutorial] Introduce more waf options and best work practices.
This commit is contained in:
@@ -33,8 +33,8 @@ from the main web site. The second is to fetch and build development
|
||||
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 @@ The simplest way to get started using Mercurial repositories is to use the
|
||||
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 @@ Let's assume that you, as a user, wish to build |ns3| in a local
|
||||
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 @@ directory under which one can keep local Mercurial repositories.
|
||||
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 @@ following displayed,
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
destination directory: bake
|
||||
requesting all changes
|
||||
adding changesets
|
||||
@@ -143,10 +139,9 @@ following displayed,
|
||||
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 @@ distribution of your choice.
|
||||
|
||||
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 @@ code either by inspection of the repository list or by going to the
|
||||
`"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 @@ bake works by downloading source packages into a source directory,
|
||||
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 @@ However, setting environment variables is not strictly necessary to
|
||||
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 @@ In particular, download tools such as Mercurial, CVS, GIT, and Bazaar
|
||||
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 @@ should yield something like:
|
||||
>> 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 @@ native |ns3| build system, Waf, to be introduced later in this tutorial.
|
||||
|
||||
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 @@ are not necessary for your work, if you wish.
|
||||
|
||||
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 @@ following magic words:
|
||||
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 @@ may continue to use it to build |ns3|. Type
|
||||
|
||||
$ ./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 @@ build the optimized version of the code. By default you have configured
|
||||
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 @@ Now go ahead and switch back to the debug build that includes the examples and t
|
||||
::
|
||||
|
||||
$ ./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 @@ Okay, sorry, I made you build the |ns3| part of the system twice,
|
||||
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
|
||||
|
||||
This allows users to work with multiple builds rather than always
|
||||
overwriting the last build.
|
||||
Combining this with build profiles lets you switch between the different
|
||||
compile options in a clean way::
|
||||
|
||||
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 --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.
|
||||
|
||||
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"
|
||||
|
||||
$ ./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 @@ see a report saying that,
|
||||
|
||||
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 @@ You will also see output from the test runner and the output will actually look
|
||||
|
||||
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 @@ produces the following output.
|
||||
|
||||
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 @@ the actual debug version of the code by typing,
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user