src/internet-stack/wscript
author Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
Mon, 29 Dec 2008 13:28:54 +0000
changeset 4064 10222f483860
parent 3977 4daeb41d7fc1
child 4065 f18c257dd25e
permissions -rw-r--r--
Upgrade to new WAF, work in progress

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

import Options
import Logs
import Utils
import Task

# Mercurial repository of the network simulation cradle
NSC_REPO = "https://secure.wand.net.nz/mercurial/nsc"
NSC_RELEASE_URL = "http://research.wand.net.nz/software/nsc"
NSC_RELEASE_NAME = "nsc-0.5.0"

# directory that contains network simulation cradle source
# note, this path is relative to the project root
NSC_DIR = "nsc"


def set_options(opt):
    opt.add_option('--enable-nsc',
                   help=('Enable Network Simulation Cradle to allow the use real-world network stacks'),
                   action="store_true", default=False,
                   dest='enable_nsc')


def nsc_fetch():
    def nsc_clone():
        print "Retrieving nsc from " + NSC_REPO
        if os.system("hg version > /dev/null 2>&1") != 0:
            raise Utils.WafError("Mercurial not installed, http fallback not yet implemented")
        if os.system("hg  clone " + NSC_REPO) != 0:
            raise Utils.WafError("hg -q clone %s failed" % NSC_REPO)

    def nsc_update():
        if os.system("hg version > /dev/null 2>&1") != 0:
            Logs.warn("Mercurial not installed, not updating nsc source")

        print "Pulling nsc updates from " + NSC_REPO
        if os.system("cd nsc && hg pull %s && hg update" % NSC_REPO) != 0:
            Logs.warn("Updating nsc using mercurial failed")

    def nsc_download():
        local_file = NSC_RELEASE_NAME + ".tar.bz2"
        remote_file = NSC_RELEASE_URL + "/" + local_file
        print "Retrieving nsc from " + remote_file
        urllib.urlretrieve(remote_file, local_file)
        print "Uncompressing " + local_file
        os.system("tar -xjf " + local_file)
        os.system('mv ' + NSC_RELEASE_NAME + ' nsc')

    if not os.path.exists('.hg'):
        nsc_download ()
    elif not os.path.exists("nsc"):
        nsc_clone()
    else:
        nsc_update()

def configure(conf):
    conf.env['ENABLE_NSC'] = False

    # checks for flex and bison, which is needed to build NSCs globaliser
    def check_nsc_buildutils():
        import flex
        import bison
        conf.check_tool('flex bison')
        conf.check(lib='fl', mandatory=True)

    if not Options.options.enable_nsc:
        conf.report_optional_feature("nsc", "Network Simulation Cradle", False,
                                     "--enable-nsc configure option not given")
	return

    check_nsc_buildutils()

    arch = os.uname()[4]
    ok = False
    if arch == 'x86_64' or arch == 'i686' or arch == 'i586' or arch == 'i486' or arch == 'i386':
        conf.env['NSC_ENABLED'] = 'yes'
        conf.env.append_value('CXXDEFINES', 'NETWORK_SIMULATION_CRADLE')
        conf.env['ENABLE_NSC'] = conf.check(mandatory=True, lib='dl', define_name='HAVE_DL', uselib='DL')
        ok = True
    conf.check_message('NSC supported architecture', arch, ok)
    conf.report_optional_feature("nsc", "Network Simulation Cradle", ok,
                                 "architecture %r not supported" % arch)
    nsc_fetch()



class NscBuildTask(Task.TaskBase):
    """task that builds nsc
    """
    after = 'link' # build after the rest of ns-3
    def __init__(self, builddir):
        self.builddir = builddir
        super(NscBuildTask, self).__init__()
        self.display = 'build-nsc\n'

    def run(self):
        # XXX: Detect gcc major version(s) available to build supported stacks
        builddir = self.builddir
        kernels = [['linux-2.6.18', 'linux2.6.18'],
                   ['linux-2.6.26', 'linux2.6.26']]
        for dir, name in kernels:
            soname = 'lib' + name + '.so'
            if not os.path.exists(os.path.join("..", NSC_DIR, dir, soname)):
                if os.system('cd ../%s && python scons.py %s' % (NSC_DIR, dir)) != 0:
                    raise Utils.WafError("Building NSC stack failed")

            if not os.path.exists(builddir + '/' + soname):
                try:
                    os.symlink('../../' + NSC_DIR + '/' + dir + '/' + soname, builddir +  '/' + soname)
                except:
                    raise Utils.WafError("Error linking " + builddir + '/' + soname)


def build(bld):
    obj = bld.create_ns3_module('internet-stack', ['node'])
    obj.source = [
        'internet-stack.cc',
        'ipv4-l4-protocol.cc',
        'udp-header.cc',
        'tcp-header.cc',
        'ipv4-checksum.cc',
        'ipv4-interface.cc',
        'ipv4-l3-protocol.cc',
        'ipv4-static-routing.cc',
        'ipv4-global-routing.cc',
        'ipv4-end-point.cc',
        'udp-l4-protocol.cc',
        'tcp-l4-protocol.cc',
        'arp-header.cc',
        'arp-cache.cc',
        'arp-ipv4-interface.cc',
        'arp-l3-protocol.cc',
        'ipv4-loopback-interface.cc',
        'udp-socket-impl.cc',
        'tcp-socket-impl.cc',
        'ipv4-end-point-demux.cc',
        'ipv4-impl.cc',
        'udp-socket-factory-impl.cc',
        'tcp-socket-factory-impl.cc',
        'pending-data.cc',
        'sequence-number.cc',
        'rtt-estimator.cc',
        'ipv4-raw-socket-factory-impl.cc',
        'ipv4-raw-socket-impl.cc',
        'icmpv4.cc',
        'icmpv4-l4-protocol.cc',
        ]

    headers = bld.new_task_gen('ns3header')
    headers.module = 'internet-stack'
    headers.source = [
        'internet-stack.h',
        'udp-header.h',
        'tcp-header.h',
        'sequence-number.h',
        'ipv4-interface.h',
        'ipv4-l3-protocol.h',
        'ipv4-static-routing.h',
        'ipv4-global-routing.h',
        'icmpv4.h',
        ]

    if bld.env['NSC_ENABLED']:        
        obj.source.append ('nsc-tcp-socket-impl.cc')
        obj.source.append ('nsc-tcp-l4-protocol.cc')
        obj.source.append ('nsc-tcp-socket-factory-impl.cc')
        obj.source.append ('nsc-sysctl.cc')
        obj.uselib = 'DL'
        builddir = os.path.abspath(os.path.join(bld.env['NS3_BUILDDIR'], bld.env ().variant()))
        NscBuildTask(builddir)