2007-05-07 12:01:51 +01:00
|
|
|
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
|
|
|
|
|
2007-06-12 18:52:58 +01:00
|
|
|
import os, os.path
|
2007-05-24 17:54:51 +01:00
|
|
|
import shutil
|
2007-08-08 15:10:36 +01:00
|
|
|
import types
|
2008-12-29 13:28:54 +00:00
|
|
|
import warnings
|
2007-05-24 17:54:51 +01:00
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
import TaskGen
|
|
|
|
|
import Task
|
|
|
|
|
import Options
|
|
|
|
|
import Build
|
2009-04-13 23:10:37 +01:00
|
|
|
import Utils
|
2007-05-24 17:54:51 +01:00
|
|
|
|
2007-07-24 16:13:31 +01:00
|
|
|
all_modules = (
|
2007-05-13 12:46:18 +01:00
|
|
|
'core',
|
|
|
|
|
'common',
|
|
|
|
|
'simulator',
|
2007-12-06 11:05:17 +00:00
|
|
|
'contrib',
|
2007-05-13 12:46:18 +01:00
|
|
|
'node',
|
2008-06-09 15:40:22 -07:00
|
|
|
'internet-stack',
|
2007-07-27 20:17:23 +02:00
|
|
|
'devices/point-to-point',
|
2007-08-09 15:56:28 -07:00
|
|
|
'devices/csma',
|
2008-10-29 22:39:36 -07:00
|
|
|
'devices/emu',
|
2008-11-07 20:41:38 -08:00
|
|
|
'devices/bridge',
|
2009-01-27 12:36:46 -08:00
|
|
|
'devices/tap-bridge',
|
2009-06-09 17:42:57 +01:00
|
|
|
'devices/virtual-net-device',
|
2007-09-12 15:23:25 -07:00
|
|
|
'applications/onoff',
|
|
|
|
|
'applications/packet-sink',
|
|
|
|
|
'applications/udp-echo',
|
2007-07-26 12:49:00 +01:00
|
|
|
'routing/olsr',
|
2007-08-03 09:29:57 -07:00
|
|
|
'routing/global-routing',
|
2007-07-23 15:53:54 +02:00
|
|
|
'mobility',
|
2007-08-24 15:12:12 +02:00
|
|
|
'devices/wifi',
|
2008-03-13 14:24:45 -07:00
|
|
|
'helper',
|
2008-08-29 13:22:09 -04:00
|
|
|
'contrib/stats',
|
2008-10-29 11:19:01 -07:00
|
|
|
'applications/v4ping',
|
2007-07-24 16:13:31 +01:00
|
|
|
)
|
2007-05-13 12:46:18 +01:00
|
|
|
|
2007-05-07 12:01:51 +01:00
|
|
|
def set_options(opt):
|
|
|
|
|
opt.sub_options('simulator')
|
2007-07-20 11:38:16 +01:00
|
|
|
|
|
|
|
|
opt.add_option('--enable-rpath',
|
|
|
|
|
help=("Link programs with rpath"
|
|
|
|
|
" (normally not needed, see "
|
|
|
|
|
" --run and --shell; moreover, only works in some"
|
|
|
|
|
" specific platforms, such as Linux and Solaris)"),
|
|
|
|
|
action="store_true", dest='enable_rpath', default=False)
|
2009-01-27 20:26:34 -08:00
|
|
|
|
2007-11-20 18:27:43 +00:00
|
|
|
opt.add_option('--enable-modules',
|
|
|
|
|
help=("Build only these modules (and dependencies)"),
|
|
|
|
|
dest='enable_modules')
|
|
|
|
|
|
2007-05-07 12:01:51 +01:00
|
|
|
def configure(conf):
|
|
|
|
|
conf.sub_config('core')
|
|
|
|
|
conf.sub_config('simulator')
|
2008-11-07 20:41:38 -08:00
|
|
|
conf.sub_config('devices/emu')
|
2009-05-28 20:10:27 +02:00
|
|
|
conf.sub_config('devices/wifi')
|
2009-01-27 12:36:46 -08:00
|
|
|
conf.sub_config('devices/tap-bridge')
|
2008-05-13 17:02:52 -07:00
|
|
|
conf.sub_config('contrib')
|
2008-08-29 23:10:00 +02:00
|
|
|
conf.sub_config('internet-stack')
|
2007-05-07 12:01:51 +01:00
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant()))
|
2008-07-31 15:04:01 -07:00
|
|
|
conf.env.append_value('NS3_MODULE_PATH', blddir)
|
2008-12-29 13:28:54 +00:00
|
|
|
if Options.options.enable_rpath:
|
2007-08-28 16:53:01 +01:00
|
|
|
conf.env.append_value('RPATH', '-Wl,-rpath=%s' % (os.path.join(blddir),))
|
2007-06-12 18:52:58 +01:00
|
|
|
|
2007-07-15 13:04:47 +01:00
|
|
|
## Used to link the 'run-tests' program with all of ns-3 code
|
|
|
|
|
conf.env['NS3_MODULES'] = ['ns3-' + module.split('/')[-1] for module in all_modules]
|
|
|
|
|
|
2007-11-20 18:27:43 +00:00
|
|
|
|
2007-08-08 15:10:36 +01:00
|
|
|
def create_ns3_module(bld, name, dependencies=()):
|
2009-04-20 17:39:54 +01:00
|
|
|
module = bld.new_task_gen('cxx')
|
2007-08-08 15:10:36 +01:00
|
|
|
module.name = 'ns3-' + name
|
|
|
|
|
module.target = module.name
|
2007-08-08 21:07:52 +01:00
|
|
|
module.add_objects = ['ns3-' + dep for dep in dependencies]
|
2008-03-15 16:13:18 +00:00
|
|
|
module.module_deps = list(dependencies)
|
2009-04-21 14:38:47 +02:00
|
|
|
if not module.env['ENABLE_STATIC_NS3']:
|
|
|
|
|
module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS'])
|
2009-04-22 17:22:41 +02:00
|
|
|
elif module.env['CXX_NAME'] == 'gcc' and \
|
|
|
|
|
os.uname()[4] == 'x86_64' and \
|
|
|
|
|
module.env['ENABLE_PYTHON_BINDINGS']:
|
|
|
|
|
# enable that flag for static builds only on x86-64 platforms
|
|
|
|
|
# when gcc is present and only when we want python bindings
|
|
|
|
|
# (it's more efficient to not use this option if we can avoid it)
|
|
|
|
|
module.env.append_value('CXXFLAGS', '-mcmodel=large')
|
|
|
|
|
|
2008-03-15 16:13:18 +00:00
|
|
|
module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION")
|
2007-08-08 15:10:36 +01:00
|
|
|
return module
|
2008-12-29 13:28:54 +00:00
|
|
|
|
|
|
|
|
def create_obj(bld, *args):
|
|
|
|
|
warnings.warn("(in %s) Use bld.new_task_gen(...) now, instead of bld.create_obj(...)" % str(bld.path),
|
|
|
|
|
DeprecationWarning, stacklevel=2)
|
|
|
|
|
return bld.new_task_gen(*args)
|
2007-05-13 12:46:18 +01:00
|
|
|
|
2007-05-07 12:01:51 +01:00
|
|
|
def build(bld):
|
2007-08-08 15:10:36 +01:00
|
|
|
bld.create_ns3_module = types.MethodType(create_ns3_module, bld)
|
2008-12-29 13:28:54 +00:00
|
|
|
bld.create_obj = types.MethodType(create_obj, bld)
|
2007-05-13 12:46:18 +01:00
|
|
|
|
2007-07-24 16:13:31 +01:00
|
|
|
bld.add_subdirs(list(all_modules))
|
2007-05-24 17:54:51 +01:00
|
|
|
|
2008-03-15 16:13:18 +00:00
|
|
|
for module in all_modules:
|
2008-12-29 13:28:54 +00:00
|
|
|
modheader = bld.new_task_gen('ns3moduleheader')
|
2008-03-15 16:13:18 +00:00
|
|
|
modheader.module = module.split('/')[-1]
|
|
|
|
|
|
2007-08-08 21:07:52 +01:00
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
class ns3header_taskgen(TaskGen.task_gen):
|
2007-05-24 17:54:51 +01:00
|
|
|
"""A set of NS-3 header files"""
|
2008-12-29 13:28:54 +00:00
|
|
|
COLOR = 'BLUE'
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
super(ns3header_taskgen, self).__init__(*args, **kwargs)
|
|
|
|
|
self.install_path = None
|
2007-12-05 11:51:10 +00:00
|
|
|
self.sub_dir = None # if not None, header files will be published as ns3/sub_dir/file.h
|
2007-12-26 13:40:39 +00:00
|
|
|
self.module = None # module name
|
2008-03-15 16:13:18 +00:00
|
|
|
|
2007-05-24 17:54:51 +01:00
|
|
|
def apply(self):
|
2007-12-26 13:40:39 +00:00
|
|
|
if self.module is None:
|
2008-12-29 13:28:54 +00:00
|
|
|
raise Utils.WafError("'module' missing on ns3headers object %s" % self)
|
2009-04-13 23:10:37 +01:00
|
|
|
ns3_dir_node = self.bld.path.find_dir("ns3")
|
2007-12-05 11:51:10 +00:00
|
|
|
if self.sub_dir is not None:
|
|
|
|
|
ns3_dir_node = ns3_dir_node.find_dir(self.sub_dir)
|
2007-05-24 17:54:51 +01:00
|
|
|
for filename in self.to_list(self.source):
|
2008-12-29 13:28:54 +00:00
|
|
|
src_node = self.path.find_resource(filename)
|
2007-05-24 17:54:51 +01:00
|
|
|
if src_node is None:
|
2008-12-29 13:28:54 +00:00
|
|
|
raise Utils.WafError("source ns3 header file %s not found" % (filename,))
|
|
|
|
|
dst_node = ns3_dir_node.find_or_declare(os.path.basename(filename))
|
2007-05-24 17:54:51 +01:00
|
|
|
assert dst_node is not None
|
2008-12-29 13:28:54 +00:00
|
|
|
task = self.create_task('ns3header', self.env)
|
2007-07-20 11:27:34 +01:00
|
|
|
task.set_inputs([src_node])
|
|
|
|
|
task.set_outputs([dst_node])
|
2007-05-24 17:54:51 +01:00
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
class ns3header_task(Task.Task):
|
2008-12-29 15:48:34 +00:00
|
|
|
before = 'cc cxx gen_ns3_module_header_task'
|
2008-12-29 13:28:54 +00:00
|
|
|
color = 'BLUE'
|
|
|
|
|
def run(self):
|
|
|
|
|
assert len(self.inputs) == len(self.outputs)
|
|
|
|
|
inputs = [node.srcpath(self.env) for node in self.inputs]
|
|
|
|
|
outputs = [node.bldpath(self.env) for node in self.outputs]
|
|
|
|
|
for src, dst in zip(inputs, outputs):
|
|
|
|
|
try:
|
|
|
|
|
os.chmod(dst, 0600)
|
|
|
|
|
except OSError:
|
|
|
|
|
pass
|
|
|
|
|
shutil.copy2(src, dst)
|
|
|
|
|
## make the headers in builddir read-only, to prevent
|
|
|
|
|
## accidental modification
|
|
|
|
|
os.chmod(dst, 0400)
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class gen_ns3_module_header_task(Task.Task):
|
|
|
|
|
before = 'cc cxx'
|
2008-12-29 15:48:34 +00:00
|
|
|
after = 'ns3header_task'
|
2008-12-29 13:28:54 +00:00
|
|
|
color = 'BLUE'
|
|
|
|
|
def run(self):
|
|
|
|
|
assert len(self.outputs) == 1
|
|
|
|
|
header_files = [os.path.basename(node.abspath(self.env)) for node in self.inputs]
|
|
|
|
|
outfile = file(self.outputs[0].bldpath(self.env), "w")
|
|
|
|
|
header_files.sort()
|
|
|
|
|
|
|
|
|
|
print >> outfile, """
|
2008-03-15 16:13:18 +00:00
|
|
|
#ifdef NS3_MODULE_COMPILATION
|
|
|
|
|
# error "Do not include ns3 module aggregator headers from other modules; these are meant only for end user scripts."
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef NS3_MODULE_%s
|
2008-12-29 13:28:54 +00:00
|
|
|
""" % (self.module.upper().replace('-', '_'),)
|
2008-03-15 16:13:18 +00:00
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
# if self.module_deps:
|
|
|
|
|
# print >> outfile, "// Module dependencies:"
|
|
|
|
|
# for dep in self.module_deps:
|
|
|
|
|
# print >> outfile, "#include \"%s-module.h\"" % dep
|
2008-03-15 16:13:18 +00:00
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
print >> outfile
|
|
|
|
|
print >> outfile, "// Module headers:"
|
|
|
|
|
for header in header_files:
|
|
|
|
|
print >> outfile, "#include \"%s\"" % (header,)
|
2008-03-15 16:13:18 +00:00
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
print >> outfile, "#endif"
|
2008-03-15 16:13:18 +00:00
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
outfile.close()
|
|
|
|
|
return 0
|
2008-03-15 16:13:18 +00:00
|
|
|
|
2009-01-25 21:57:24 +00:00
|
|
|
def sig_explicit_deps(self):
|
2009-04-13 23:10:37 +01:00
|
|
|
m = Utils.md5()
|
2009-01-25 21:57:24 +00:00
|
|
|
m.update('\n'.join([node.abspath(self.env) for node in self.inputs]))
|
|
|
|
|
return m.digest()
|
|
|
|
|
|
|
|
|
|
def unique_id(self):
|
|
|
|
|
try:
|
|
|
|
|
return self.uid
|
|
|
|
|
except AttributeError:
|
|
|
|
|
"this is not a real hot zone, but we want to avoid surprizes here"
|
2009-04-13 23:10:37 +01:00
|
|
|
m = Utils.md5()
|
2009-01-25 21:57:24 +00:00
|
|
|
m.update("ns-3-module-header-%s" % self.module)
|
|
|
|
|
self.uid = m.digest()
|
|
|
|
|
return self.uid
|
|
|
|
|
|
2008-03-15 16:13:18 +00:00
|
|
|
|
2008-12-29 13:28:54 +00:00
|
|
|
class ns3moduleheader_taskgen(TaskGen.task_gen):
|
2008-03-15 16:13:18 +00:00
|
|
|
"""
|
|
|
|
|
Generates a 'ns3/foo-module.h' header file that includes all
|
|
|
|
|
public ns3 headers of a certain module.
|
|
|
|
|
"""
|
2008-12-29 13:28:54 +00:00
|
|
|
COLOR = 'BLUE'
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
super(ns3moduleheader_taskgen, self).__init__(*args, **kwargs)
|
2008-03-15 16:13:18 +00:00
|
|
|
|
|
|
|
|
def apply(self):
|
|
|
|
|
## get all of the ns3 headers
|
2009-04-13 23:10:37 +01:00
|
|
|
ns3_dir_node = self.bld.path.find_dir("ns3")
|
2008-03-15 16:13:18 +00:00
|
|
|
all_headers_inputs = []
|
2009-04-13 23:10:37 +01:00
|
|
|
for ns3headers in self.bld.all_task_gen:
|
2008-04-26 21:54:36 +01:00
|
|
|
if isinstance(ns3headers, ns3header_taskgen):
|
2008-03-15 16:13:18 +00:00
|
|
|
if ns3headers.module != self.module:
|
|
|
|
|
continue
|
|
|
|
|
for source in ns3headers.to_list(ns3headers.source):
|
|
|
|
|
source = os.path.basename(source)
|
2008-12-29 13:28:54 +00:00
|
|
|
node = ns3_dir_node.find_or_declare(os.path.basename(source))
|
2008-03-15 16:13:18 +00:00
|
|
|
if node is None:
|
|
|
|
|
fatal("missing header file %s" % (source,))
|
|
|
|
|
all_headers_inputs.append(node)
|
2009-04-13 23:10:37 +01:00
|
|
|
if not all_headers_inputs:
|
|
|
|
|
raise Utils.WscriptError("error finding headers for module %s" % self.module)
|
2008-03-15 16:13:18 +00:00
|
|
|
assert all_headers_inputs
|
2009-04-13 23:10:37 +01:00
|
|
|
module_obj = self.bld.name_to_obj("ns3-" + self.module, self.env)
|
2008-03-15 16:13:18 +00:00
|
|
|
assert module_obj is not None
|
2008-12-29 13:28:54 +00:00
|
|
|
all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self.module)]
|
|
|
|
|
task = self.create_task('gen_ns3_module_header', self.env)
|
2008-03-15 16:13:18 +00:00
|
|
|
task.set_inputs(all_headers_inputs)
|
|
|
|
|
task.set_outputs(all_headers_outputs)
|
|
|
|
|
task.module = self.module
|
|
|
|
|
task.module_deps = module_obj.module_deps
|
|
|
|
|
|
|
|
|
|
def install(self):
|
|
|
|
|
pass
|