Developer FAQ

From Nsnam
Revision as of 18:02, 24 August 2007 by Rajb245 (Talk | contribs) (added a bit about hg diff and hg export for generating patches)

Jump to: navigation, search

Main Page - Current Development - Developer FAQ - Tools - Related Projects - Project Ideas - Summer Projects

Installation - Troubleshooting - User FAQ - HOWTOs - Samples - Models - Education - Contributed Code - Papers

Mercurial repository layout for developers

  1. In your home dir on code.nsnam.org, you will find a new directory named "repositories/username". e.g.: /home/tomh/repositories/tomh. If you create a repository in this directory, it will appear automatically on http://code.nsnam.org
  2. You can obviously ssh to your personal account and manage these repositories
  3. You can push to these repositories with the command: hg push ssh://tomh@code.nsnam.org/repositories/tomh/ns-3-com
  4. You can pull with the usual commands: hg clone http://code.nsnam.org/tomh/ns-3-com
  5. If you want to allow another user to push into your repository, all you have to do is change the unix permissions of your repository to allow this user write permissions. This means that if you want to give everyone write permissions, you can "chmod -R g +rw /home/tomh/repositories/tomh/ns-3-com/". If you want to allow only a smaller subset of users to push, we will need to create unix group which matches this subset
  6. The push command for the main tree is still: hg push ssh://code@code.nsnam.org/repos/ns-3-dev

Mercurial tips

  1. How to undo a commit: Let's suppose you are working on a private repository and you check something in, but some other files were inadvertently checked in, and you want to revert and start over. There are two ways to do this:
    1. hg revert: This can be used to revert the repository to a previous revision number. For example, to revert to changeset number #1000, type hg revert -r 1000 --all. This does not remove your checkin from the repository history. For example, if your mistaken checkin was number 1001, and you revert back to 1000 and then commit, you will be at changeset number 1002 now even though the code matches what was in there at changeset 1000.
    2. hg rollback: This can be used to completely wipe clean the last transaction only (commit, import, push, pull). Use with care-- cannot be undone.
  2. How to rename a file: hg rename old-file-name new-file-name This is preferable to adding the new file name and removing the old file name, because it preserves revision history. Don't forget to commit once you are done.
  3. How to merge a branch: If you have forked a branch repository, have worked on it, and are ready to merge it back to ns-3-dev, here are the steps to take (Also, read this chapter to better understand how the mercurial source tree is structured when merging is occurring):
    1. cd into your branch
    2. hg pull http://code.nsnam.org/ns-3-dev
    3. hg merge
    4. resolve all of the merge issues, if any, and confirm that it builds and validates
    5. hg ci -m"merge your-branch-name with tip"
    6. hg push ssh://code@code.nsnam.org//home/code/repos/ns-3-dev
  4. How to create patches for circulation: hg export tip Suppose you don't have write access to the main repositories, but have some patches you'd like to circulate. This command outputs out all the diffs for the latest changeset you committed into your local repository. Simply redirect this output to a file, and you can circulate your patch for consideration. This is for when you have committed changesets. If you would like to export uncommitted changes as a patch, use: hg diff This gets the diffs of all the uncommitted changes versus what is checked into the repository. Redirect to a file for circulation among developers, or for inclusion with a bug report, etc.

The WAF build system

See also the Waf User FAQ.

Obtaining WAF

Although WAF is distributed with ns-3 releases, when checking out ns-3 from the mercurial repository waf is not included, mainly because it is a large binary, redundant, and is maintained outside ns-3. Therefore ns-3 developers working with mercurial branches have to separately obtain WAF first.

Ns-3 is working with a unreleased version of WAF, from the subversion repository. Although usually the version from the subversion trunk works fine, it represents a development version it can be occasionally be temporarily broken. Therefore a special subversion tag called ns3 exists, pointing to the last version that was tested to work correctly with ns-3. Thus, to obtain WAF the correct command is:

svn checkout http://waf.googlecode.com/svn/tags/ns3/ waf

Alternatively, for greater convenience a snapshot of waf can be downloaded from this url: http://www.nsnam.org/tools/

Note: normally only the file waf is needed. On Unix systems it should be made executable (chmod a+x waf), and then you can run it normally, else you would have to run it with python (python /path/to/waf ...options...). On win32 systems, with the standard command prompt, the file waf.bat can be used to provide the same effect (it is a batch file that automatically runs waf through python).

Documentation resources

There is some incomplete documentation near the bottom of the WAF home page. Some useful tips can be found in the WAF Wiki. Finally, there is a plethora of examples distributed in WAF itself, in the 'demos' directory.

How to add new ns-3 modules

Ns-3 is organized as a set of modules. Each module is built as a separate shared library, has a name, may depend on other modules, and installs a specific set of public header files.

To add a new ns-3 module to the WAF build system, begin by creating a directory under the src/ subtree, with the source files inside. We will use p2p module as example here. Each module needs to define a wscript file. For instance let us see what src/devices/p2p/wscript contains:

## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-

def build(bld):
    p2p = bld.create_obj('cpp', 'shlib')
    p2p.name = 'ns3-p2p'
    p2p.target = p2p.name
    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 wscript file is basically a special python module. The main entry point to this module is the build(bld) python function.

In the code above, the p2p variable represents a shared library, which is also a ns-3 module. The following attributes have to be set:

  • p2p.name: should the module name. By convention (and you should follow the convetion else build breaks) module names are ns3-dirname, where dirname is the directory name of the module. For example, the module under src/devices/p2p is named ns3-p2p;
  • p2p.target: this is the base name of the shared library file. It should normally be the same as p2p.name;
  • p2p.uselib_local: should be set to a list of module names that this module depends on. Dependencies are used when declaring programs, to avoid having to declare an expanded list of all dependencies;
  • p2p.source: this attribute should be set to a list of C++ source files for the module, excluding header files.

There is usually also a headers object. It is used to declare public header files. These files are copied to the build directory, and can be included from any module with #include "ns3/header-name.h".

A final step, after the wscript file is created, is to register it. Open the file src/wscript and add the new module to the all_modules list variable:

all_modules = [
    'core',
    'common',
    'simulator',
    'node',
    'internet-node',
    'devices/p2p', # <---- example here
    'applications',
    ]

To compile with the new module, remember to run waf configure first.

Adding programs

Just create a 'program' waf object and use the attribute uselib_local to specify which modules the program uses. Example:

    obj = bld.create_obj('cpp', 'program')
    obj.target = "sample-internet-program"
    obj.uselib_local = ["ns3-internet-node"]
    obj.source = ['my-source-code.cc']

Submitting patches for consideration

When you send a tree without a detailed summary of your changes, it would help if you could send a list of the changesets you want to merge. To generate it, first merge with ns-3-dev and then, from your modified directory, run "hg outgoing -p http://code.nsnam.org/ns-3-dev"

Also, avoid spurious coding style and whitespace changes when preparing such a patch, as it distracts from the readability of your proposed technical changes.