diff --git a/.hgtags b/.hgtags index 35fb54f89..bff7cf994 100644 --- a/.hgtags +++ b/.hgtags @@ -2,3 +2,4 @@ 7ac5a4b0969b255c4824c926c2b37ef450136ce9 release ns-3.0.2 0dc81e76166c56aaae64da48b673b62155943aad packet-history-working 38099dd26e9467b8f49f8632f22789858149a6e7 release ns-3.0.3 +5701e60bf01a8ac1308945e69001e0cc07948faf release ns-3.0.4 diff --git a/RELEASE_NOTES b/RELEASE_NOTES index ae53a615f..9de1ba7c1 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -3,6 +3,14 @@ This file contains ns-3 release notes (most recent releases first). +Release 3.0.4 (2007/07/15) +======================== + + - Enable waf as the default build system. + - Per-packet metadata: a system to track which headers and trailers + are added to a packet + - Simplifications to point-to-point devices and channel + Release 3.0.3 (2007/06/15) ======================== diff --git a/SConstruct b/SConstruct index eb287a041..6d2a8c0b9 100644 --- a/SConstruct +++ b/SConstruct @@ -24,7 +24,6 @@ ns3.add_extra_dist ('RELEASE_NOTES') ns3.add_extra_dist ('AUTHORS') ns3.add_extra_dist ('VERSION') -ns3.add_extra_dist('doc/build-waf.txt') ns3.add_extra_dist('ns3/_placeholder_') for wscript in [ "src/core/wscript", @@ -41,7 +40,6 @@ for wscript in [ "wscript", ]: ns3.add_extra_dist(wscript) -ns3.add_extra_dist('waf') ns3.add_extra_dist('waf.bat') diff --git a/VERSION b/VERSION index 75a22a26a..b0f2dcb32 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.3 +3.0.4 diff --git a/doc/build-waf.txt b/doc/build-waf.txt deleted file mode 100644 index 42bc70eb1..000000000 --- a/doc/build-waf.txt +++ /dev/null @@ -1,114 +0,0 @@ -The main ns-3 build system is SCons. Read the file build.txt -for SCons instructions. - -Waf is an alternative build system, similar to SCons. ns-3 now is -able to build with Waf, in parallel to SCons. - -(http://www.freehackers.org/~tnagy/waf.html) - -Note: the Waf build scripts are experimental at this stage. -Gustavo Carneiro (gjcarneiro@gmail.com) is the maintainer. - -=== Building with Waf === - -To build ns-3 with waf type the commands: - 1. waf configure [options] - 2. waf - -[ Note: if waf does not exist in your path, see the section -"Note for developers" below ] - -To see valid configure options, type waf --help. The most important -option is -d . Valid debug levels (which are listed in -waf --help) are: ultradebug, debug, release, and optimized. It is -also possible to change the flags used for compilation with (e.g.): -CXXFLAGS="-O3" waf configure. - -[ Note: Unlike some other build tools, to change the build target, -the option must be supplied during the configure stage rather than -the build stage (i.e., "waf -d optimized" will not work; instead, do -"waf -d optimized configure; waf" ] - -The resulting binaries are placed in build//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) - - 4. waf --run "program [args]" - Run a ns3 program, given its target name, with the given - arguments. This takes care of automatically modifying the the - path for finding the ns3 dynamic libraries in the environment - before running the program. Note: the "program [args]" string is - parsed using POSIX shell rules. - - 5. waf --shell - Starts a nested system shell with modified environment to run ns3 programs. - - 6. waf distclean - Cleans out the entire build/ directory - - 7. waf dist - 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 ~). - - -=== 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/tags/ns3/ waf - -[ note: 'tags/ns3' is a tag that represents the last svn version -tested to work correctly with ns3, although 'trunk' will likely work - as well ] - -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). - diff --git a/doc/build.txt b/doc/build.txt index e724529d3..bfb2b518d 100644 --- a/doc/build.txt +++ b/doc/build.txt @@ -1,186 +1,115 @@ -If you want to build ns3, you need to install scons (see -http://www.scons.org). scons takes care of building -the whole source tree using your system compiler. scons -0.91.1 and 0.91.96 have been tested and are known to -work on linux FC5, Mac os X and MinGW. +The Waf build system is used to build ns-3. Waf is a Python-based +build system (http://www.freehackers.org/~tnagy/waf.html) -To start a build, you can just type 'scons' which -will generate a debug shared build by default, located -in the directory 'build-dir/dbg-shared/bin' and -'build-dir/dbg-shared/lib'. +=== Installing Waf === -All builds are built with debugging symbols. Debugging -builds enable asserts while optimized builds disable them. -On platforms which support it, rpath is used which means that -the executable binaries generated link explicitely against -the right libraries. This saves you the pain of having to -setup environment variables to point to the right libraries. +If this file is part of a development release tarball, the top-level +ns-3 directory should contain a current waf script. -(Note: An alternative build system (Waf) is being -evaluated in the development branch of ns-3-dev on our server -only (i.e., not in the release tarballs)-- see doc/build-waf.txt) +However, the ns-3 Mercurial code repository does not contain the waf +script. Instead, developers should check it out from a subversion +repository: -1) Options ----------- + svn checkout http://waf.googlecode.com/svn/tags/ns3/ waf -- verbose: if you have installed scons 0.91.96 or higher, - the default build output is terse. To get a more verbose - output, you need to set the 'verbose' variable to 'y'. -Example: scons verbose=y -- cflags: flags for the C compiler. -Example: scons cflags="-O3 -ffast-math" -- cxxflags: flags for the C++ compiler. -Example: scons cxxflags="-O3 -ffast-math" -- ldflags: flags for the linker: -Example: scons ldflags="-L/foo -L/bar" -- cc: the C compiler to use: -Example: scons cc=gcc-4.0 -- cxx: the C++ compiler to use: -Example: scons cxx=g++-4.0 -- high-precision-as-double: set to 'y' to make sure that the - high-precision arithmetics performed by the Time class on - behalf of the user will use doubles. By default, the code - uses 128 integers. -Example: scons high-precision-as-double=y -- inheritenv: set to 'y' if you want to make your compiler - execute within the same environment (env vars) as your own - shell. This is typically used to make colorgcc work. -Example: scons inheritenv=y +[ note: 'tags/ns3' is a tag that represents the last svn version +tested to work correctly with ns3, although 'trunk' will likely work + as well ] -2) Targets ----------- +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). -- doc: build the doxygen documentation. -Example: scons doc +=== Building with Waf === -- dbg-shared: a debug build using shared libraries. - The files are built in 'build-dir/dbg-shared/'. -Example: scons dbg-shared +To build ns-3 with waf type the commands: + 1. waf configure [options] + 2. waf -- dbg-static: a debug build using static libraries - The files are built in 'build-dir/dbg-static/'. -Example: scons dbg-static +To see valid configure options, type waf --help. The most important +option is -d . Valid debug levels (which are listed in +waf --help) are: ultradebug, debug, release, and optimized. It is +also possible to change the flags used for compilation with (e.g.): +CXXFLAGS="-O3" waf configure. -- opt-shared: an optimized build using shared libraries. - The files are built in 'build-dir/opt-shared/'. -Example: scons opt-shared +[ Note: Unlike some other build tools, to change the build target, +the option must be supplied during the configure stage rather than +the build stage (i.e., "waf -d optimized" will not work; instead, do +"waf -d optimized configure; waf" ] -- opt-static: an optimized build using static libraries. - The files are built in 'build-dir/opt-static/'. -Example: scons opt-static +The resulting binaries are placed in build//srcpath. -- dbg: an alias for dbg-shared -Example: scons dbg +Other waf usages include: -- opt: an alias for opt-shared -Example: scons opt + 1. waf check + Runs the unit tests -- all: alias for dbg-shared, dbg-static, opt-shared - and opt-static -Example: scons all + 2. waf --doxygen + Run doxygen to generate documentation -- gcov: code coverage analysis. Build a debugging version of - the code for code coverage analysis in 'build-dir/gcov'. Once - the code has been built, you can run various applications to - exercise the code paths. To generate an html report from - the gcov data, use the lcov-report target + 3. waf --lcov-report + Run code coverage analysis (assuming the project was configured +with --enable-gcov) -- lcov-report: generate html report of gcov data. The output - is stored in 'build-dir/lcov-report/'. + 4. waf --run "program [args]" + Run a ns3 program, given its target name, with the given + arguments. This takes care of automatically modifying the the + path for finding the ns3 dynamic libraries in the environment + before running the program. Note: the "program [args]" string is + parsed using POSIX shell rules. -- dist: generate a release tarball and zipfile from the - source tree. The tarball and zipfile name are generated - according to the version number stored in the SConstruct - file. -Example in SConstruct: -ns3 = Ns3 () -ns3.name = 'foo' -ns3.version = '0.0.10' -Example command: scons dist -Example output files: -foo-0.0.10.tar.gz -foo-0.0.10.zip + 4.1 waf --run programname --command-template "... %s ..." -- distcheck: generate a release tarball and zipfile and - attempt to run the 'all' target for the release tarball. -Example: scons distcheck + Same as --run, but uses a command template with %s replaced by the + actual program (whose name is given by --run). This can be use to + run ns-3 programs with helper tools. For example, to run unit + tests with valgrind, use the command: -3) How the build system works ------------------------------ + waf --run run-tests --command-template "valgrind %s" -The current build system defines what are called "ns3 modules": each module -is a set of source files, normal header files and installable header -files. Each module also depends on a set of other modules. We build -modules automatically in the correct order. That is, we always start -from the module which does not depend on any other module (core) and -proceed with the other modules and make sure that when a module is -built, all the modules it depends upon have already been built. + 5. waf --shell + Starts a nested system shell with modified environment to run ns3 programs. -To build a module, we: -1) generate the .o files -2) link the .o files together -3) install the installable headers in the common directory -top_build_dir/include/ns3. + 6. waf distclean + Cleans out the entire build/ directory -This means that if you want to use a header from your own module, you -should just include it: #include "foo.h" but if you want to include a -header from another module, you need to include it with #include -"ns3/bar.h". This allows you to make sure that our "public" ns3 headers -do not conflict with existing system-level headers. For instance, -if you were to define a header called queue.h, you would include -ns3/queue.h rather than queue.h, when including from a separate module, -since many systems provide a queue.h system include file. + 7. waf dist + 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 ~). -4) How to add files to a module ? ---------------------------------- -In the main SConstruct file, you can add source code -to the add_sources method. For example, to add a foo.cc -file to the core module, we coud do this: -core.add_sources ('foo.cc') -Of course, if this file implements public API, its -header should be installable: -core.add_inst_headers ('foo.h') +=== Extending ns-3 === -5) How to create a new module ? -------------------------------- +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. -# create a new module. First arg is the name of -# the new module. Second arg is the directory in -# which all source files for this module reside. -my_module = build.Ns3Module ('my', 'src/my_dir') -# add it to build system -ns3.add (my_module) -# specify module dependencies. Here, depends -# on the 'ipv4' and 'core' modules -my_module.add_deps (['core', 'ipv4']) -# add source code to build located in -# src/my_dir -my_module.add_sources ([ - 'my_a.cc', - 'my_b.cc', - 'my_c.cc' -]) -my_module.add_sources ([ - 'my_d.cc' -]) -# add headers which are not public -my_module.add_headers ([ - 'my_a.h', - 'my_c.h' -]) -# add headers which are public -my_module.add_inst_headers ([ - 'my_b.h' -]) -my_module.add_inst_headers ([ - 'my_d.h' -]) -# if you need to link against an external library, -# you must add 'external' dependencies. Here, the -# pthread library -my_module.add_external_dep ('pthread') -# by default, a module is conceptually a library. If you -# want to generate an executable from a module you need to: -my_module.set_executable () +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', + ] diff --git a/doc/release_steps.txt b/doc/release_steps.txt index e5c17ddfc..689013ce6 100644 --- a/doc/release_steps.txt +++ b/doc/release_steps.txt @@ -5,15 +5,23 @@ Steps in doing an ns-3 release - revise and check in RELEASE_NOTES - update and check in VERSION to the latest release number 2. make a new "architecture.pdf" document and place it in the doc/ directory -3. scons dist -4. test tarball on release platforms (run-tests and simple-p2p) -5. tag ns-3-dev with "release ns-3.0.X" -6. clone the ns-3-dev and place it on the repository -7. upload "ns-3.0.x.tar.gz" to the releases/ directory on the server -8. update web page +3. add current version of waf script from subversion: + - svn checkout http://waf.googlecode.com/svn/tags/ns3/ waf + - build waf script and put it into top of ns-3-dev +4. cd ns-3-dev; ./waf configure; ./waf dist +5. test tarball on release platforms (run-tests and simple-p2p) +6. tag ns-3-dev with "release ns-3.0.X" + - hg tag "release ns-3.0.x" + - hg push +7. clone the tagged ns-3-dev and place it on the repository + - ssh code.nsnam.org; sudo; su code; + - cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.0.x + - cd /home/code/repos/ns-3.0.x/.hg and edit the hgrc appropriately +8. upload "ns-3.0.x.tar.bz2" to the releases/ directory on the server +9. update web page - add link to news.html - update download.html - update roadmap.html - build and update Doxygen directory on the server - update and upload software architecture document (PDF, HTML) -9. announce to ns-developers, with summary of release notes +10. announce to ns-developers, with summary of release notes diff --git a/wscript b/wscript index bfa1d96de..35c17074a 100644 --- a/wscript +++ b/wscript @@ -1,5 +1,4 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -import os import sys import shlex import shutil @@ -66,8 +65,14 @@ def set_options(opt): dest='doxygen') opt.add_option('--run', - help=('Run a locally built program'), + help=('Run a locally built program; argument can be a program name,' + ' or a command starting with the program name.'), type="string", default='', dest='run') + opt.add_option('--command-template', + help=('Template of the command used to run the program given by --run;' + ' It should be a shell command string containing %s inside,' + ' which will be replaced by the actual program.'), + type="string", default=None, dest='command_template') opt.add_option('--shell', help=('Run a shell with an environment suitably modified to run locally built programs'), @@ -163,7 +168,11 @@ def shutdown(): doxygen() if Params.g_options.run: - run_program(Params.g_options.run) + run_program(Params.g_options.run, Params.g_options.command_template) + raise SystemExit(0) + + if Params.g_options.command_template: + Params.fatal("Option --command-template requires the option --run to be given") def _find_program(program_name, env): launch_dir = os.path.abspath(Params.g_cwd_launch) @@ -212,33 +221,58 @@ def _run_argv(argv): retval = subprocess.Popen(argv, env=os_env).wait() if retval: - raise SystemExit(retval) + Params.fatal("Command %s exited with code %i" % (argv, retval)) -def run_program(program_string): +def run_program(program_string, command_template=None): + """ + if command_template is not None, then program_string == program + name and argv is given by command_template with %s replaced by the + full path to the program. Else, program_string is interpreted as + a shell command with first name being the program name. + """ env = Params.g_build.env_of_name('default') - argv = shlex.split(program_string) - program_name = argv[0] - try: - program_obj = _find_program(program_name, env) - except ValueError, ex: - Params.fatal(str(ex)) + if command_template is None: + argv = shlex.split(program_string) + program_name = argv[0] - try: - program_node, = program_obj.m_linktask.m_outputs - except AttributeError: - Params.fatal("%s does not appear to be a program" % (program_name,)) + try: + program_obj = _find_program(program_name, env) + except ValueError, ex: + Params.fatal(str(ex)) + + try: + program_node, = program_obj.m_linktask.m_outputs + except AttributeError: + Params.fatal("%s does not appear to be a program" % (program_name,)) + + execvec = [program_node.abspath(env)] + argv[1:] + + else: + + program_name = program_string + try: + program_obj = _find_program(program_name, env) + except ValueError, ex: + Params.fatal(str(ex)) + try: + program_node, = program_obj.m_linktask.m_outputs + except AttributeError: + Params.fatal("%s does not appear to be a program" % (program_name,)) + + execvec = shlex.split(command_template % (program_node.abspath(env),)) - execvec = [program_node.abspath(env)] + argv[1:] former_cwd = os.getcwd() os.chdir(Params.g_cwd_launch) try: - return _run_argv(execvec) + retval = _run_argv(execvec) finally: os.chdir(former_cwd) + return retval + def run_shell(): if sys.platform == 'win32':