diff --git a/bindings/python/wscript b/bindings/python/wscript index 5a5309575..4d2dcf516 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -1,17 +1,18 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- import re -import Params -import Configure -import Object -import Action import os -import Task import pproc as subprocess -from Params import fatal, warning import shutil import sys +import Task +import Options +import Configure +import TaskGen +import Logs +import Build + ## Adjust python path to look for our local copy of pybindgen LOCAL_PYBINDGEN_PATH = os.path.join(os.getcwd(), "bindings", "python", "pybindgen") #PYBINDGEN_BRANCH = 'lp:pybindgen' @@ -109,7 +110,7 @@ __version__ = %r def configure(conf): conf.env['ENABLE_PYTHON_BINDINGS'] = False - if Params.g_options.python_disable: + if Options.options.python_disable: conf.report_optional_feature("python", "Python Bindings", False, "disabled by user request") return @@ -119,7 +120,7 @@ def configure(conf): if sys.platform == 'cygwin': conf.report_optional_feature("python", "Python Bindings", False, "unsupported platform 'cygwin'") - warning("Python is not supported in CygWin environment. Try MingW instead.") + Logs.warn("Python is not supported in CygWin environment. Try MingW instead.") return ## Check for Python @@ -142,11 +143,11 @@ def configure(conf): ## Check for pybindgen no_net = False - if Params.g_options.with_pybindgen: - conf.env['WITH_PYBINDGEN'] = os.path.abspath(Params.g_options.with_pybindgen) + if Options.options.with_pybindgen: + conf.env['WITH_PYBINDGEN'] = os.path.abspath(Options.options.with_pybindgen) no_net = True - if Params.g_options.pybindgen_checkout: + if Options.options.pybindgen_checkout: fetch_pybindgen(conf) set_pybindgen_pythonpath(conf.env) @@ -258,29 +259,32 @@ def calc_header_include(path): return os.path.join (calc_header_include (head), tail) -def gen_ns3_metaheader(task): - assert len(task.m_outputs) == 1 +class gen_everything_h_task(Task.Task): + before = 'cc cxx' - header_files = [calc_header_include(node.abspath(task.m_env)) for node in task.m_inputs] - outfile = file(task.m_outputs[0].bldpath(task.m_env), "w") + def run(self): + assert len(self.outputs) == 1 - def sort_func(h1, h2): - return cmp((get_header_prio(h1), h1), (get_header_prio(h1), h2)) + header_files = [calc_header_include(node.abspath(self.env)) for node in self.inputs] + outfile = file(self.outputs[0].bldpath(self.env), "w") - header_files.sort(sort_func) + def sort_func(h1, h2): + return cmp((get_header_prio(h1), h1), (get_header_prio(h1), h2)) - print >> outfile, """ + header_files.sort(sort_func) + + print >> outfile, """ /* http://www.nsnam.org/bugzilla/show_bug.cgi?id=413 */ #ifdef ECHO # undef ECHO #endif -""" - for header in header_files: - print >> outfile, "#include \"ns3/%s\"" % (header,) + """ + for header in header_files: + print >> outfile, "#include \"ns3/%s\"" % (header,) - print >> outfile, """ + print >> outfile, """ namespace ns3 { static inline Ptr __dummy_function_to_force_template_instantiation (Ptr obj, TypeId typeId) @@ -312,34 +316,34 @@ __dummy_function_to_force_template_instantiation_v2 () } """ - outfile.close() - return 0 + outfile.close() + return 0 -class all_ns3_headers_taskgen(Object.task_gen): +class all_ns3_headers_taskgen(TaskGen.task_gen): """Generates a 'everything.h' header file that includes some/all public ns3 headers. This single header file is to be parsed only once by gccxml, for greater efficiency. """ - def __init__(self, *features): - Object.task_gen.__init__(self, *features) - self.inst_var = 0#'INCLUDEDIR' + def __init__(self, *args, **kwargs): + super(all_ns3_headers_taskgen, self).__init__(*args, **kwargs) + self.install_path = None #self.inst_dir = 'ns3' def apply(self): ## get all of the ns3 headers - ns3_dir_node = Params.g_build.m_srcnode.find_dir("ns3") + ns3_dir_node = Build.bld.path.find_dir("ns3") all_headers_inputs = [] for filename in self.to_list(self.source): - src_node = ns3_dir_node.find_build(filename) + src_node = ns3_dir_node.find_or_declare(filename) if src_node is None: - Params.fatal("source ns3 header file %s not found" % (filename,)) + raise Utils.WafError("source ns3 header file %s not found" % (filename,)) all_headers_inputs.append(src_node) ## if self.source was empty, include all ns3 headers in enabled modules if not all_headers_inputs: - for ns3headers in Object.g_allobjs: + for ns3headers in Build.bld.all_task_gen: if type(ns3headers).__name__ == 'ns3header_taskgen': # XXX: find less hackish way to compare ## skip headers not part of enabled modules if self.env['NS3_ENABLED_MODULES']: @@ -348,13 +352,13 @@ class all_ns3_headers_taskgen(Object.task_gen): for source in ns3headers.to_list(ns3headers.source): #source = os.path.basename(source) - node = ns3_dir_node.find_build(source) + node = ns3_dir_node.find_or_declare(source) if node is None: fatal("missing header file %s" % (source,)) all_headers_inputs.append(node) assert all_headers_inputs - all_headers_outputs = [self.path.find_build("everything.h")] - task = self.create_task('gen-ns3-metaheader', self.env, 4) + all_headers_outputs = [self.path.find_or_declare("everything.h")] + task = self.create_task('gen_everything_h', self.env) task.set_inputs(all_headers_inputs) task.set_outputs(all_headers_outputs) @@ -370,13 +374,13 @@ def get_modules_and_headers(): """ retval = {} - for module in Object.g_allobjs: + for module in Build.bld.all_task_gen: if not module.name.startswith('ns3-'): continue module_name = module.name[4:] # strip the ns3- prefix ## find the headers object for this module headers = [] - for ns3headers in Object.g_allobjs: + for ns3headers in Build.bld.all_task_gen: if type(ns3headers).__name__ != 'ns3header_taskgen': # XXX: find less hackish way to compare continue if ns3headers.module != module_name: @@ -388,15 +392,15 @@ def get_modules_and_headers(): -class PythonScanTask(Task.TaskBase): +class python_scan_task(Task.TaskBase): """Uses gccxml to scan the file 'everything.h' and extract API definitions. """ + after = 'gen_everything_h' def __init__(self, curdirnode, env): - self.prio = 5 # everything.h has prio 4 - super(PythonScanTask, self).__init__() + super(python_scan_task, self).__init__() self.curdirnode = curdirnode self.env = env - self.m_display = 'python-scan\n' + self.display = 'python-scan\n' def run(self): #print "Rescanning the python bindings..." @@ -404,7 +408,7 @@ class PythonScanTask(Task.TaskBase): self.env['PYTHON'], os.path.join(self.curdirnode.abspath(), 'ns3modulescan.py'), # scanning script self.curdirnode.find_dir('../..').abspath(self.env), # include path (where the ns3 include dir is) - self.curdirnode.find_build('everything.h').abspath(self.env), + self.curdirnode.find_or_declare('everything.h').abspath(self.env), os.path.join(self.curdirnode.abspath(), 'ns3modulegen_generated.py'), # output file ] scan = subprocess.Popen(argv, stdin=subprocess.PIPE) @@ -415,24 +419,24 @@ class PythonScanTask(Task.TaskBase): raise SystemExit(0) def build(bld): - if Params.g_options.python_disable: + if Options.options.python_disable: return - env = bld.env_of_name('default') - curdir = bld.m_curdirnode.abspath() + env = bld.env + curdir = bld.path.abspath() set_pybindgen_pythonpath(env) #Object.register('all-ns3-headers', AllNs3Headers) - Action.Action('gen-ns3-metaheader', func=gen_ns3_metaheader, color='BLUE') + #Action.Action('gen-ns3-metaheader', func=gen_ns3_metaheader, color='BLUE') if env['ENABLE_PYTHON_BINDINGS']: - obj = bld.create_obj('all_ns3_headers') + obj = bld.new_task_gen('all_ns3_headers') - if Params.g_options.python_scan: + if Options.options.python_scan: if not env['ENABLE_PYTHON_SCANNING']: - Params.fatal("Cannot re-scan python bindings: (py)gccxml not available") - PythonScanTask(bld.m_curdirnode, env) + raise Utils.WafError("Cannot re-scan python bindings: (py)gccxml not available") + PythonScanTask(bld.path, env) ## Get a list of scanned modules; the set of scanned modules ## may be smaller than the set of all modules, in case a new @@ -448,46 +452,62 @@ def build(bld): scanned_modules.append(name) if env['ENABLE_PYTHON_BINDINGS']: - bindgen = bld.create_obj('command-output') - bindgen.name = 'pybindgen' - bindgen.command = env['PYTHON'] - bindgen.command_is_external = True - bindgen.stderr = 'ns3modulegen.log' - bindgen.argv = [ - #'-m', 'pdb', - bindgen.input_file("ns3modulegen.py"), - bindgen.output_file("ns3module.cc"), + source = [ + 'ns3modulegen.py', + 'ns3modulegen_generated.py', + 'ns3modulegen_core_customizations.py', ] - bindgen.argv.extend(get_modules_and_headers().iterkeys()) - bindgen.hidden_inputs = ['ns3modulegen_generated.py', - 'ns3modulegen_core_customizations.py'] + target = [ + 'ns3module.cc', + 'ns3module.h', + 'ns3modulegen.log', + ] + argv = ['NS3_ENABLED_FEATURES=${FEATURES}', '${PYTHON}', '${SRC[0]}', '${TGT[0]}'] + argv.extend(get_modules_and_headers().iterkeys()) + + #bindgen.name = 'pybindgen' + #bindgen.command = env['PYTHON'] + #bindgen.command_is_external = True + #bindgen.stderr = 'ns3modulegen.log' + #bindgen.argv = [ + #'-m', 'pdb', + # bindgen.input_file("ns3modulegen.py"), + # bindgen.output_file("ns3module.cc"), + # ] + #bindgen.hidden_inputs = ['ns3modulegen_generated.py', + # 'ns3modulegen_core_customizations.py'] for module in scanned_modules: - bindgen.hidden_inputs.append("ns3_module_%s.py" % module) + source.append("ns3_module_%s.py" % module) local = "ns3_module_%s__local.py" % module if os.path.exists(os.path.join(curdir, local)): - bindgen.hidden_inputs.append(local) + source.append(local) - bindgen.hidden_outputs = ['ns3module.h'] + argv.extend(['2>', '${TGT[2]}']) # 2> ns3modulegen.log + + #bindgen.hidden_outputs = ['ns3module.h'] for module in scanned_modules: - bindgen.hidden_outputs.append("ns3_module_%s.cc" % module) + target.append("ns3_module_%s.cc" % module) - bindgen.prio = 50 + #bindgen.prio = 50 - bindgen.os_env = dict(os.environ) + #bindgen.os_env = dict(os.environ) features = [] for (name, caption, was_enabled, reason_not_enabled) in env['NS3_OPTIONAL_FEATURES']: if was_enabled: features.append(name) - bindgen.os_env['NS3_ENABLED_FEATURES'] = ','.join(features) + #bindgen.os_env['NS3_ENABLED_FEATURES'] = ','.join(features) + + bindgen = bld.new_task_gen('command', source=source, target=target, + command=argv, variables=dict(FEATURES=(','.join(features)))) ## we build python bindings if either we have the tools to ## generate them or if the pregenerated source file is already ## present in the source dir. if env['ENABLE_PYTHON_BINDINGS'] \ - or os.path.exists(os.path.join(bld.m_curdirnode.abspath(), 'ns3module.cc')): - pymod = bld.create_obj('cpp', 'shlib', 'pyext') + or os.path.exists(os.path.join(bld.path.abspath(), 'ns3module.cc')): + pymod = bld.new_task_gen('cxx', 'shlib', 'pyext') pymod.source = ['ns3module.cc', 'ns3module_helpers.cc'] pymod.includes = '.' for module in scanned_modules: @@ -497,10 +517,10 @@ def build(bld): pymod.uselib_local = "ns3" pymod.env.append_value('CXXDEFINES', ['NS_DEPRECATED=""', 'NS3_DEPRECATED_H']) - # copy the __init__.py file to the build dir waf can't handle + # copy the __init__.py file to the build dir. waf can't handle # this, it's against waf's principles to have build dir files # with the same name as source dir files, apparently. - dirnode = bld.m_curdirnode.find_dir('ns3') + dirnode = bld.path.find_dir('ns3') src = os.path.join(dirnode.abspath(), '__init__.py') dst = os.path.join(dirnode.abspath(env), '__init__.py') try: diff --git a/doc/build.txt b/doc/build.txt index 090b83408..984e809d4 100644 --- a/doc/build.txt +++ b/doc/build.txt @@ -9,6 +9,12 @@ http://www.nsnam.org/wiki/index.php/Installation The top-level ns-3 directory should contain a current waf script. +Note: we're using a WAF version based on WAF 1.5.x. The source code +can be retrieved from the followin URL: + + https://code.launchpad.net/~gjc/waf/cmd + + === Building with Waf === To build ns-3 with waf type the commands from the top-level directory: diff --git a/regression.py b/regression.py index 9d63cfcd0..36d69b3f0 100644 --- a/regression.py +++ b/regression.py @@ -1,12 +1,19 @@ +# python lib modules import os import sys -import Params import shutil import pproc as subprocess import urllib +# WAF modules +import Build +import Options +import Utils + +# local modules import wutils + # # The directory in which the tarball of the reference traces lives. This is # used if Mercurial is not on the system. @@ -45,7 +52,7 @@ class Regression(object): def __init__(self, testdir, reference_traces): self.testdir = testdir self.reference_traces = reference_traces - self.env = Params.g_build.env_of_name('default') + self.env = Build.bld.env def run_test(self, verbose, generate, testName, arguments=[], pyscript=None, refTestName=None): """ @@ -83,13 +90,13 @@ class Regression(object): os.mkdir(refTestDirName) if pyscript is None: - Params.g_options.cwd_launch = refTestDirName + Options.options.cwd_launch = refTestDirName tmpl = "%s" for arg in arguments: tmpl = tmpl + " " + arg wutils.run_program(testName, tmpl) else: - argv = [self.env['PYTHON'], os.path.join(Params.g_cwd_launch, *os.path.split(pyscript))] + arguments + argv = [self.env['PYTHON'], os.path.join(Options.cwd_launch, *os.path.split(pyscript))] + arguments before = os.getcwd() os.chdir(refTestDirName) try: @@ -120,7 +127,7 @@ class Regression(object): # testName + " > /dev/null 2>&1") if pyscript is None: - Params.g_options.cwd_launch = traceDirName + Options.options.cwd_launch = traceDirName wutils.run_program(testName, command_template=wutils.get_command_template(*arguments)) else: argv = [self.env['PYTHON'], os.path.join('..', '..', '..', *os.path.split(pyscript))] + arguments @@ -191,13 +198,13 @@ def run_regression(reference_traces): sys.path.append(testdir) sys.modules['tracediff'] = Regression(testdir, reference_traces) - if Params.g_options.regression_tests: - tests = Params.g_options.regression_tests.split(',') + if Options.options.regression_tests: + tests = Options.options.regression_tests.split(',') else: tests = _find_tests(testdir) print "========== Running Regression Tests ==========" - env = Params.g_build.env_of_name('default') + env = Build.bld.env if not no_net: if env['MERCURIAL']: print "Synchronizing reference traces using Mercurial." @@ -216,7 +223,7 @@ def run_regression(reference_traces): finally: os.chdir("..") if result: - Params.fatal("Synchronizing reference traces using Mercurial failed.") + raise Utils.WafError("Synchronizing reference traces using Mercurial failed.") else: if not os.path.exists(reference_traces): traceball = dir_name + wutils.TRACEBALL_SUFFIX @@ -235,7 +242,7 @@ def run_regression(reference_traces): try: result = _run_regression_test(test) if result == 0: - if Params.g_options.regression_generate: + if Options.options.regression_generate: print "GENERATE " + test else: print "PASS " + test @@ -243,7 +250,7 @@ def run_regression(reference_traces): bad.append(test) print "FAIL " + test except NotImplementedError: - print "SKIP " + test + print "SKIP " + test return len(bad) > 0 @@ -265,6 +272,6 @@ def _run_regression_test(test): os.mkdir("traces") mod = __import__(test, globals(), locals(), []) - return mod.run(verbose=(Params.g_options.verbose > 0), - generate=Params.g_options.regression_generate) + return mod.run(verbose=(Options.options.verbose > 0), + generate=Options.options.regression_generate) diff --git a/src/applications/onoff/wscript b/src/applications/onoff/wscript index ee1041066..961dcaac5 100644 --- a/src/applications/onoff/wscript +++ b/src/applications/onoff/wscript @@ -5,7 +5,7 @@ def build(bld): module.source = [ 'onoff-application.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'onoff' headers.source = [ 'onoff-application.h', diff --git a/src/applications/packet-sink/wscript b/src/applications/packet-sink/wscript index 120095544..0f618ddff 100644 --- a/src/applications/packet-sink/wscript +++ b/src/applications/packet-sink/wscript @@ -5,7 +5,7 @@ def build(bld): module.source = [ 'packet-sink.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'packet-sink' headers.source = [ 'packet-sink.h', diff --git a/src/applications/udp-echo/wscript b/src/applications/udp-echo/wscript index 762e59ec9..4c27c517b 100644 --- a/src/applications/udp-echo/wscript +++ b/src/applications/udp-echo/wscript @@ -6,7 +6,7 @@ def build(bld): 'udp-echo-client.cc', 'udp-echo-server.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'udp-echo' headers.source = [ 'udp-echo-client.h', diff --git a/src/applications/v4ping/wscript b/src/applications/v4ping/wscript index a4c56c3f3..2fa4075d3 100644 --- a/src/applications/v4ping/wscript +++ b/src/applications/v4ping/wscript @@ -5,7 +5,7 @@ def build(bld): module.source = [ 'v4ping.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'v4ping' headers.source = [ 'v4ping.h', diff --git a/src/common/wscript b/src/common/wscript index 0b76283bf..3614fef06 100644 --- a/src/common/wscript +++ b/src/common/wscript @@ -18,7 +18,7 @@ def build(bld): 'tag-buffer.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'common' headers.source = [ 'buffer.h', diff --git a/src/contrib/stats/wscript b/src/contrib/stats/wscript index 3be5543e9..62b6146fd 100644 --- a/src/contrib/stats/wscript +++ b/src/contrib/stats/wscript @@ -1,12 +1,7 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- def configure(conf): - e = conf.create_library_configurator() - e.mandatory = False - e.name = 'sqlite3' - e.define = 'SQLITE3' - e.uselib = 'SQLITE3' - conf.env['SQLITE_STATS'] = e.run() + conf.env['SQLITE_STATS'] = conf.check(lib='sqlite3', define_name='SQLITE3', uselib='SQLITE3') conf.report_optional_feature("SqliteDataOutput", "SQlite stats data output", conf.env['SQLITE_STATS'], "library 'sqlite3' not found") @@ -22,7 +17,7 @@ def build(bld): 'omnet-data-output.cc', 'data-collector.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'stats' headers.source = [ 'data-calculator.h', @@ -34,7 +29,7 @@ def build(bld): 'data-collector.h', ] - if bld.env()['SQLITE_STATS']: + if bld.env['SQLITE_STATS']: headers.source.append('sqlite-data-output.h') obj.source.append('sqlite-data-output.cc') obj.uselib = 'SQLITE3' diff --git a/src/contrib/wscript b/src/contrib/wscript index f868774f9..7324d8a56 100644 --- a/src/contrib/wscript +++ b/src/contrib/wscript @@ -1,11 +1,8 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- def configure(conf): - check = conf.create_pkgconfig_configurator() - check.name = 'gtk+-2.0 >= 2.12' - check.uselib = 'GTK_CONFIG_STORE' - check.mandatory = False - conf.env['ENABLE_GTK_CONFIG_STORE'] = check.run() + have_it = conf.pkg_check_modules('GTK_CONFIG_STORE', 'gtk+-2.0 >= 2.12', mandatory=False) + conf.env['ENABLE_GTK_CONFIG_STORE'] = have_it conf.report_optional_feature("GtkConfigStore", "GtkConfigStore", conf.env['ENABLE_GTK_CONFIG_STORE'], "library 'gtk+-2.0 >= 2.12' not found") @@ -23,7 +20,7 @@ def build(bld): 'flow-id-tag.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'contrib' headers.source = [ 'event-garbage-collector.h', @@ -33,7 +30,7 @@ def build(bld): 'flow-id-tag.h', ] - if bld.env()['ENABLE_GTK_CONFIG_STORE']: + if bld.env['ENABLE_GTK_CONFIG_STORE']: headers.source.append ('gtk-config-store.h') module.source.append ('gtk-config-store.cc') module.uselib = 'GTK_CONFIG_STORE' diff --git a/src/core/wscript b/src/core/wscript index 586b0ee95..8d76057fe 100644 --- a/src/core/wscript +++ b/src/core/wscript @@ -3,36 +3,16 @@ import sys def configure(conf): - e = conf.create_header_configurator() - e.mandatory = False - e.name = 'stdlib.h' - e.define = 'HAVE_STDLIB_H' - e.run() + if conf.check(header_name='stdlib.h'): + conf.define('HAVE_STDLIB_H', 1) + conf.define('HAVE_GETENV', 1) - e = conf.create_header_configurator() - e.mandatory = False - e.name = 'stdlib.h' - e.define = 'HAVE_GETENV' - e.run() + conf.check(header_name='signal.h', define_name='HAVE_SIGNAL_H') - e = conf.create_header_configurator() - e.mandatory = False - e.name = 'signal.h' - e.define = 'HAVE_SIGNAL_H' - e.run() + conf.check(lib='rt', uselib='RT', define_name='HAVE_RT') - e = conf.create_library_configurator() - e.mandatory = False - e.name = 'rt' - e.define = 'HAVE_RT' - e.uselib = 'RT' - e.run() + conf.env['ENABLE_THREADING'] = conf.check(header_name='pthread.h', define_name='HAVE_PTHREAD_H') - e = conf.create_header_configurator() - e.mandatory = False - e.name = 'pthread.h' - e.define = 'HAVE_PTHREAD_H' - conf.env['ENABLE_THREADING'] = e.run() conf.report_optional_feature("Threading", "Threading Primitives", conf.env['ENABLE_THREADING'], " include not detected") @@ -76,7 +56,7 @@ def build(bld): ] core.uselib = 'RT' - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'core' headers.source = [ 'system-wall-clock-ms.h', @@ -129,7 +109,7 @@ def build(bld): 'unix-system-wall-clock-ms.cc', ]) - if bld.env()['ENABLE_THREADING']: + if bld.env['ENABLE_THREADING']: core.source.extend([ 'unix-system-thread.cc', 'unix-system-mutex.cc', diff --git a/src/devices/bridge/wscript b/src/devices/bridge/wscript index fec55457e..b0a13f0c4 100644 --- a/src/devices/bridge/wscript +++ b/src/devices/bridge/wscript @@ -6,7 +6,7 @@ def build(bld): 'bridge-net-device.cc', 'bridge-channel.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'bridge' headers.source = [ 'bridge-net-device.h', diff --git a/src/devices/csma/wscript b/src/devices/csma/wscript index a90ac5bd3..af86e352b 100644 --- a/src/devices/csma/wscript +++ b/src/devices/csma/wscript @@ -7,7 +7,7 @@ def build(bld): 'csma-net-device.cc', 'csma-channel.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'csma' headers.source = [ 'backoff.h', diff --git a/src/devices/emu/wscript b/src/devices/emu/wscript index ff5a4fa75..8400d1288 100644 --- a/src/devices/emu/wscript +++ b/src/devices/emu/wscript @@ -1,11 +1,8 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- def configure(conf): - e = conf.create_header_configurator() - e.mandatory = False - e.name = 'linux/if_ether.h' - e.define = 'HAVE_IF_ETHER_H' - conf.env['ENABLE_EMU'] = e.run() + conf.env['ENABLE_EMU'] = conf.check(header_name='linux/if_ether.h', + define_name='HAVE_IF_ETHER_H') conf.report_optional_feature("EmuNetDevice", "Emulated Net Device", conf.env['ENABLE_EMU'], " include not detected") @@ -14,7 +11,7 @@ def build(bld): module = bld.create_ns3_module('emu', ['node']) module.source = [ ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'emu' headers.source = [ 'emu.h', diff --git a/src/devices/point-to-point/wscript b/src/devices/point-to-point/wscript index 31aa62ade..a1fb07c57 100644 --- a/src/devices/point-to-point/wscript +++ b/src/devices/point-to-point/wscript @@ -9,7 +9,7 @@ def build(bld): 'point-to-point-test.cc', 'ppp-header.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'point-to-point' headers.source = [ 'point-to-point-net-device.h', diff --git a/src/devices/wifi/wscript b/src/devices/wifi/wscript index b01ac49e0..43998e5df 100644 --- a/src/devices/wifi/wscript +++ b/src/devices/wifi/wscript @@ -44,7 +44,7 @@ def build(bld): 'constant-rate-wifi-manager.cc', 'wifi-test.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'wifi' headers.source = [ 'propagation-delay-model.h', diff --git a/src/helper/wscript b/src/helper/wscript index c71039134..d1f2ef6a6 100644 --- a/src/helper/wscript +++ b/src/helper/wscript @@ -25,7 +25,7 @@ def build(bld): 'v4ping-helper.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'helper' headers.source = [ 'node-container.h', diff --git a/src/internet-stack/wscript b/src/internet-stack/wscript index 6b9625712..7841cbf22 100644 --- a/src/internet-stack/wscript +++ b/src/internet-stack/wscript @@ -1,9 +1,12 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -import Params -import Task 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" @@ -25,17 +28,17 @@ def nsc_fetch(): def nsc_clone(): print "Retrieving nsc from " + NSC_REPO if os.system("hg version > /dev/null 2>&1") != 0: - Params.fatal("Mercurial not installed, http fallback not yet implemented") + raise Utils.WafError("Mercurial not installed, http fallback not yet implemented") if os.system("hg clone " + NSC_REPO) != 0: - Params.fatal("hg -q clone %s failed" % NSC_REPO) + raise Utils.WafError("hg -q clone %s failed" % NSC_REPO) def nsc_update(): if os.system("hg version > /dev/null 2>&1") != 0: - Params.warning("Mercurial not installed, not updating nsc source") + 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: - Params.warning("Updating nsc using mercurial failed") + Logs.warn("Updating nsc using mercurial failed") def nsc_download(): local_file = NSC_RELEASE_NAME + ".tar.bz2" @@ -61,12 +64,9 @@ def configure(conf): import flex import bison conf.check_tool('flex bison') - e = conf.create_library_configurator() - e.mandatory = True - e.name = 'fl' - e.run() + conf.check(lib='fl', mandatory=True) - if not Params.g_options.enable_nsc: + if not Options.options.enable_nsc: conf.report_optional_feature("nsc", "Network Simulation Cradle", False, "--enable-nsc configure option not given") return @@ -78,13 +78,7 @@ def configure(conf): 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') - e = conf.create_library_configurator() - e.mandatory = True - e.name = 'dl' - e.define = 'HAVE_DL' - e.uselib = 'DL' - e.run() - conf.env['ENABLE_NSC'] = True + 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, @@ -96,11 +90,11 @@ def configure(conf): class NscBuildTask(Task.TaskBase): """task that builds nsc """ + after = 'link' # build after the rest of ns-3 def __init__(self, builddir): - self.prio = 1000 # build after the rest of ns-3 self.builddir = builddir super(NscBuildTask, self).__init__() - self.m_display = 'build-nsc\n' + self.display = 'build-nsc\n' def run(self): # XXX: Detect gcc major version(s) available to build supported stacks @@ -111,13 +105,13 @@ class NscBuildTask(Task.TaskBase): 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: - Params.fatal("Building NSC stack failed") + raise Utils.WafError("Building NSC stack failed") if not os.path.exists(builddir + '/' + soname): try: os.symlink('../../' + NSC_DIR + '/' + dir + '/' + soname, builddir + '/' + soname) except: - Params.fatal("Error linking " + builddir + '/' + soname) + raise Utils.WafError("Error linking " + builddir + '/' + soname) def build(bld): @@ -155,7 +149,7 @@ def build(bld): 'icmpv4-l4-protocol.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'internet-stack' headers.source = [ 'internet-stack.h', @@ -169,11 +163,11 @@ def build(bld): 'icmpv4.h', ] - if bld.env()['NSC_ENABLED']: + 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())) + builddir = os.path.abspath(os.path.join(bld.env['NS3_BUILDDIR'], bld.env ().variant())) NscBuildTask(builddir) diff --git a/src/mobility/wscript b/src/mobility/wscript index 2ce6b1844..0163e3639 100644 --- a/src/mobility/wscript +++ b/src/mobility/wscript @@ -16,7 +16,7 @@ def build(bld): 'random-direction-2d-mobility-model.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'mobility' headers.source = [ 'vector.h', diff --git a/src/node/wscript b/src/node/wscript index 9ef38c624..cf318b0f2 100644 --- a/src/node/wscript +++ b/src/node/wscript @@ -40,7 +40,7 @@ def build(bld): 'ipv4-raw-socket-factory.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'node' headers.source = [ 'address.h', diff --git a/src/routing/global-routing/wscript b/src/routing/global-routing/wscript index 17816ade1..483e5b5d0 100644 --- a/src/routing/global-routing/wscript +++ b/src/routing/global-routing/wscript @@ -8,7 +8,7 @@ def build(bld): 'global-route-manager-impl.cc', 'candidate-queue.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'global-routing' headers.source = [ 'global-router-interface.h', diff --git a/src/routing/olsr/wscript b/src/routing/olsr/wscript index 8e82c6de5..52e835d5b 100644 --- a/src/routing/olsr/wscript +++ b/src/routing/olsr/wscript @@ -11,7 +11,7 @@ def build(bld): 'olsr-agent-impl.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'olsr' headers.source = [ 'olsr-agent.h', diff --git a/src/simulator/wscript b/src/simulator/wscript index 506119579..5cf9c5b66 100644 --- a/src/simulator/wscript +++ b/src/simulator/wscript @@ -1,7 +1,7 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- import sys -import Params +import Options def set_options(opt): @@ -15,32 +15,21 @@ def set_options(opt): def configure(conf): - if Params.g_options.high_precision_as_double: + if Options.options.high_precision_as_double: conf.define('USE_HIGH_PRECISION_DOUBLE', 1) conf.env['USE_HIGH_PRECISION_DOUBLE'] = 1 highprec = 'long double' else: conf.env['USE_HIGH_PRECISION_DOUBLE'] = 0 highprec = '128-bit integer' - conf.check_message_custom('high precision time','implementation',highprec) - e = conf.create_header_configurator() - e.mandatory = False - e.name = 'stdint.h' - e.define = 'HAVE_STDINT_H' - e.run() + conf.check_message_custom('high precision time', 'implementation', highprec) - e = conf.create_header_configurator() - e.mandatory = False - e.name = 'inttypes.h' - e.define = 'HAVE_INTTYPES_H' - e.run() + conf.check(header_name='stdint.h', define_name='HAVE_STDINT_H') - e = conf.create_header_configurator() - e.mandatory = False - e.name = 'sys/inttypes.h' - e.define = 'HAVE_SYS_INT_TYPES_H' - e.run() + conf.check(header_name='inttypes.h', define_name='HAVE_INTTYPES_H') + + conf.check(header_name='sys/inttypes.h', define_name='HAVE_SYS_INT_TYPES_H') conf.write_config_header('ns3/simulator-config.h') @@ -68,7 +57,7 @@ def build(bld): 'make-event.cc', ] - headers = bld.create_obj('ns3header') + headers = bld.new_task_gen('ns3header') headers.module = 'simulator' headers.source = [ 'high-precision.h', diff --git a/src/wscript b/src/wscript index ede9746b3..3d79e10a8 100644 --- a/src/wscript +++ b/src/wscript @@ -3,11 +3,16 @@ import os, os.path import shutil import types +import warnings -import Action -import Common -import Object -import Params +import TaskGen +import Task +import Options +import Build +#import Action +#import Common +#import Object +#import Params all_modules = ( @@ -55,9 +60,9 @@ def configure(conf): conf.sub_config('contrib') conf.sub_config('internet-stack') - blddir = os.path.abspath(os.path.join(conf.m_blddir, conf.env.variant())) + blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant())) conf.env.append_value('NS3_MODULE_PATH', blddir) - if Params.g_options.enable_rpath: + if Options.options.enable_rpath: conf.env.append_value('RPATH', '-Wl,-rpath=%s' % (os.path.join(blddir),)) ## Used to link the 'run-tests' program with all of ns-3 code @@ -65,7 +70,7 @@ def configure(conf): def create_ns3_module(bld, name, dependencies=()): - module = bld.create_obj('cpp', 'objects') + module = bld.new_task_gen('cxx', 'objects') module.name = 'ns3-' + name module.target = module.name module.add_objects = ['ns3-' + dep for dep in dependencies] @@ -73,131 +78,134 @@ def create_ns3_module(bld, name, dependencies=()): module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS']) module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION") return module - + +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) def build(bld): #Object.register('ns3header', Ns3Header) - Action.Action('ns3header', func=_ns3_headers_inst, color='BLUE') + #Action.Action('ns3header', func=_ns3_headers_inst, color='BLUE') #Object.register('ns3-module-header', Ns3ModuleHeader) - Action.Action('gen-ns3-module-header', func=gen_ns3_module_header, color='BLUE') + #Action.Action('gen-ns3-module-header', func=gen_ns3_module_header, color='BLUE') bld.create_ns3_module = types.MethodType(create_ns3_module, bld) + bld.create_obj = types.MethodType(create_obj, bld) bld.add_subdirs(list(all_modules)) for module in all_modules: - modheader = bld.create_obj('ns3moduleheader') + modheader = bld.new_task_gen('ns3moduleheader') modheader.module = module.split('/')[-1] -class ns3header_taskgen(Object.task_gen): +class ns3header_taskgen(TaskGen.task_gen): """A set of NS-3 header files""" - def __init__(self, *features): - Object.task_gen.__init__(self, *features) - self.inst_var = 'INCLUDEDIR' - self.inst_dir = 'ns3' + COLOR = 'BLUE' + def __init__(self, *args, **kwargs): + super(ns3header_taskgen, self).__init__(*args, **kwargs) + self.install_path = None self.sub_dir = None # if not None, header files will be published as ns3/sub_dir/file.h self.module = None # module name def apply(self): if self.module is None: - Params.fatal("'module' missing on ns3headers object %s" % self) - ns3_dir_node = Params.g_build.m_srcnode.find_dir("ns3") + raise Utils.WafError("'module' missing on ns3headers object %s" % self) + ns3_dir_node = Build.bld.path.find_dir("ns3") if self.sub_dir is not None: ns3_dir_node = ns3_dir_node.find_dir(self.sub_dir) for filename in self.to_list(self.source): - src_node = self.path.find_source(filename) + src_node = self.path.find_resource(filename) if src_node is None: - Params.fatal("source ns3 header file %s not found" % (filename,)) - dst_node = ns3_dir_node.find_build(os.path.basename(filename)) + raise Utils.WafError("source ns3 header file %s not found" % (filename,)) + dst_node = ns3_dir_node.find_or_declare(os.path.basename(filename)) assert dst_node is not None - task = self.create_task('ns3header', self.env, 1) + task = self.create_task('ns3header', self.env) task.set_inputs([src_node]) task.set_outputs([dst_node]) - def install(self): - if self.sub_dir is None: - inst_dir = self.inst_dir - else: - inst_dir = os.path.join(self.inst_dir, self.sub_dir) - for i in self.m_tasks: - current = Params.g_build.m_curdirnode - lst = map(lambda a: a.relpath_gen(current), i.m_outputs) - Common.install_files(self.inst_var, inst_dir, lst) - -def _ns3_headers_inst(task): - assert len(task.m_inputs) == len(task.m_outputs) - inputs = [node.srcpath(task.m_env) for node in task.m_inputs] - outputs = [node.bldpath(task.m_env) for node in task.m_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 ns3header_task(Task.Task): + before = 'cc cxx' + 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 -def gen_ns3_module_header(task): - assert len(task.m_outputs) == 1 - header_files = [os.path.basename(node.abspath(task.m_env)) for node in task.m_inputs] - outfile = file(task.m_outputs[0].bldpath(task.m_env), "w") - header_files.sort() - print >> outfile, """ +class gen_ns3_module_header_task(Task.Task): + before = 'cc cxx' + 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, """ #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 -""" % (task.module.upper().replace('-', '_'),) + """ % (self.module.upper().replace('-', '_'),) -# if task.module_deps: -# print >> outfile, "// Module dependencies:" -# for dep in task.module_deps: -# print >> outfile, "#include \"%s-module.h\"" % dep + # if self.module_deps: + # print >> outfile, "// Module dependencies:" + # for dep in self.module_deps: + # print >> outfile, "#include \"%s-module.h\"" % dep - print >> outfile - print >> outfile, "// Module headers:" - for header in header_files: - print >> outfile, "#include \"%s\"" % (header,) + print >> outfile + print >> outfile, "// Module headers:" + for header in header_files: + print >> outfile, "#include \"%s\"" % (header,) - print >> outfile, "#endif" + print >> outfile, "#endif" - outfile.close() - return 0 + outfile.close() + return 0 -class ns3moduleheader_taskgen(Object.task_gen): +class ns3moduleheader_taskgen(TaskGen.task_gen): """ Generates a 'ns3/foo-module.h' header file that includes all public ns3 headers of a certain module. """ - def __init__(self, *features): - Object.task_gen.__init__(self, *features) + COLOR = 'BLUE' + def __init__(self, *args, **kwargs): + super(ns3moduleheader_taskgen, self).__init__(*args, **kwargs) self.module_name = None def apply(self): ## get all of the ns3 headers - ns3_dir_node = Params.g_build.m_srcnode.find_dir("ns3") + ns3_dir_node = Build.bld.path.find_dir("ns3") all_headers_inputs = [] - for ns3headers in Object.g_allobjs: + for ns3headers in Build.bld.all_task_gen: if isinstance(ns3headers, ns3header_taskgen): if ns3headers.module != self.module: continue for source in ns3headers.to_list(ns3headers.source): source = os.path.basename(source) - node = ns3_dir_node.find_build(os.path.basename(source)) + node = ns3_dir_node.find_or_declare(os.path.basename(source)) if node is None: fatal("missing header file %s" % (source,)) all_headers_inputs.append(node) assert all_headers_inputs - module_obj = Object.name_to_obj("ns3-" + self.module) + module_obj = Build.bld.name_to_obj("ns3-" + self.module, self.env) assert module_obj is not None - all_headers_outputs = [ns3_dir_node.find_build("%s-module.h" % self.module)] - task = self.create_task('gen-ns3-module-header', self.env, 4) + all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self.module)] + task = self.create_task('gen_ns3_module_header', self.env) task.set_inputs(all_headers_inputs) task.set_outputs(all_headers_outputs) task.module = self.module diff --git a/utils/wscript b/utils/wscript index dfbd84c1f..07e880b7c 100644 --- a/utils/wscript +++ b/utils/wscript @@ -2,18 +2,15 @@ import os.path def configure(conf): - check = conf.create_pkgconfig_configurator() - check.name = 'goocanvas gthread-2.0' - check.uselib = 'MOBILITY_VISUALIZER' - check.mandatory = False - conf.env['ENABLE_MOBILITY_VISUALIZER'] = check.run() + conf.env['ENABLE_MOBILITY_VISUALIZER'] = conf.pkg_check_modules( + 'MOBILITY_VISUALIZER', 'goocanvas gthread-2.0', mandatory=False) def build(bld): - env = bld.env_of_name('default') + env = bld.env unit_tests = bld.create_ns3_program('run-tests', ['common']) - unit_tests.inst_var = 0 # do not install + unit_tests.install_path = None # do not install unit_tests.source = 'run-tests.cc' ## link unit test program with all ns3 modules unit_tests.uselib_local = 'ns3' diff --git a/waf b/waf index ece4755da..712934209 100755 Binary files a/waf and b/waf differ diff --git a/wscript b/wscript index 11ed03832..b80a9757b 100644 --- a/wscript +++ b/wscript @@ -1,24 +1,31 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +# python lib modules import sys import shutil import types import optparse import os.path +# WAF modules import pproc as subprocess - -import Params -import Object +import Options +import Logs +import TaskGen import ccroot import Task +import Utils +import Build +import Configure +# local modules import wutils import regression -Params.g_autoconfig = 1 +Options.autoconfig = 1 # the following two variables are used by the target "waf dist" -VERSION = file("VERSION").read().strip() +VERSION = file("VERSION", "rt").read().strip() APPNAME = 'ns' wutils.VERSION = VERSION @@ -36,7 +43,7 @@ def dist_hook(): shutil.rmtree("nsc", True) if not os.path.exists("bindings/python/pybindgen"): - Params.fatal("Missing pybindgen checkout; run './waf configure --pybindgen-checkout' first.") + raise Utils.WafError("Missing pybindgen checkout; run './waf configure --pybindgen-checkout' first.") ## build the name of the traces subdirectory. Will be something like ## ns-3-dev-ref-traces @@ -44,7 +51,7 @@ def dist_hook(): ## Create a tar.bz2 file with the traces traces_dir = os.path.join(regression.REGRESSION_DIR, traces_name) if not os.path.isdir(traces_dir): - Params.warning("Not creating traces archive: the %s directory does not exist" % traces_dir) + Logs.warn("Not creating traces archive: the %s directory does not exist" % traces_dir) else: traceball = traces_name + wutils.TRACEBALL_SUFFIX tar = tarfile.open(os.path.join("..", traceball), 'w:bz2') @@ -160,19 +167,18 @@ def check_compilation_flag(conf, flag): flag: can be a string or a list of strings """ - # Check for -Wno-error=deprecated-declarations - save_CXXFLAGS = list(conf.env['CXXFLAGS']) - conf.env.append_value('CXXFLAGS', flag) - e = conf.create_test_configurator() - e.mandatory = 0 - e.code = '#include \nint main() { return 0; }\n' - e.want_message = 0 - ok = e.run() - conf.check_message_custom(flag, 'compilation flag support', - (ok and 'yes' or 'no')) + env = conf.env.copy() + env.append_value('CXXFLAGS', flag) + try: + retval = conf.run_c_code(code='#include \nint main() { return 0; }\n', + env=env, compile_filename='test.cc', + compile_mode='cxx',type='program', execute=False) + except Configure.ConfigurationError: + ok = False + else: + ok = (retval == 0) + conf.check_message_custom(flag, 'support', (ok and 'yes' or 'no')) - if not ok: # if it doesn't accept, remove it again - conf.env['CXXFLAGS'] = save_CXXFLAGS def report_optional_feature(conf, name, caption, was_enabled, reason_not_enabled): conf.env.append_value('NS3_OPTIONAL_FEATURES', (name, caption, was_enabled, reason_not_enabled)) @@ -184,12 +190,14 @@ def configure(conf): conf.report_optional_feature = types.MethodType(report_optional_feature, conf) conf.env['NS3_OPTIONAL_FEATURES'] = [] - conf.env['NS3_BUILDDIR'] = conf.m_blddir + conf.env['NS3_BUILDDIR'] = conf.blddir conf.check_tool('compiler_cxx') + conf.check_tool('pkgconfig') + conf.check_tool('command') # create the second environment, set the variant and set its name variant_env = conf.env.copy() - debug_level = Params.g_options.debug_level.lower() + debug_level = Options.options.debug_level.lower() if debug_level == 'ultradebug': variant_name = 'debug' else: @@ -197,12 +205,12 @@ def configure(conf): variant_env['INCLUDEDIR'] = os.path.join(variant_env['PREFIX'], 'include') - if Params.g_options.regression_traces is not None: - variant_env['REGRESSION_TRACES'] = os.path.join("..", Params.g_options.regression_traces) + if Options.options.regression_traces is not None: + variant_env['REGRESSION_TRACES'] = os.path.join("..", Options.options.regression_traces) else: variant_env['REGRESSION_TRACES'] = None - if Params.g_options.enable_gcov: + if Options.options.enable_gcov: variant_name += '-gcov' variant_env.append_value('CCFLAGS', '-fprofile-arcs') variant_env.append_value('CCFLAGS', '-ftest-coverage') @@ -226,13 +234,13 @@ def configure(conf): check_compilation_flag(conf, '-Wno-error=deprecated-declarations') - if 'debug' in Params.g_options.debug_level.lower(): + if 'debug' in Options.options.debug_level.lower(): variant_env.append_value('CXXDEFINES', 'NS3_ASSERT_ENABLE') variant_env.append_value('CXXDEFINES', 'NS3_LOG_ENABLE') ## In optimized builds we still want debugging symbols, e.g. for ## profiling, and at least partially usable stack traces. - if ('optimized' in Params.g_options.debug_level.lower() + if ('optimized' in Options.options.debug_level.lower() and 'CXXFLAGS' not in os.environ): for flag in variant_env['CXXFLAGS_DEBUG']: ## this probably doesn't work for MSVC @@ -240,7 +248,7 @@ def configure(conf): variant_env.append_value('CXXFLAGS', flag) ## in optimized builds, replace -O2 with -O3 - if 'optimized' in Params.g_options.debug_level.lower(): + if 'optimized' in Options.options.debug_level.lower(): lst = variant_env['CXXFLAGS'] for i, flag in enumerate(lst): if flag == '-O2': @@ -254,9 +262,9 @@ def configure(conf): conf.sub_config('utils') conf.sub_config('bindings/python') - if Params.g_options.enable_modules: + if Options.options.enable_modules: conf.env['NS3_ENABLED_MODULES'] = ['ns3-'+mod for mod in - Params.g_options.enable_modules.split(',')] + Options.options.enable_modules.split(',')] # we cannot run regression tests without diff conf.find_program('diff', var='DIFF') @@ -280,9 +288,9 @@ def configure(conf): class SuidBuildTask(Task.TaskBase): """task that makes a binary Suid """ + after = 'link' def __init__(self, bld, program): self.m_display = 'build-suid' - self.prio = 1000 # build after the rest of ns-3 self.__program = program self.__env = bld.env () super(SuidBuildTask, self).__init__() @@ -291,29 +299,30 @@ class SuidBuildTask(Task.TaskBase): try: program_obj = wutils.find_program(self.__program.target, self.__env) except ValueError, ex: - Params.fatal(str(ex)) + raise Utils.WafError(str(ex)) - try: - program_node = program_obj.path.find_build(ccroot.get_target_name(program_obj)) - except AttributeError: - Params.fatal("%s does not appear to be a program" % (self.__program.name,)) + program_node = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj)) + #try: + # program_node = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj)) + #except AttributeError: + # raise Utils.WafError("%s does not appear to be a program" % (self.__program.name,)) filename = program_node.abspath(self.__env) os.system ('sudo chown root ' + filename) os.system ('sudo chmod u+s ' + filename) def create_suid_program(bld, name): - program = bld.create_obj('cpp', 'program') + program = bld.new_task_gen('cxx', 'program') program.is_ns3_program = True program.module_deps = list() program.name = name program.target = name - if bld.env ()['SUDO'] and Params.g_options.enable_sudo: - SuidBuildTask (bld, program) + if bld.env['SUDO'] and Options.options.enable_sudo: + SuidBuildTask(bld, program) return program def create_ns3_program(bld, name, dependencies=('simulator',)): - program = bld.create_obj('cpp', 'program') + program = bld.new_task_gen('cxx', 'program') program.is_ns3_program = True program.name = name program.target = program.name @@ -322,7 +331,7 @@ def create_ns3_program(bld, name, dependencies=('simulator',)): return program def add_scratch_programs(bld): - all_modules = [mod[len("ns3-"):] for mod in bld.env()['NS3_MODULES']] + all_modules = [mod[len("ns3-"):] for mod in bld.env['NS3_MODULES']] for filename in os.listdir("scratch"): if filename.startswith('.') or filename == 'CVS': continue @@ -356,7 +365,7 @@ def _exec_command_interact_win32(s): def build(bld): - if Params.g_options.no_task_lines: + if Options.options.no_task_lines: import Runner def null_printout(s): pass @@ -366,28 +375,30 @@ def build(bld): import Runner Runner.exec_command = _exec_command_interact_win32 - Params.g_cwd_launch = Params.g_build.m_curdirnode.abspath() + Options.cwd_launch = bld.path.abspath() bld.create_ns3_program = types.MethodType(create_ns3_program, bld) bld.create_suid_program = types.MethodType(create_suid_program, bld) + + # switch default variant to the one matching our debug level variant_name = bld.env_of_name('default')['NS3_ACTIVE_VARIANT'] variant_env = bld.env_of_name(variant_name) - bld.m_allenvs['default'] = variant_env # switch to the active variant + bld.all_envs['default'] = variant_env - if Params.g_options.shell: + if Options.options.shell: run_shell() raise SystemExit(0) - if Params.g_options.doxygen: + if Options.options.doxygen: doxygen() raise SystemExit(0) check_shell() - if Params.g_options.doxygen: + if Options.options.doxygen: doxygen() raise SystemExit(0) - print "Entering directory `%s'" % os.path.join(Params.g_build.m_curdirnode.abspath(), 'build') + print "Entering directory `%s'" % os.path.join(bld.path.abspath(), 'build') # process subfolders from here bld.add_subdirs('src') bld.add_subdirs('samples utils examples') @@ -397,13 +408,13 @@ def build(bld): ## if --enabled-modules option was given, we disable building the ## modules that were not enabled, and programs that depend on ## disabled modules. - env = bld.env() + env = bld.env - if Params.g_options.enable_modules: - Params.warning("the option --enable-modules is being applied to this build only;" + if Options.options.enable_modules: + Logs.warn("the option --enable-modules is being applied to this build only;" " to make it permanent it needs to be given to waf configure.") env['NS3_ENABLED_MODULES'] = ['ns3-'+mod for mod in - Params.g_options.enable_modules.split(',')] + Options.options.enable_modules.split(',')] if env['NS3_ENABLED_MODULES']: modules = env['NS3_ENABLED_MODULES'] @@ -422,17 +433,17 @@ def build(bld): changed = True ## remove objects that depend on modules not listed - for obj in list(Object.g_allobjs): + for obj in list(Build.bld.all_task_gen): if hasattr(obj, 'ns3_module_dependencies'): for dep in obj.ns3_module_dependencies: if dep not in modules: - Object.g_allobjs.remove(obj) + Build.bld.all_task_gen.remove(obj) break if obj.name in env['NS3_MODULES'] and obj.name not in modules: - Object.g_allobjs.remove(obj) + Build.bld.all_task_gen.remove(obj) ## Create a single ns3 library containing all enabled modules - lib = bld.create_obj('cpp', 'shlib') + lib = bld.new_task_gen('cxx', 'shlib') lib.name = 'ns3' lib.target = 'ns3' if env['NS3_ENABLED_MODULES']: @@ -445,25 +456,25 @@ def build(bld): bld.add_subdirs('bindings/python') - if Params.g_options.run: + if Options.options.run: # Check that the requested program name is valid - program_name, dummy_program_argv = wutils.get_run_program(Params.g_options.run, get_command_template()) + program_name, dummy_program_argv = wutils.get_run_program(Options.options.run, get_command_template()) # When --run'ing a program, tell WAF to only build that program, # nothing more; this greatly speeds up compilation when all you # want to do is run a test program. - if not Params.g_options.compile_targets: - Params.g_options.compile_targets = program_name + if not Options.options.compile_targets: + Options.options.compile_targets = program_name def get_command_template(*arguments): - if Params.g_options.valgrind: - if Params.g_options.command_template: - Params.fatal("Options --command-template and --valgrind are conflicting") + if Options.options.valgrind: + if Options.options.command_template: + raise Utils.WafError("Options --command-template and --valgrind are conflicting") cmd = "valgrind --leak-check=full %s" else: - cmd = Params.g_options.command_template or '%s' + cmd = Options.options.command_template or '%s' for arg in arguments: cmd = cmd + " " + arg return cmd @@ -477,14 +488,14 @@ def shutdown(): #ut.want_to_see_test_error = True #ut.run() #ut.print_results() - env = Params.g_build.env_of_name('default') + env = Build.bld.env - if Params.g_commands['check']: + if Options.commands['check']: _run_waf_check() - if Params.g_options.regression or Params.g_options.regression_generate: + if Options.options.regression or Options.options.regression_generate: if not env['DIFF']: - Params.fatal("Cannot run regression tests: the 'diff' program is not installed.") + raise Utils.WafError("Cannot run regression tests: the 'diff' program is not installed.") _dir = os.getcwd() os.chdir("regression") @@ -498,20 +509,20 @@ def shutdown(): if retval: sys.exit(retval) - if Params.g_options.lcov_report: + if Options.options.lcov_report: lcov_report() - if Params.g_options.run: - wutils.run_program(Params.g_options.run, get_command_template()) + if Options.options.run: + wutils.run_program(Options.options.run, get_command_template()) raise SystemExit(0) - if Params.g_options.pyrun: - wutils.run_python_program(Params.g_options.pyrun) + if Options.options.pyrun: + wutils.run_python_program(Options.options.pyrun) raise SystemExit(0) def _run_waf_check(): ## generate the trace sources list docs - env = Params.g_build.env_of_name('default') + env = Build.bld.env proc_env = wutils.get_proc_env() try: program_obj = wutils.find_program('print-introspected-doxygen', env) @@ -520,7 +531,7 @@ def _run_waf_check(): # --enable-modules=xxx pass else: - prog = program_obj.path.find_build(ccroot.get_target_name(program_obj)).abspath(env) + prog = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj)).abspath(env) out = open(os.path.join('doc', 'introspected-doxygen.h'), 'w') if subprocess.Popen([prog], stdout=out, env=proc_env).wait(): raise SystemExit(1) @@ -541,7 +552,7 @@ def _run_waf_check(): def check_shell(): if 'NS3_MODULE_PATH' not in os.environ: return - env = Params.g_build.env_of_name('default') + env = Build.bld.env correct_modpath = os.pathsep.join(env['NS3_MODULE_PATH']) found_modpath = os.environ['NS3_MODULE_PATH'] if found_modpath != correct_modpath: @@ -554,7 +565,7 @@ def check_shell(): "You should correct this situation before running any program. Possible solutions:\n" " 1. Exit this shell, and start a new one\n" " 2. Run a new nested shell") - Params.fatal(msg) + raise Utils.WafError(msg) def run_shell(): @@ -563,12 +574,12 @@ def run_shell(): else: shell = os.environ.get("SHELL", "/bin/sh") - env = Params.g_build.env_of_name('default') + env = Build.bld.env wutils.run_argv([shell], {'NS3_MODULE_PATH': os.pathsep.join(env['NS3_MODULE_PATH'])}) def doxygen(): if not os.path.exists('doc/introspected-doxygen.h'): - Params.warning("doc/introspected-doxygen.h does not exist; run waf check to generate it.") + Logs.warn("doc/introspected-doxygen.h does not exist; run waf check to generate it.") ## run doxygen doxygen_config = os.path.join('doc', 'doxygen.conf') @@ -576,11 +587,11 @@ def doxygen(): raise SystemExit(1) def lcov_report(): - env = Params.g_build.env_of_name('default') + env = Build.bld.env variant_name = env['NS3_ACTIVE_VARIANT'] if 'gcov' not in variant_name: - Params.fatal("project not configured for code coverage;" + raise Utils.WafError("project not configured for code coverage;" " reconfigure with --enable-gcov") os.chdir(blddir) @@ -618,7 +629,7 @@ def lcov_report(): ## implementation that is more efficient. ## import Scripting -from Scripting import g_dist_exts, g_excludes, BLDDIR +from Scripting import dist_exts, excludes, BLDDIR import Utils import os @@ -667,7 +678,7 @@ def copytree(src, dst, symlinks=False, excludes=(), build_dir=None): if name.startswith('.') or name.startswith('++'): to_remove = True else: - for x in g_dist_exts: + for x in dist_exts: if ends(x): to_remove = True break @@ -707,7 +718,7 @@ def DistDir(appname, version): build_dir = getattr(Utils.g_module, BLDDIR, None) # Copy everything into the new folder - copytree('.', TMPFOLDER, excludes=g_excludes, build_dir=build_dir) + copytree('.', TMPFOLDER, excludes=excludes, build_dir=build_dir) # TODO undocumented hook dist_hook = getattr(Utils.g_module, 'dist_hook', None) diff --git a/wutils.py b/wutils.py index fe89dd579..1b0413692 100644 --- a/wutils.py +++ b/wutils.py @@ -1,15 +1,22 @@ import os import os.path -import Params -import Object import sys import pproc as subprocess import shlex + +# WAF modules import ccroot +import Options +import Utils +import Logs +import TaskGen +import Build + # these are set from the main wscript file APPNAME=None VERSION=None + # # The last part of the path name to use to find the regression traces tarball. # path will be APPNAME + '-' + VERSION + REGRESSION_SUFFIX + TRACEBALL_SUFFIX, @@ -20,12 +27,12 @@ TRACEBALL_SUFFIX = ".tar.bz2" def get_command_template(*arguments): - if Params.g_options.valgrind: - if Params.g_options.command_template: - Params.fatal("Options --command-template and --valgrind are conflicting") + if Options.options.valgrind: + if Options.options.command_template: + raise Utils.WafError("Options --command-template and --valgrind are conflicting") cmd = "valgrind --leak-check=full %s" else: - cmd = Params.g_options.command_template or '%s' + cmd = Options.options.command_template or '%s' for arg in arguments: cmd = cmd + " " + arg return cmd @@ -33,9 +40,9 @@ def get_command_template(*arguments): def find_program(program_name, env): - launch_dir = os.path.abspath(Params.g_cwd_launch) + launch_dir = os.path.abspath(Options.cwd_launch) found_programs = [] - for obj in Object.g_allobjs: + for obj in Build.bld.all_task_gen: if not getattr(obj, 'is_ns3_program', False): continue @@ -51,7 +58,7 @@ def find_program(program_name, env): % (program_name, found_programs)) def get_proc_env(os_env=None): - env = Params.g_build.env_of_name('default') + env = Build.bld.env if sys.platform == 'linux2': pathvar = 'LD_LIBRARY_PATH' elif sys.platform == 'darwin': @@ -63,7 +70,7 @@ def get_proc_env(os_env=None): elif sys.platform.startswith('freebsd'): pathvar = 'LD_LIBRARY_PATH' else: - Params.warning(("Don't know how to configure " + Logs.warn(("Don't know how to configure " "dynamic library path for the platform %r;" " assuming it's LD_LIBRARY_PATH.") % (sys.platform,)) pathvar = 'LD_LIBRARY_PATH' @@ -78,7 +85,7 @@ def get_proc_env(os_env=None): else: proc_env[pathvar] = os.pathsep.join(list(env['NS3_MODULE_PATH'])) - pymoddir = Params.g_build.m_curdirnode.find_dir('bindings/python').abspath(env) + pymoddir = Build.bld.path.find_dir('bindings/python').abspath(env) if 'PYTHONPATH' in proc_env: proc_env['PYTHONPATH'] = os.pathsep.join([pymoddir] + [proc_env['PYTHONPATH']]) else: @@ -88,10 +95,10 @@ def get_proc_env(os_env=None): def run_argv(argv, os_env=None): proc_env = get_proc_env(os_env) - #env = Params.g_build.env_of_name('default') + #env = Build.bld.env retval = subprocess.Popen(argv, env=proc_env).wait() if retval: - Params.fatal("Command %s exited with code %i" % (argv, retval)) + raise Utils.WafError("Command %s exited with code %i" % (argv, retval)) return retval def get_run_program(program_string, command_template=None): @@ -100,7 +107,7 @@ def get_run_program(program_string, command_template=None): run_program(program_string, command_template). """ #print "get_run_program_argv(program_string=%r, command_template=%r)" % (program_string, command_template) - env = Params.g_build.env_of_name('default') + env = Build.bld.env if command_template in (None, '%s'): argv = shlex.split(program_string) @@ -109,12 +116,13 @@ def get_run_program(program_string, command_template=None): try: program_obj = find_program(program_name, env) except ValueError, ex: - Params.fatal(str(ex)) + raise Utils.WafError(str(ex)) - try: - program_node = program_obj.path.find_build(ccroot.get_target_name(program_obj)) - except AttributeError: - Params.fatal("%s does not appear to be a program" % (program_name,)) + program_node = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj)) + #try: + # program_node = program_obj.path.find_build(ccroot.get_target_name(program_obj)) + #except AttributeError: + # raise Utils.WafError("%s does not appear to be a program" % (program_name,)) execvec = [program_node.abspath(env)] + argv[1:] @@ -124,11 +132,13 @@ def get_run_program(program_string, command_template=None): try: program_obj = find_program(program_name, env) except ValueError, ex: - Params.fatal(str(ex)) - try: - program_node = program_obj.path.find_build(ccroot.get_target_name(program_obj)) - except AttributeError: - Params.fatal("%s does not appear to be a program" % (program_name,)) + raise Utils.WafError(str(ex)) + + program_node = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj)) + #try: + # program_node = program_obj.path.find_build(ccroot.get_target_name(program_obj)) + #except AttributeError: + # raise Utils.WafError("%s does not appear to be a program" % (program_name,)) execvec = shlex.split(command_template % (program_node.abspath(env),)) return program_name, execvec @@ -142,10 +152,10 @@ def run_program(program_string, command_template=None): """ dummy_program_name, execvec = get_run_program(program_string, command_template) former_cwd = os.getcwd() - if (Params.g_options.cwd_launch): - os.chdir(Params.g_options.cwd_launch) + if (Options.options.cwd_launch): + os.chdir(Options.options.cwd_launch) else: - os.chdir(Params.g_cwd_launch) + os.chdir(Options.cwd_launch) try: retval = run_argv(execvec) finally: @@ -156,14 +166,14 @@ def run_program(program_string, command_template=None): def run_python_program(program_string): - env = Params.g_build.env_of_name('default') + env = Build.bld.env execvec = shlex.split(program_string) former_cwd = os.getcwd() - if (Params.g_options.cwd_launch): - os.chdir(Params.g_options.cwd_launch) + if (Options.options.cwd_launch): + os.chdir(Options.options.cwd_launch) else: - os.chdir(Params.g_cwd_launch) + os.chdir(Options.cwd_launch) try: retval = run_argv([env['PYTHON']] + execvec) finally: