Merge waf-1.6 branch
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
^testpy-output
|
||||
^doc/html
|
||||
^doc/latex
|
||||
^\.lock-wscript
|
||||
^\.lock-wafbuild
|
||||
^\.waf
|
||||
^doc/introspected-doxygen\.h$
|
||||
.*\.py[co]$
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import types
|
||||
import re
|
||||
import os
|
||||
import pproc as subprocess
|
||||
import subprocess
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
@@ -14,6 +14,8 @@ import Logs
|
||||
import Build
|
||||
import Utils
|
||||
|
||||
from waflib.Errors import WafError
|
||||
|
||||
## https://launchpad.net/pybindgen/
|
||||
REQUIRED_PYBINDGEN_VERSION = (0, 15, 0, 795)
|
||||
REQUIRED_PYGCCXML_VERSION = (0, 9, 5)
|
||||
@@ -21,17 +23,17 @@ REQUIRED_PYGCCXML_VERSION = (0, 9, 5)
|
||||
|
||||
|
||||
from TaskGen import feature, after
|
||||
import Task, ccroot
|
||||
from python import _get_python_variables # this comes from wafadmin/Tools/python.py
|
||||
import Task
|
||||
#from python import _get_python_variables # this comes from wafadmin/Tools/python.py
|
||||
|
||||
|
||||
# Patch a bug in waf-1.5.16's python detection, see
|
||||
# https://www.nsnam.org/bugzilla/show_bug.cgi?id=1250
|
||||
import python
|
||||
python.FRAG_2 = """
|
||||
#include <Python.h>
|
||||
""" + python.FRAG_2
|
||||
del python
|
||||
if 0:
|
||||
# Patch a bug in waf-1.5.16's python detection, see
|
||||
# https://www.nsnam.org/bugzilla/show_bug.cgi?id=1250
|
||||
import python
|
||||
python.FRAG_2 = """
|
||||
#include <Python.h>
|
||||
""" + python.FRAG_2
|
||||
del python
|
||||
|
||||
|
||||
|
||||
@@ -46,18 +48,14 @@ def set_pybindgen_pythonpath(env):
|
||||
add_to_python_path(env['WITH_PYBINDGEN'])
|
||||
|
||||
|
||||
def set_options(opt):
|
||||
def options(opt):
|
||||
opt.tool_options('python')
|
||||
opt.add_option('--disable-python',
|
||||
help=("Don't build Python bindings."),
|
||||
action="store_true", default=False,
|
||||
dest='python_disable')
|
||||
opt.add_option('--python-scan',
|
||||
help=("Rescan Python bindings. Needs working GCCXML / pygccxml environment."),
|
||||
action="store_true", default=False,
|
||||
dest='python_scan')
|
||||
opt.add_option('--apiscan',
|
||||
help=("EXPERIMENTAL: Rescan the API for the indicated module(s), for Python bindings. "
|
||||
help=("Rescan the API for the indicated module(s), for Python bindings. "
|
||||
"Needs working GCCXML / pygccxml environment. "
|
||||
"The metamodule 'all' expands to all available ns-3 modules."),
|
||||
default=None, dest='apiscan', metavar="MODULE[,MODULE...]")
|
||||
@@ -86,7 +84,7 @@ def configure(conf):
|
||||
available_modules.sort()
|
||||
all_modules_enabled = (enabled_modules == available_modules)
|
||||
|
||||
conf.check_tool('misc')
|
||||
conf.check_tool('misc', tooldir=['waf-tools'])
|
||||
|
||||
if sys.platform == 'cygwin':
|
||||
conf.report_optional_feature("python", "Python Bindings", False,
|
||||
@@ -103,17 +101,33 @@ def configure(conf):
|
||||
conf.report_optional_feature("python", "Python Bindings", False, str(ex))
|
||||
return
|
||||
|
||||
# stupid Mac OSX Python wants to build extensions as "universal
|
||||
# binaries", i386, x86_64, and ppc, but this way the type
|
||||
# __uint128_t is not available. We need to disable the multiarch
|
||||
# crap by removing the -arch parameters.
|
||||
for flags_var in ["CFLAGS_PYEXT", "CFLAGS_PYEMBED", "CXXFLAGS_PYEMBED",
|
||||
"CXXFLAGS_PYEXT", "LINKFLAGS_PYEMBED", "LINKFLAGS_PYEXT"]:
|
||||
flags = conf.env[flags_var]
|
||||
i = 0
|
||||
while i < len(flags):
|
||||
if flags[i] == '-arch':
|
||||
del flags[i]
|
||||
del flags[i]
|
||||
continue
|
||||
i += 1
|
||||
conf.env[flags_var] = flags
|
||||
|
||||
# alternative code to computing PYTHONDIR, that is more correct than the one in waf 1.5.16
|
||||
if 'PYTHONDIR' in conf.environ:
|
||||
pydir = conf.environ['PYTHONDIR']
|
||||
else:
|
||||
(pydir,) = _get_python_variables(conf.env['PYTHON'],
|
||||
["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r)" % conf.env['PREFIX']],
|
||||
['from distutils.sysconfig import get_python_lib'])
|
||||
if hasattr(conf, 'define'): # conf.define is added by the C tool, so may not exist
|
||||
conf.define('PYTHONDIR', pydir)
|
||||
conf.env['PYTHONDIR'] = pydir
|
||||
if 0:
|
||||
# alternative code to computing PYTHONDIR, that is more correct than the one in waf 1.5.16
|
||||
if 'PYTHONDIR' in conf.environ:
|
||||
pydir = conf.environ['PYTHONDIR']
|
||||
else:
|
||||
(pydir,) = _get_python_variables(conf.env['PYTHON'],
|
||||
["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r)" % conf.env['PREFIX']],
|
||||
['from distutils.sysconfig import get_python_lib'])
|
||||
if hasattr(conf, 'define'): # conf.define is added by the C tool, so may not exist
|
||||
conf.define('PYTHONDIR', pydir)
|
||||
conf.env['PYTHONDIR'] = pydir
|
||||
|
||||
|
||||
# -fvisibility=hidden optimization
|
||||
@@ -125,7 +139,7 @@ def configure(conf):
|
||||
# Check for the location of pybindgen
|
||||
if Options.options.with_pybindgen is not None:
|
||||
if os.path.isdir(Options.options.with_pybindgen):
|
||||
conf.check_message("pybindgen location", '', True, ("%s (given)" % Options.options.with_pybindgen))
|
||||
conf.msg("Checking for pybindgen location", ("%s (given)" % Options.options.with_pybindgen))
|
||||
conf.env['WITH_PYBINDGEN'] = os.path.abspath(Options.options.with_pybindgen)
|
||||
else:
|
||||
# ns-3-dev uses ../pybindgen, while ns-3 releases use ../REQUIRED_PYBINDGEN_VERSION
|
||||
@@ -133,15 +147,15 @@ def configure(conf):
|
||||
pybindgen_release_str = "pybindgen-" + '.'.join([str(x) for x in REQUIRED_PYBINDGEN_VERSION])
|
||||
pybindgen_release_dir = os.path.join('..', pybindgen_release_str)
|
||||
if os.path.isdir(pybindgen_dir):
|
||||
conf.check_message("pybindgen location", '', True, ("%s (guessed)" % pybindgen_dir))
|
||||
conf.msg("Checking for pybindgen location", ("%s (guessed)" % pybindgen_dir))
|
||||
conf.env['WITH_PYBINDGEN'] = os.path.abspath(pybindgen_dir)
|
||||
elif os.path.isdir(pybindgen_release_dir):
|
||||
conf.check_message("pybindgen location", '', True, ("%s (guessed)" % pybindgen_release_dir))
|
||||
conf.msg("Checking for pybindgen location", ("%s (guessed)" % pybindgen_release_dir))
|
||||
conf.env['WITH_PYBINDGEN'] = os.path.abspath(pybindgen_release_dir)
|
||||
del pybindgen_dir
|
||||
del pybindgen_release_dir
|
||||
if not conf.env['WITH_PYBINDGEN']:
|
||||
conf.check_message("pybindgen location", '', False)
|
||||
conf.msg("pybindgen location", False)
|
||||
|
||||
# Check for pybindgen
|
||||
|
||||
@@ -155,15 +169,13 @@ def configure(conf):
|
||||
"PyBindGen missing")
|
||||
return
|
||||
else:
|
||||
out = subprocess.Popen([conf.env['PYTHON'], "-c",
|
||||
out = subprocess.Popen([conf.env['PYTHON'][0], "-c",
|
||||
"import pybindgen.version; "
|
||||
"print '.'.join([str(x) for x in pybindgen.version.__version__])"],
|
||||
stdout=subprocess.PIPE).communicate()[0]
|
||||
pybindgen_version_str = out.strip()
|
||||
pybindgen_version = tuple([int(x) for x in pybindgen_version_str.split('.')])
|
||||
conf.check_message('pybindgen', 'version',
|
||||
(pybindgen_version == REQUIRED_PYBINDGEN_VERSION),
|
||||
pybindgen_version_str)
|
||||
conf.msg('Checking for pybindgen version', pybindgen_version_str)
|
||||
if not (pybindgen_version == REQUIRED_PYBINDGEN_VERSION):
|
||||
Logs.warn("pybindgen (found %s), (need %s)" %
|
||||
(pybindgen_version_str,
|
||||
@@ -188,10 +200,10 @@ int main ()
|
||||
try:
|
||||
ret = conf.run_c_code(code=test_program,
|
||||
env=conf.env.copy(), compile_filename='test.cc',
|
||||
compile_mode='cxx',type='cprogram', execute=False)
|
||||
features='cxx cprogram', execute=False)
|
||||
except Configure.ConfigurationError:
|
||||
ret = 1
|
||||
conf.check_message_custom('types %s and %s' % (t1, t2), 'equivalency', (ret and 'no' or 'yes'))
|
||||
conf.msg('Checking for types %s and %s equivalence' % (t1, t2), (ret and 'no' or 'yes'))
|
||||
return not ret
|
||||
|
||||
uint64_is_long = test("uint64_t", "unsigned long")
|
||||
@@ -208,7 +220,7 @@ int main ()
|
||||
else:
|
||||
msg = conf.env['PYTHON_BINDINGS_APIDEFS']
|
||||
|
||||
conf.check_message_custom('the apidefs that can be used for Python bindings', '', msg)
|
||||
conf.msg('Checking for the apidefs that can be used for Python bindings', msg)
|
||||
|
||||
if conf.env['PYTHON_BINDINGS_APIDEFS'] is None:
|
||||
conf.report_optional_feature("python", "Python Bindings", False,
|
||||
@@ -230,9 +242,9 @@ int main ()
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
gcc_rtti_abi = conf.check(fragment=fragment, msg="Checking for internal GCC cxxabi",
|
||||
okmsg="complete", errmsg='incomplete',
|
||||
mandatory=False)
|
||||
gcc_rtti_abi = conf.check_nonfatal(fragment=fragment, msg="Checking for internal GCC cxxabi",
|
||||
okmsg="complete", errmsg='incomplete',
|
||||
mandatory=False)
|
||||
conf.env["GCC_RTTI_ABI_COMPLETE"] = str(bool(gcc_rtti_abi))
|
||||
|
||||
|
||||
@@ -245,14 +257,12 @@ int main ()
|
||||
"Missing 'pygccxml' Python module")
|
||||
return
|
||||
|
||||
out = subprocess.Popen([conf.env['PYTHON'], "-c",
|
||||
out = subprocess.Popen([conf.env['PYTHON'][0], "-c",
|
||||
"import pygccxml; print pygccxml.__version__"],
|
||||
stdout=subprocess.PIPE).communicate()[0]
|
||||
pygccxml_version_str = out.strip()
|
||||
pygccxml_version = tuple([int(x) for x in pygccxml_version_str.split('.')])
|
||||
conf.check_message('pygccxml', 'version',
|
||||
(pygccxml_version >= REQUIRED_PYGCCXML_VERSION),
|
||||
pygccxml_version_str)
|
||||
conf.msg('Checking for pygccxml version', pygccxml_version_str)
|
||||
if not (pygccxml_version >= REQUIRED_PYGCCXML_VERSION):
|
||||
Logs.warn("pygccxml (found %s) is too old (need %s) => "
|
||||
"automatic scanning of API definitions will not be possible" %
|
||||
@@ -264,7 +274,10 @@ int main ()
|
||||
|
||||
|
||||
## Check gccxml version
|
||||
gccxml = conf.find_program('gccxml', var='GCCXML')
|
||||
try:
|
||||
gccxml = conf.find_program('gccxml', var='GCCXML')
|
||||
except WafError:
|
||||
gccxml = None
|
||||
if not gccxml:
|
||||
Logs.warn("gccxml missing; automatic scanning of API definitions will not be possible")
|
||||
conf.report_optional_feature("pygccxml", "Python API Scanning Support", False,
|
||||
@@ -275,7 +288,7 @@ int main ()
|
||||
m = re.match( "^GCC-XML version (\d\.\d(\.\d)?)$", gccxml_version_line)
|
||||
gccxml_version = m.group(1)
|
||||
gccxml_version_ok = ([int(s) for s in gccxml_version.split('.')] >= [0, 9])
|
||||
conf.check_message('gccxml', 'version', True, gccxml_version)
|
||||
conf.msg('Checking for gccxml version', gccxml_version)
|
||||
if not gccxml_version_ok:
|
||||
Logs.warn("gccxml too old, need version >= 0.9; automatic scanning of API definitions will not be possible")
|
||||
conf.report_optional_feature("pygccxml", "Python API Scanning Support", False,
|
||||
@@ -291,19 +304,18 @@ int main ()
|
||||
def get_headers_map(bld):
|
||||
headers_map = {} # header => module
|
||||
for ns3headers in bld.all_task_gen:
|
||||
if type(ns3headers).__name__ == 'ns3header_taskgen': # XXX: find less hackish way to compare
|
||||
if 'ns3header' in getattr(ns3headers, "features", []):
|
||||
if ns3headers.module.endswith('-test'):
|
||||
continue
|
||||
for h in ns3headers.to_list(ns3headers.source):
|
||||
for h in ns3headers.to_list(ns3headers.headers):
|
||||
headers_map[os.path.basename(h)] = ns3headers.module
|
||||
return headers_map
|
||||
|
||||
def get_module_path(bld, module):
|
||||
for ns3headers in bld.all_task_gen:
|
||||
if type(ns3headers).__name__ == 'ns3header_taskgen': # XXX: find less hackish way to compare
|
||||
if 'ns3header' in getattr(ns3headers, "features", []):
|
||||
if ns3headers.module == module:
|
||||
break
|
||||
|
||||
else:
|
||||
raise ValueError("Module %r not found" % module)
|
||||
return ns3headers.path.abspath()
|
||||
@@ -311,8 +323,8 @@ def get_module_path(bld, module):
|
||||
class apiscan_task(Task.TaskBase):
|
||||
"""Uses gccxml to scan the file 'everything.h' and extract API definitions.
|
||||
"""
|
||||
after = 'gen_ns3_module_header_task ns3header_task'
|
||||
before = 'cc cxx gchx'
|
||||
after = 'gen_ns3_module_header ns3header'
|
||||
before = 'cc cxx command'
|
||||
color = "BLUE"
|
||||
def __init__(self, curdirnode, env, bld, target, cflags, module):
|
||||
self.bld = bld
|
||||
@@ -327,7 +339,7 @@ class apiscan_task(Task.TaskBase):
|
||||
return 'api-scan-%s\n' % (self.target,)
|
||||
|
||||
def run(self):
|
||||
top_builddir = self.curdirnode.find_dir('../..').abspath(self.env)
|
||||
top_builddir = self.bld.bldnode.abspath()
|
||||
module_path = get_module_path(self.bld, self.module)
|
||||
headers_map = get_headers_map(self.bld)
|
||||
scan_header = os.path.join(top_builddir, "ns3", "%s-module.h" % self.module)
|
||||
@@ -337,7 +349,7 @@ class apiscan_task(Task.TaskBase):
|
||||
return 0
|
||||
|
||||
argv = [
|
||||
self.env['PYTHON'],
|
||||
self.env['PYTHON'][0],
|
||||
os.path.join(self.curdirnode.abspath(), 'ns3modulescan-modular.py'), # scanning script
|
||||
top_builddir,
|
||||
self.module,
|
||||
@@ -367,58 +379,22 @@ def get_modules_and_headers(bld):
|
||||
## find the headers object for this module
|
||||
headers = []
|
||||
for ns3headers in bld.all_task_gen:
|
||||
if type(ns3headers).__name__ != 'ns3header_taskgen': # XXX: find less hackish way to compare
|
||||
if 'ns3header' not in getattr(ns3headers, "features", []):
|
||||
continue
|
||||
if ns3headers.module != module_name:
|
||||
continue
|
||||
for source in ns3headers.to_list(ns3headers.source):
|
||||
for source in ns3headers.to_list(ns3headers.headers):
|
||||
headers.append(os.path.basename(source))
|
||||
retval[module_name] = (list(module.module_deps), headers)
|
||||
return retval
|
||||
|
||||
|
||||
|
||||
class python_scan_task(Task.TaskBase):
|
||||
"""Uses gccxml to scan the file 'everything.h' and extract API definitions.
|
||||
"""
|
||||
after = 'gen_everything_h_task'
|
||||
before = 'cc cxx gchx'
|
||||
color = "BLUE"
|
||||
def __init__(self, curdirnode, env, bld, target, cflags):
|
||||
self.bld = bld
|
||||
super(python_scan_task, self).__init__(generator=self)
|
||||
self.curdirnode = curdirnode
|
||||
self.env = env
|
||||
self.target = target
|
||||
self.cflags = cflags
|
||||
|
||||
def display(self):
|
||||
return 'python-scan-%s\n' % (self.target,)
|
||||
|
||||
def run(self):
|
||||
defsdir = os.path.join(self.curdirnode.abspath(), 'apidefs', self.target)
|
||||
try:
|
||||
os.mkdir(defsdir)
|
||||
except OSError:
|
||||
pass
|
||||
argv = [
|
||||
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_or_declare('everything.h').abspath(self.env),
|
||||
os.path.join(defsdir, 'ns3modulegen_generated.py'), # output file
|
||||
self.cflags,
|
||||
]
|
||||
scan = subprocess.Popen(argv, stdin=subprocess.PIPE)
|
||||
print >> scan.stdin, repr(get_modules_and_headers(self.bld))
|
||||
scan.stdin.close()
|
||||
retval = scan.wait()
|
||||
return retval
|
||||
|
||||
class python_scan_task_collector(Task.TaskBase):
|
||||
"""Tasks that waits for the python-scan-* tasks to complete and then signals WAF to exit
|
||||
"""
|
||||
after = 'python_scan_task apiscan_task'
|
||||
after = 'apiscan'
|
||||
before = 'cc cxx'
|
||||
color = "BLUE"
|
||||
def __init__(self, curdirnode, env, bld):
|
||||
@@ -434,19 +410,20 @@ class python_scan_task_collector(Task.TaskBase):
|
||||
# signal stop (we generated files into the source dir and WAF
|
||||
# can't cope with it, so we have to force the user to restart
|
||||
# WAF)
|
||||
self.bld.generator.stop = 1
|
||||
self.bld.producer.stop = 1
|
||||
self.bld.producer.free_task_pool()
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
class gen_ns3_compat_pymod_task(Task.Task):
|
||||
"""Generates a 'ns3.py' compatibility module."""
|
||||
before = 'cc cxx gchx'
|
||||
before = 'cc cxx'
|
||||
color = 'BLUE'
|
||||
|
||||
def run(self):
|
||||
assert len(self.outputs) == 1
|
||||
outfile = file(self.outputs[0].abspath(self.env), "w")
|
||||
outfile = file(self.outputs[0].abspath(), "w")
|
||||
print >> outfile, "import warnings"
|
||||
print >> outfile, 'warnings.warn("the ns3 module is a compatibility layer '\
|
||||
'and should not be used in newly written code", DeprecationWarning, stacklevel=2)'
|
||||
@@ -505,16 +482,20 @@ def build(bld):
|
||||
scan_modules = Options.options.apiscan.split(',')
|
||||
print "Modules to scan: ", scan_modules
|
||||
for target, cflags in scan_targets:
|
||||
group = bld.get_group(bld.current_group)
|
||||
for module in scan_modules:
|
||||
apiscan_task(bld.path, env, bld, target, cflags, module)
|
||||
python_scan_task_collector(bld.path, env, bld)
|
||||
group.append(apiscan_task(bld.path, env, bld, target, cflags, module))
|
||||
group.append(python_scan_task_collector(bld.path, env, bld))
|
||||
return
|
||||
|
||||
|
||||
if env['ENABLE_PYTHON_BINDINGS']:
|
||||
task = gen_ns3_compat_pymod_task(env)
|
||||
task = gen_ns3_compat_pymod_task(env=env.derive())
|
||||
task.set_outputs(bld.path.find_or_declare("ns3.py"))
|
||||
task.dep_vars = ['PYTHON_MODULES_BUILT']
|
||||
task.bld = bld
|
||||
grp = bld.get_group(bld.current_group)
|
||||
grp.append(task)
|
||||
|
||||
# note: the actual build commands for the python bindings are in
|
||||
# src/wscript, not here.
|
||||
|
||||
@@ -23,7 +23,7 @@ def build(bld):
|
||||
'test/loopback.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'aodv'
|
||||
headers.source = [
|
||||
'model/aodv-id-cache.h',
|
||||
|
||||
@@ -32,7 +32,7 @@ def build(bld):
|
||||
'test/udp-client-server-test.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'applications'
|
||||
headers.source = [
|
||||
'model/bulk-send-application.h',
|
||||
|
||||
@@ -7,7 +7,7 @@ def build(bld):
|
||||
'model/bridge-channel.cc',
|
||||
'helper/bridge-helper.cc',
|
||||
]
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'bridge'
|
||||
headers.source = [
|
||||
'model/bridge-net-device.h',
|
||||
|
||||
@@ -4,24 +4,32 @@ import os
|
||||
import Options
|
||||
|
||||
|
||||
def set_options(opt):
|
||||
def options(opt):
|
||||
opt.add_option('--with-nsclick',
|
||||
help=('Path to Click source or installation prefix for NS-3 Click Integration support'),
|
||||
dest='with_nsclick', default=None)
|
||||
opt.add_option('--disable-nsclick',
|
||||
help=('Disable NS-3 Click Integration support'),
|
||||
dest='disable_nsclick', default=False, action="store_true")
|
||||
|
||||
def configure(conf):
|
||||
if Options.options.disable_nsclick:
|
||||
conf.report_optional_feature("nsclick", "NS-3 Click Integration", False,
|
||||
"disabled by user request")
|
||||
return
|
||||
|
||||
if Options.options.with_nsclick:
|
||||
if os.path.isdir(Options.options.with_nsclick):
|
||||
conf.check_message("libnsclick.so location", '', True, ("%s (given)" % Options.options.with_nsclick))
|
||||
conf.msg("libnsclick.so location", ("%s (given)" % Options.options.with_nsclick))
|
||||
conf.env['WITH_NSCLICK'] = os.path.abspath(Options.options.with_nsclick)
|
||||
else:
|
||||
nsclick_dir = os.path.join('..','click')
|
||||
if os.path.isdir(nsclick_dir):
|
||||
conf.check_message("click location", '', True, ("%s (guessed)" % nsclick_dir))
|
||||
conf.msg("click location", ("%s (guessed)" % nsclick_dir))
|
||||
conf.env['WITH_NSCLICK'] = os.path.abspath(nsclick_dir)
|
||||
del nsclick_dir
|
||||
if not conf.env['WITH_NSCLICK']:
|
||||
conf.check_message("click location", '', False)
|
||||
conf.msg("click location", False)
|
||||
conf.report_optional_feature("nsclick", "NS-3 Click Integration", False,
|
||||
"nsclick not enabled (see option --with-nsclick)")
|
||||
|
||||
@@ -58,7 +66,7 @@ int main()
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
conf.env['DL'] = conf.check(mandatory=True, lib='dl', define_name='DL', uselib='DL')
|
||||
conf.env['DL'] = conf.check(mandatory=True, lib='dl', define_name='DL', uselib_store='DL')
|
||||
|
||||
for tmp in ['lib', 'ns']:
|
||||
libdir = os.path.abspath(os.path.join(conf.env['WITH_NSCLICK'],tmp))
|
||||
@@ -68,11 +76,11 @@ int main()
|
||||
|
||||
conf.env['CPPPATH_NSCLICK'] = [os.path.abspath(os.path.join(conf.env['WITH_NSCLICK'],'include'))]
|
||||
|
||||
conf.env['NSCLICK'] = conf.check(fragment=test_code, lib='nsclick', uselib='NSCLICK DL')
|
||||
conf.env['NSCLICK'] = conf.check_nonfatal(fragment=test_code, lib='nsclick', use='DL', uselib_store='NSCLICK')
|
||||
conf.report_optional_feature("nsclick", "NS-3 Click Integration",
|
||||
conf.env['NSCLICK'], "nsclick library not found")
|
||||
if conf.env['NSCLICK']:
|
||||
conf.env.append_value('CXXDEFINES', 'NS3_CLICK')
|
||||
conf.env.append_value('DEFINES', 'NS3_CLICK')
|
||||
conf.env.append_value('CPPPATH', conf.env['CPPPATH_NSCLICK'])
|
||||
else:
|
||||
# Add this module to the list of modules that won't be built
|
||||
@@ -84,7 +92,7 @@ def build(bld):
|
||||
if 'click' in bld.env['MODULES_NOT_BUILT']:
|
||||
return
|
||||
|
||||
module = bld.create_ns3_module('click', ['internet'])
|
||||
module = bld.create_ns3_module('click', ['core', 'network', 'internet'])
|
||||
module.includes = '. CPPPATH_NSCLICK'
|
||||
module.source = [
|
||||
'model/ipv4-click-routing.cc',
|
||||
@@ -98,10 +106,10 @@ def build(bld):
|
||||
]
|
||||
|
||||
if bld.env['NSCLICK'] and bld.env['DL']:
|
||||
module.uselib = 'NSCLICK DL'
|
||||
module_test.uselib = 'NSCLICK DL'
|
||||
module.use = 'NSCLICK DL'
|
||||
module_test.use = 'NSCLICK DL'
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'click'
|
||||
headers.source = [
|
||||
'model/ipv4-click-routing.h',
|
||||
|
||||
@@ -29,7 +29,7 @@ def build(bld):
|
||||
'model/raw-text-config.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'config-store'
|
||||
headers.source = [
|
||||
'model/file-config.h',
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(HAVE___UINT128_T)and !defined(HAVE_UINT128_T)
|
||||
#if defined(HAVE___UINT128_T) && !defined(HAVE_UINT128_T)
|
||||
typedef __uint128_t uint128_t;
|
||||
typedef __int128_t int128_t;
|
||||
#endif
|
||||
|
||||
@@ -3,7 +3,7 @@ import sys
|
||||
|
||||
import Options
|
||||
|
||||
def set_options(opt):
|
||||
def options(opt):
|
||||
opt.add_option('--int64x64-as-double',
|
||||
help=('Whether to use a double floating point'
|
||||
' type for int64x64 values'
|
||||
@@ -15,9 +15,8 @@ def set_options(opt):
|
||||
|
||||
|
||||
def configure(conf):
|
||||
a = conf.check(type_name='uint128_t', define_name='HAVE_UINT128_T')
|
||||
b = conf.check(type_name='__uint128_t', define_name='HAVE___UINT128_T')
|
||||
|
||||
a = conf.check_nonfatal(type_name='uint128_t', define_name='HAVE_UINT128_T')
|
||||
b = conf.check_nonfatal(type_name='__uint128_t', define_name='HAVE___UINT128_T')
|
||||
|
||||
if Options.options.int64x64_as_double:
|
||||
conf.define('INT64X64_USE_DOUBLE', 1)
|
||||
@@ -32,20 +31,20 @@ def configure(conf):
|
||||
conf.env['INT64X64_USE_CAIRO'] = 1
|
||||
highprec = 'cairo 128-bit integer'
|
||||
|
||||
conf.check_message_custom('high precision time', 'implementation', highprec)
|
||||
conf.msg('Checking high precision time implementation', highprec)
|
||||
|
||||
conf.check(header_name='stdint.h', define_name='HAVE_STDINT_H')
|
||||
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.check(header_name='sys/types.h', define_name='HAVE_SYS_TYPES_H')
|
||||
conf.check(header_name='sys/stat.h', define_name='HAVE_SYS_STAT_H')
|
||||
conf.check(header_name='dirent.h', define_name='HAVE_DIRENT_H')
|
||||
conf.check_nonfatal(header_name='stdint.h', define_name='HAVE_STDINT_H')
|
||||
conf.check_nonfatal(header_name='inttypes.h', define_name='HAVE_INTTYPES_H')
|
||||
conf.check_nonfatal(header_name='sys/inttypes.h', define_name='HAVE_SYS_INT_TYPES_H')
|
||||
conf.check_nonfatal(header_name='sys/types.h', define_name='HAVE_SYS_TYPES_H')
|
||||
conf.check_nonfatal(header_name='sys/stat.h', define_name='HAVE_SYS_STAT_H')
|
||||
conf.check_nonfatal(header_name='dirent.h', define_name='HAVE_DIRENT_H')
|
||||
|
||||
if conf.check(header_name='stdlib.h'):
|
||||
if conf.check_nonfatal(header_name='stdlib.h'):
|
||||
conf.define('HAVE_STDLIB_H', 1)
|
||||
conf.define('HAVE_GETENV', 1)
|
||||
|
||||
conf.check(header_name='signal.h', define_name='HAVE_SIGNAL_H')
|
||||
conf.check_nonfatal(header_name='signal.h', define_name='HAVE_SIGNAL_H')
|
||||
|
||||
# Check for POSIX threads
|
||||
test_env = conf.env.copy()
|
||||
@@ -62,10 +61,9 @@ int main ()
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
have_pthread = conf.check(header_name='pthread.h', define_name='HAVE_PTHREAD_H',
|
||||
env=test_env, fragment=fragment,
|
||||
errmsg='Could not find pthread support (build/config.log for details)',
|
||||
mandatory=False)
|
||||
have_pthread = conf.check_nonfatal(header_name='pthread.h', define_name='HAVE_PTHREAD_H',
|
||||
env=test_env, fragment=fragment,
|
||||
errmsg='Could not find pthread support (build/config.log for details)')
|
||||
if have_pthread:
|
||||
# darwin accepts -pthread but prints a warning saying it is ignored
|
||||
if Options.platform != 'darwin' and Options.platform != 'cygwin':
|
||||
@@ -79,12 +77,12 @@ int main ()
|
||||
conf.env['ENABLE_THREADING'],
|
||||
"<pthread.h> include not detected")
|
||||
|
||||
conf.check(header_name='stdint.h', define_name='HAVE_STDINT_H')
|
||||
conf.check(header_name='inttypes.h', define_name='HAVE_INTTYPES_H')
|
||||
conf.check_nonfatal(header_name='stdint.h', define_name='HAVE_STDINT_H')
|
||||
conf.check_nonfatal(header_name='inttypes.h', define_name='HAVE_INTTYPES_H')
|
||||
|
||||
conf.check(header_name='sys/inttypes.h', define_name='HAVE_SYS_INT_TYPES_H')
|
||||
conf.check_nonfatal(header_name='sys/inttypes.h', define_name='HAVE_SYS_INT_TYPES_H')
|
||||
|
||||
if not conf.check(lib='rt', uselib='RT', define_name='HAVE_RT'):
|
||||
if not conf.check_nonfatal(lib='rt', uselib='RT', define_name='HAVE_RT'):
|
||||
conf.report_optional_feature("RealTime", "Real Time Simulator",
|
||||
False, "librt is not available")
|
||||
else:
|
||||
@@ -170,7 +168,7 @@ def build(bld):
|
||||
'test/watchdog-test-suite.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'core'
|
||||
headers.source = [
|
||||
'model/nstime.h',
|
||||
@@ -252,7 +250,7 @@ def build(bld):
|
||||
])
|
||||
|
||||
|
||||
env = bld.env_of_name('default')
|
||||
env = bld.env
|
||||
if env['INT64X64_USE_DOUBLE']:
|
||||
headers.source.extend(['model/int64x64-double.h'])
|
||||
elif env['INT64X64_USE_128']:
|
||||
|
||||
207
src/create-module.py
Executable file
207
src/create-module.py
Executable file
@@ -0,0 +1,207 @@
|
||||
#! /usr/bin/env python
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
import os
|
||||
|
||||
|
||||
WSCRIPT_TEMPLATE = '''# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
# def options(opt):
|
||||
# pass
|
||||
|
||||
# def configure(conf):
|
||||
# conf.check_nonfatal(header_name='stdint.h', define_name='HAVE_STDINT_H')
|
||||
|
||||
def build(bld):
|
||||
module = bld.create_ns3_module(%(MODULE)r, ['core'])
|
||||
module.source = [
|
||||
'model/%(MODULE)s.cc',
|
||||
'helper/%(MODULE)s-helper.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = %(MODULE)r
|
||||
headers.source = [
|
||||
'model/%(MODULE)s.h',
|
||||
'helper/%(MODULE)s-helper.h',
|
||||
]
|
||||
|
||||
if bld.env.ENABLE_EXAMPLES:
|
||||
bld.add_subdirs('examples')
|
||||
|
||||
# bld.ns3_python_bindings()
|
||||
|
||||
'''
|
||||
|
||||
|
||||
|
||||
MODEL_CC_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
|
||||
#include "%(MODULE)s.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/* ... */
|
||||
|
||||
|
||||
}
|
||||
|
||||
'''
|
||||
|
||||
|
||||
|
||||
MODEL_H_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
#ifndef %(INCLUDE_GUARD)s
|
||||
#define %(INCLUDE_GUARD)s
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/* ... */
|
||||
|
||||
}
|
||||
|
||||
#endif /* %(INCLUDE_GUARD)s */
|
||||
|
||||
'''
|
||||
|
||||
|
||||
|
||||
HELPER_CC_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
|
||||
#include "%(MODULE)s-helper.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/* ... */
|
||||
|
||||
|
||||
}
|
||||
|
||||
'''
|
||||
|
||||
|
||||
|
||||
HELPER_H_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
#ifndef %(INCLUDE_GUARD)s
|
||||
#define %(INCLUDE_GUARD)s
|
||||
|
||||
#include "ns3/%(MODULE)s.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/* ... */
|
||||
|
||||
}
|
||||
|
||||
#endif /* %(INCLUDE_GUARD)s */
|
||||
|
||||
'''
|
||||
|
||||
|
||||
EXAMPLES_WSCRIPT_TEMPLATE = '''# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
obj = bld.create_ns3_program('%(MODULE)s-example', [%(MODULE)r])
|
||||
obj.source = '%(MODULE)s-example.cc'
|
||||
|
||||
'''
|
||||
|
||||
EXAMPLE_CC_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
|
||||
#include "ns3/core-module.h"
|
||||
#include "ns3/%(MODULE)s-helper.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
bool verbose = true;
|
||||
|
||||
CommandLine cmd;
|
||||
cmd.AddValue ("verbose", "Tell application to log if true", verbose);
|
||||
|
||||
cmd.Parse (argc,argv);
|
||||
|
||||
/* ... */
|
||||
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
'''
|
||||
|
||||
|
||||
def main(argv):
|
||||
parser = OptionParser(usage=("Usage: %prog [options] modulename\n"
|
||||
"Utility script to create a basic template for a new ns-3 module"))
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
modname = args[0]
|
||||
assert os.path.sep not in modname
|
||||
|
||||
moduledir = os.path.join(os.path.dirname(__file__), modname)
|
||||
|
||||
if os.path.exists(moduledir):
|
||||
print >> sys.stderr, "Module %r already exists" % (modname,)
|
||||
return 2
|
||||
|
||||
os.mkdir(moduledir)
|
||||
wscript = file(os.path.join(moduledir, "wscript"), "wt")
|
||||
wscript.write(WSCRIPT_TEMPLATE % dict(MODULE=modname))
|
||||
wscript.close()
|
||||
|
||||
|
||||
#
|
||||
# model
|
||||
#
|
||||
modeldir = os.path.join(moduledir, "model")
|
||||
os.mkdir(modeldir)
|
||||
|
||||
model_cc = file(os.path.join(moduledir, "model", "%s.cc" % modname), "wt")
|
||||
model_cc.write(MODEL_CC_TEMPLATE % dict(MODULE=modname))
|
||||
model_cc.close()
|
||||
|
||||
model_h = file(os.path.join(moduledir, "model", "%s.h" % modname), "wt")
|
||||
model_h.write(MODEL_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD="__%s_H__" % (modname.upper()),))
|
||||
model_h.close()
|
||||
|
||||
|
||||
|
||||
#
|
||||
# helper
|
||||
#
|
||||
helperdir = os.path.join(moduledir, "helper")
|
||||
os.mkdir(helperdir)
|
||||
|
||||
helper_cc = file(os.path.join(moduledir, "helper", "%s-helper.cc" % modname), "wt")
|
||||
helper_cc.write(HELPER_CC_TEMPLATE % dict(MODULE=modname))
|
||||
helper_cc.close()
|
||||
|
||||
helper_h = file(os.path.join(moduledir, "helper", "%s-helper.h" % modname), "wt")
|
||||
helper_h.write(HELPER_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD="__%s_HELPER_H__" % (modname.upper()),))
|
||||
helper_h.close()
|
||||
|
||||
|
||||
examplesdir = os.path.join(moduledir, "examples")
|
||||
os.mkdir(examplesdir)
|
||||
|
||||
examples_wscript = file(os.path.join(examplesdir, "wscript"), "wt")
|
||||
examples_wscript.write(EXAMPLES_WSCRIPT_TEMPLATE % dict(MODULE=modname))
|
||||
examples_wscript.close()
|
||||
|
||||
example_cc = file(os.path.join(moduledir, "examples", "%s-example.cc" % modname), "wt")
|
||||
example_cc.write(EXAMPLE_CC_TEMPLATE % dict(MODULE=modname))
|
||||
example_cc.close()
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
||||
@@ -5,7 +5,7 @@ def build(bld):
|
||||
obj.source = [
|
||||
'model/csma-star-helper.cc',
|
||||
]
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'csma-layout'
|
||||
headers.source = [
|
||||
'model/csma-star-helper.h',
|
||||
|
||||
@@ -8,7 +8,7 @@ def build(bld):
|
||||
'model/csma-channel.cc',
|
||||
'helper/csma-helper.cc',
|
||||
]
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'csma'
|
||||
headers.source = [
|
||||
'model/backoff.h',
|
||||
|
||||
@@ -16,7 +16,7 @@ def build(bld):
|
||||
'test/dsdv-testcase.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'dsdv'
|
||||
headers.source = [
|
||||
'model/dsdv-rtable.h',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
env = bld.env_of_name('default')
|
||||
env = bld.env
|
||||
if env['ENABLE_EMU']:
|
||||
obj = bld.create_ns3_program('emu-udp-echo', ['emu', 'internet', 'applications'])
|
||||
obj.source = 'emu-udp-echo.cc'
|
||||
|
||||
@@ -4,7 +4,7 @@ import os.path
|
||||
|
||||
def configure(conf):
|
||||
if conf.env['ENABLE_THREADING']:
|
||||
conf.env['ENABLE_EMU'] = conf.check(header_name='netpacket/packet.h',
|
||||
conf.env['ENABLE_EMU'] = conf.check_nonfatal(header_name='netpacket/packet.h',
|
||||
define_name='HAVE_PACKET_H')
|
||||
conf.report_optional_feature("EmuNetDevice", "Emulated Net Device",
|
||||
conf.env['ENABLE_EMU'],
|
||||
@@ -15,7 +15,8 @@ def configure(conf):
|
||||
"needs threading support which is not available")
|
||||
|
||||
if conf.env['ENABLE_EMU']:
|
||||
blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant()))
|
||||
#blddir = conf.bldnode.abspath()
|
||||
blddir = os.path.abspath(os.path.join(conf.bldnode.abspath(), conf.variant))
|
||||
emucreatordir = os.path.abspath(os.path.join(blddir, "src/emu"))
|
||||
conf.env.append_value('NS3_EXECUTABLE_PATH', emucreatordir)
|
||||
else:
|
||||
@@ -35,7 +36,7 @@ def build(bld):
|
||||
'helper/emu-helper.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'emu'
|
||||
headers.source = [
|
||||
'model/emu-net-device.h',
|
||||
|
||||
@@ -25,7 +25,7 @@ def build(bld):
|
||||
'test/li-ion-energy-source-test.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'energy'
|
||||
headers.source = [
|
||||
'model/wifi-radio-energy-model.h',
|
||||
|
||||
@@ -17,7 +17,7 @@ def build(bld):
|
||||
'test/histogram-test-suite.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'flow-monitor'
|
||||
headers.source = ["model/%s" % s for s in [
|
||||
'flow-monitor.h',
|
||||
|
||||
@@ -11,7 +11,7 @@ import Task
|
||||
NSC_RELEASE_NAME = "nsc-0.5.2"
|
||||
|
||||
|
||||
def set_options(opt):
|
||||
def options(opt):
|
||||
opt.add_option('--with-nsc',
|
||||
help=('Use Network Simulation Cradle, given by the indicated path,'
|
||||
' to allow the use of real-world network stacks'),
|
||||
@@ -32,23 +32,23 @@ def configure(conf):
|
||||
# Check for the location of NSC
|
||||
if Options.options.with_nsc:
|
||||
if os.path.isdir(Options.options.with_nsc):
|
||||
conf.check_message("NSC location", '', True, ("%s (given)" % Options.options.with_nsc))
|
||||
conf.msg("NSC location", ("%s (given)" % Options.options.with_nsc))
|
||||
conf.env['WITH_NSC'] = os.path.abspath(Options.options.with_nsc)
|
||||
else:
|
||||
# ns-3-dev uses ../nsc, while ns-3 releases use ../NSC_RELEASE_NAME
|
||||
nsc_dir = os.path.join('..', "nsc")
|
||||
nsc_release_dir = os.path.join('..', NSC_RELEASE_NAME)
|
||||
if os.path.isdir(nsc_dir):
|
||||
conf.check_message("NSC location", '', True, ("%s (guessed)" % nsc_dir))
|
||||
conf.msg("NSC location",("%s (guessed)" % nsc_dir))
|
||||
conf.env['WITH_NSC'] = os.path.abspath(nsc_dir)
|
||||
elif os.path.isdir(nsc_release_dir):
|
||||
conf.check_message("NSC location", '', True, ("%s (guessed)" % nsc_release_dir))
|
||||
conf.msg("NSC location", ("%s (guessed)" % nsc_release_dir))
|
||||
conf.env['WITH_NSC'] = os.path.abspath(nsc_release_dir)
|
||||
del nsc_dir
|
||||
del nsc_release_dir
|
||||
|
||||
if not conf.env['WITH_NSC']:
|
||||
conf.check_message("NSC location", '', False)
|
||||
conf.msg("NSC location", False)
|
||||
conf.report_optional_feature("nsc", "Network Simulation Cradle", False,
|
||||
"NSC not found (see option --with-nsc)")
|
||||
return
|
||||
@@ -61,9 +61,9 @@ def configure(conf):
|
||||
if arch in ('x86_64', 'i686', 'i586', 'i486', 'i386'):
|
||||
conf.env['NSC_ENABLED'] = True
|
||||
conf.env.append_value('CXXDEFINES', 'NETWORK_SIMULATION_CRADLE')
|
||||
conf.check(mandatory=True, lib='dl', define_name='HAVE_DL', uselib='DL')
|
||||
conf.check_nonfatal(mandatory=True, lib='dl', define_name='HAVE_DL', uselib='DL')
|
||||
ok = True
|
||||
conf.check_message('NSC supported architecture', arch, ok)
|
||||
conf.msg('NSC supported architecture ' + arch, ok)
|
||||
|
||||
if not ok:
|
||||
conf.env['NSC_ENABLED'] = False
|
||||
@@ -205,7 +205,7 @@ def build(bld):
|
||||
'test/udp-test.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'internet'
|
||||
headers.source = [
|
||||
'model/udp-header.h',
|
||||
|
||||
@@ -47,7 +47,7 @@ def build(bld):
|
||||
'test/lte-propagation-loss-model-test.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'lte'
|
||||
headers.source = [
|
||||
'model/lte-spectrum-phy.h',
|
||||
|
||||
@@ -53,7 +53,7 @@ def build(bld):
|
||||
'test/flame/regression.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'mesh'
|
||||
headers.source = [
|
||||
'model/mesh-information-element.h',
|
||||
|
||||
@@ -30,7 +30,7 @@ def build(bld):
|
||||
'test/waypoint-mobility-model-test.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'mobility'
|
||||
headers.source = [
|
||||
'model/box.h',
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
import sys
|
||||
import subprocess
|
||||
import Options
|
||||
|
||||
from waflib.Errors import WafError
|
||||
|
||||
def configure(conf):
|
||||
env = conf.env
|
||||
conf.find_program('mpic++', var='MPI')
|
||||
try:
|
||||
conf.find_program('mpic++', var='MPI')
|
||||
except WafError:
|
||||
return
|
||||
if Options.options.enable_mpi and conf.env['MPI']:
|
||||
p = subprocess.Popen([conf.env['MPI'], '-showme:compile'], stdout=subprocess.PIPE)
|
||||
flags = p.stdout.read().rstrip().split()
|
||||
@@ -29,7 +32,7 @@ def configure(conf):
|
||||
|
||||
|
||||
def build(bld):
|
||||
env = bld.env_of_name('default')
|
||||
env = bld.env
|
||||
sim = bld.create_ns3_module('mpi', ['core', 'network'])
|
||||
sim.source = [
|
||||
'model/distributed-simulator-impl.cc',
|
||||
@@ -37,7 +40,7 @@ def build(bld):
|
||||
'model/mpi-receiver.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'mpi'
|
||||
headers.source = [
|
||||
'model/distributed-simulator-impl.h',
|
||||
|
||||
@@ -8,7 +8,7 @@ def build (bld) :
|
||||
'helper/animation-interface-helper.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen ('ns3header')
|
||||
headers = bld.new_task_gen (features=['ns3header'])
|
||||
headers.module = 'netanim'
|
||||
headers.source = [
|
||||
'model/animation-interface.h',
|
||||
|
||||
@@ -67,7 +67,7 @@ def build(bld):
|
||||
'test/sequence-number-test-suite.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'network'
|
||||
headers.source = [
|
||||
'model/address.h',
|
||||
|
||||
@@ -8,7 +8,7 @@ def build(bld):
|
||||
'helper/ipv4-nix-vector-helper.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'nix-vector-routing'
|
||||
headers.source = [
|
||||
'model/ipv4-nix-vector-routing.h',
|
||||
|
||||
@@ -20,7 +20,7 @@ def build(bld):
|
||||
'test/tc-regression-test.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'olsr'
|
||||
headers.source = [
|
||||
'model/olsr-routing-protocol.h',
|
||||
|
||||
@@ -2,27 +2,24 @@
|
||||
|
||||
import os
|
||||
import Options
|
||||
from waflib.Errors import WafError
|
||||
|
||||
def set_options(opt):
|
||||
def options(opt):
|
||||
opt.add_option('--with-openflow',
|
||||
help=('Path to OFSID source for NS-3 OpenFlow Integration support'),
|
||||
default='', dest='with_openflow')
|
||||
opt.tool_options('boost')
|
||||
opt.tool_options('boost', tooldir=["waf-tools"])
|
||||
|
||||
def configure(conf):
|
||||
conf.check_tool('boost')
|
||||
conf.env['BOOST'] = conf.check_boost(lib = 'signals filesystem',
|
||||
kind = 'STATIC_BOTH',
|
||||
score_version = (-1000, 1000),
|
||||
tag_minscore = 1000)
|
||||
if not conf.env['BOOST']:
|
||||
conf.env['BOOST'] = conf.check_boost(lib = 'signals filesystem',
|
||||
kind = 'STATIC_BOTH',
|
||||
score_version = (-1000, 1000),
|
||||
tag_minscore = 1000,
|
||||
libpath="/usr/lib64")
|
||||
try:
|
||||
conf.check_tool('boost')
|
||||
conf.check_boost(lib='signals filesystem')
|
||||
if not conf.env.LIB_BOOST:
|
||||
conf.check_boost(lib='signals filesystem', libpath="/usr/lib64")
|
||||
except WafError:
|
||||
conf.env['LIB_BOOST'] = []
|
||||
|
||||
if not conf.env['BOOST']:
|
||||
if not conf.env.LIB_BOOST:
|
||||
conf.report_optional_feature("openflow", "NS-3 OpenFlow Integration", False,
|
||||
"Required boost libraries not found")
|
||||
|
||||
@@ -34,16 +31,16 @@ def configure(conf):
|
||||
|
||||
if Options.options.with_openflow:
|
||||
if os.path.isdir(Options.options.with_openflow):
|
||||
conf.check_message("OpenFlow location", '', True, ("%s (given)" % Options.options.with_openflow))
|
||||
conf.msg("Checking for OpenFlow location", ("%s (given)" % Options.options.with_openflow))
|
||||
conf.env['WITH_OPENFLOW'] = os.path.abspath(Options.options.with_openflow)
|
||||
else:
|
||||
openflow_dir = os.path.join('..','openflow')
|
||||
if os.path.isdir(openflow_dir):
|
||||
conf.check_message("OpenFlow location", '', True, ("%s (guessed)" % openflow_dir))
|
||||
conf.msg("Checking for OpenFlow location", ("%s (guessed)" % openflow_dir))
|
||||
conf.env['WITH_OPENFLOW'] = os.path.abspath(openflow_dir)
|
||||
del openflow_dir
|
||||
if not conf.env['WITH_OPENFLOW']:
|
||||
conf.check_message("OpenFlow location", '', False)
|
||||
conf.msg("Checking for OpenFlow location", False)
|
||||
conf.report_optional_feature("openflow", "NS-3 OpenFlow Integration", False,
|
||||
"OpenFlow not enabled (see option --with-openflow)")
|
||||
# Add this module to the list of modules that won't be built
|
||||
@@ -104,23 +101,19 @@ int main()
|
||||
|
||||
conf.env.append_value('NS3_MODULE_PATH',os.path.abspath(os.path.join(conf.env['WITH_OPENFLOW'],'build','default')))
|
||||
|
||||
conf.env['CPPPATH_OPENFLOW'] = [
|
||||
conf.env['INCLUDES_OPENFLOW'] = [
|
||||
os.path.abspath(os.path.join(conf.env['WITH_OPENFLOW'],'include'))]
|
||||
conf.env['LIBPATH_OPENFLOW'] = [
|
||||
os.path.abspath(os.path.join(conf.env['WITH_OPENFLOW'],'build','default')),
|
||||
os.path.abspath(os.path.join(conf.env['WITH_OPENFLOW'],'lib'))]
|
||||
|
||||
conf.env['OPENFLOW'] = conf.check(fragment=test_code, lib='openflow',
|
||||
libpath=conf.env['LIBPATH_OPENFLOW'],
|
||||
uselib='OPENFLOW DL XML2')
|
||||
|
||||
conf.env['OPENFLOW'] = conf.check_nonfatal(fragment=test_code, lib='openflow',
|
||||
libpath=conf.env['LIBPATH_OPENFLOW'],
|
||||
use='OPENFLOW DL XML2')
|
||||
conf.report_optional_feature("openflow", "NS-3 OpenFlow Integration",
|
||||
conf.env['OPENFLOW'], "openflow library not found")
|
||||
if conf.env['OPENFLOW']:
|
||||
conf.env['ENABLE_OPENFLOW'] = True
|
||||
conf.env.append_value('CXXDEFINES', 'NS3_OPENFLOW')
|
||||
conf.env.append_value('CPPPATH', conf.env['CPPPATH_OPENFLOW'])
|
||||
conf.env.append_value('LIBPATH', conf.env['LIBPATH_OPENFLOW'])
|
||||
else:
|
||||
# Add this module to the list of modules that won't be built
|
||||
# if they are enabled.
|
||||
@@ -146,7 +139,7 @@ def build(bld):
|
||||
obj.uselib = 'OPENFLOW DL XML2'
|
||||
obj_test.uselib = 'OPENFLOW DL XML2'
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'openflow'
|
||||
headers.source = [
|
||||
]
|
||||
@@ -155,6 +148,10 @@ def build(bld):
|
||||
obj.source.append('model/openflow-interface.cc')
|
||||
obj.source.append('model/openflow-switch-net-device.cc')
|
||||
obj.source.append('helper/openflow-switch-helper.cc')
|
||||
|
||||
obj.env.append_value('DEFINES', 'NS3_OPENFLOW')
|
||||
obj.use = "OPENFLOW"
|
||||
|
||||
obj_test.source.append('test/openflow-switch-test-suite.cc')
|
||||
headers.source.append('model/openflow-interface.h')
|
||||
headers.source.append('model/openflow-switch-net-device.h')
|
||||
|
||||
@@ -9,7 +9,7 @@ def build(bld):
|
||||
'model/point-to-point-star.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'point-to-point-layout'
|
||||
headers.source = [
|
||||
'model/point-to-point-dumbbell.h',
|
||||
|
||||
@@ -16,7 +16,7 @@ def build(bld):
|
||||
'test/point-to-point-test.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'point-to-point'
|
||||
headers.source = [
|
||||
'model/point-to-point-net-device.h',
|
||||
|
||||
@@ -15,7 +15,7 @@ def build(bld):
|
||||
'test/propagation-loss-model-test-suite.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'propagation'
|
||||
headers.source = [
|
||||
'model/propagation-delay-model.h',
|
||||
|
||||
@@ -39,7 +39,7 @@ def build(bld):
|
||||
'test/spectrum-ideal-phy-test.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'spectrum'
|
||||
headers.source = [
|
||||
'model/spectrum-model.h',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def configure(conf):
|
||||
conf.env['SQLITE_STATS'] = conf.check(lib='sqlite3', define_name='SQLITE3', uselib='SQLITE3')
|
||||
conf.env['SQLITE_STATS'] = conf.check_nonfatal(lib='sqlite3', define_name='SQLITE3', uselib='SQLITE3')
|
||||
conf.report_optional_feature("SqliteDataOutput", "SQlite stats data output",
|
||||
conf.env['SQLITE_STATS'],
|
||||
"library 'sqlite3' not found")
|
||||
@@ -23,7 +23,7 @@ def build(bld):
|
||||
'test/basic-data-calculators-test-suite.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'stats'
|
||||
headers.source = [
|
||||
'model/data-calculator.h',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
env = bld.env_of_name('default')
|
||||
env = bld.env
|
||||
if env['ENABLE_TAP']:
|
||||
obj = bld.create_ns3_program('tap-csma', ['csma', 'tap-bridge', 'internet', 'wifi'])
|
||||
obj.source = 'tap-csma.cc'
|
||||
|
||||
@@ -4,7 +4,7 @@ import os.path
|
||||
|
||||
def configure(conf):
|
||||
if conf.env['ENABLE_THREADING']:
|
||||
conf.env['ENABLE_TAP'] = conf.check(header_name='linux/if_tun.h',
|
||||
conf.env['ENABLE_TAP'] = conf.check_nonfatal(header_name='linux/if_tun.h',
|
||||
define_name='HAVE_IF_TUN_H')
|
||||
conf.report_optional_feature("TapBridge", "Tap Bridge",
|
||||
conf.env['ENABLE_TAP'],
|
||||
@@ -15,7 +15,7 @@ def configure(conf):
|
||||
"needs threading support which is not available")
|
||||
|
||||
if conf.env['ENABLE_TAP']:
|
||||
blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant()))
|
||||
blddir = os.path.abspath(os.path.join(conf.bldnode.abspath(), conf.variant))
|
||||
tapcreatordir = os.path.abspath(os.path.join(blddir, "src/tap-bridge"))
|
||||
conf.env.append_value('NS3_EXECUTABLE_PATH', tapcreatordir)
|
||||
else:
|
||||
@@ -34,7 +34,7 @@ def build(bld):
|
||||
'model/tap-encode-decode.cc',
|
||||
'helper/tap-bridge-helper.cc',
|
||||
]
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'tap-bridge'
|
||||
headers.source = [
|
||||
'model/tap-bridge.h',
|
||||
|
||||
@@ -27,7 +27,7 @@ def build(bld):
|
||||
]
|
||||
|
||||
# Make headers be installed for this module.
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'template'
|
||||
|
||||
# Set the C++ header files for this module.
|
||||
|
||||
@@ -16,7 +16,7 @@ def build(bld):
|
||||
return
|
||||
|
||||
ns3tcp = bld.create_ns3_module('ns3tcp', ['internet', 'point-to-point', 'csma', 'applications'])
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'ns3tcp'
|
||||
headers.source = [
|
||||
'ns3tcp.h',
|
||||
|
||||
@@ -16,7 +16,7 @@ def build(bld):
|
||||
return
|
||||
|
||||
ns3wifi = bld.create_ns3_module('ns3wifi', ['internet', 'mobility', 'propagation', 'wifi', 'applications'])
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'ns3wifi'
|
||||
headers.source = [
|
||||
'ns3wifi.h',
|
||||
|
||||
@@ -20,7 +20,7 @@ def build(bld):
|
||||
return
|
||||
|
||||
test = bld.create_ns3_module('test', ['internet', 'mobility', 'applications', 'csma', 'bridge', 'config-store', 'tools', 'point-to-point', 'csma-layout', 'flow-monitor'])
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'test'
|
||||
|
||||
test_test = bld.create_ns3_module_test_library('test')
|
||||
|
||||
@@ -14,7 +14,7 @@ def build(bld):
|
||||
'test/event-garbage-collector-test-suite.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'tools'
|
||||
headers.source = [
|
||||
'model/average.h',
|
||||
|
||||
@@ -15,7 +15,7 @@ def build(bld):
|
||||
'test/rocketfuel-topology-reader-test-suite.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'topology-read'
|
||||
headers.source = [
|
||||
'model/topology-reader.h',
|
||||
|
||||
@@ -32,7 +32,7 @@ def build(bld):
|
||||
'test/uan-test.cc',
|
||||
'test/uan-energy-model-test.cc',
|
||||
]
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'uan'
|
||||
headers.source = [
|
||||
'model/uan-channel.h',
|
||||
|
||||
@@ -6,7 +6,7 @@ def build(bld):
|
||||
module.source = [
|
||||
'model/virtual-net-device.cc',
|
||||
]
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'virtual-net-device'
|
||||
headers.source = [
|
||||
'model/virtual-net-device.h',
|
||||
|
||||
@@ -13,7 +13,7 @@ def build(bld):
|
||||
if 'visualizer' in bld.env['MODULES_NOT_BUILT']:
|
||||
return
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'visualizer'
|
||||
headers.source = [
|
||||
]
|
||||
@@ -36,8 +36,8 @@ def build(bld):
|
||||
return
|
||||
|
||||
module.features.append('pyembed')
|
||||
module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS'])
|
||||
module.includes = '.'
|
||||
#module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS'])
|
||||
#module.includes = '.'
|
||||
|
||||
module.source.extend([
|
||||
'model/pyviz.cc',
|
||||
|
||||
@@ -75,7 +75,7 @@ def build(bld):
|
||||
'test/wifi-test.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'wifi'
|
||||
headers.source = [
|
||||
'model/wifi-information-element.h',
|
||||
|
||||
@@ -63,7 +63,7 @@ def build(bld):
|
||||
'test/wimax-fragmentation-test.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
headers = bld.new_task_gen(features=['ns3header'])
|
||||
headers.module = 'wimax'
|
||||
headers.source = [
|
||||
'model/wimax-channel.h',
|
||||
|
||||
529
src/wscript
529
src/wscript
@@ -6,15 +6,13 @@ import shutil
|
||||
import types
|
||||
import warnings
|
||||
|
||||
from waflib.Errors import WafError
|
||||
|
||||
import TaskGen
|
||||
import Task
|
||||
import Options
|
||||
import Build
|
||||
import Utils
|
||||
import Constants
|
||||
|
||||
import ccroot
|
||||
ccroot.USE_TOP_LEVEL = True
|
||||
|
||||
import wutils
|
||||
|
||||
@@ -23,53 +21,21 @@ try:
|
||||
except NameError:
|
||||
from sets import Set as set # Python 2.3 fallback
|
||||
|
||||
all_modules = [
|
||||
'core',
|
||||
'network',
|
||||
'config-store',
|
||||
'internet',
|
||||
'propagation',
|
||||
'point-to-point',
|
||||
'csma',
|
||||
'emu',
|
||||
'bridge',
|
||||
'tap-bridge',
|
||||
'virtual-net-device',
|
||||
'applications',
|
||||
'nix-vector-routing',
|
||||
'olsr',
|
||||
'aodv',
|
||||
'dsdv',
|
||||
'click',
|
||||
'openflow',
|
||||
'mobility',
|
||||
'wifi',
|
||||
'netanim',
|
||||
'stats',
|
||||
'uan',
|
||||
'spectrum',
|
||||
'mesh',
|
||||
'test',
|
||||
'test/ns3tcp',
|
||||
'test/ns3wifi',
|
||||
'flow-monitor',
|
||||
'wimax',
|
||||
'lte',
|
||||
'mpi',
|
||||
'topology-read',
|
||||
'energy',
|
||||
'tools',
|
||||
'visualizer',
|
||||
'point-to-point-layout',
|
||||
'csma-layout',
|
||||
'template',
|
||||
]
|
||||
|
||||
def set_options(opt):
|
||||
opt.sub_options('core')
|
||||
opt.sub_options('click')
|
||||
opt.sub_options('openflow')
|
||||
all_modules = []
|
||||
for dirname in os.listdir('src'):
|
||||
if dirname.startswith('.') or dir == 'CVS':
|
||||
continue
|
||||
path = os.path.join('src', dirname)
|
||||
if not os.path.isdir(path):
|
||||
continue
|
||||
if os.path.exists(os.path.join(path, 'wscript')):
|
||||
all_modules.append(dirname)
|
||||
all_modules.sort()
|
||||
|
||||
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--enable-rpath',
|
||||
help=("Link programs with rpath"
|
||||
" (normally not needed, see "
|
||||
@@ -81,20 +47,15 @@ def set_options(opt):
|
||||
help=("Build only these modules (and dependencies)"),
|
||||
dest='enable_modules')
|
||||
|
||||
def configure(conf):
|
||||
conf.sub_config('core')
|
||||
conf.sub_config('emu')
|
||||
conf.sub_config('tap-bridge')
|
||||
conf.sub_config('config-store')
|
||||
conf.sub_config('internet')
|
||||
conf.sub_config('netanim')
|
||||
conf.sub_config('test')
|
||||
conf.sub_config('click')
|
||||
conf.sub_config('openflow')
|
||||
conf.sub_config('stats')
|
||||
conf.sub_config('visualizer')
|
||||
for module in all_modules:
|
||||
opt.sub_options(module, mandatory=False)
|
||||
|
||||
blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant()))
|
||||
|
||||
def configure(conf):
|
||||
for module in all_modules:
|
||||
conf.sub_config(module, mandatory=False)
|
||||
|
||||
blddir = os.path.abspath(os.path.join(conf.bldnode.abspath(), conf.variant))
|
||||
conf.env.append_value('NS3_MODULE_PATH', blddir)
|
||||
if Options.options.enable_rpath:
|
||||
conf.env.append_value('RPATH', '-Wl,-rpath=%s' % (os.path.join(blddir),))
|
||||
@@ -103,177 +64,91 @@ def configure(conf):
|
||||
conf.env['NS3_MODULES'] = ['ns3-' + module.split('/')[-1] for module in all_modules]
|
||||
|
||||
|
||||
class ns3module_taskgen(TaskGen.task_gen):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ns3module_taskgen, self).__init__(*args, **kwargs)
|
||||
self.libs = []
|
||||
|
||||
def apply(self):
|
||||
static_enabled = False
|
||||
shared_enabled = True
|
||||
bld = self.bld
|
||||
if bld.env['ENABLE_STATIC_NS3']:
|
||||
static_enabled = True
|
||||
shared_enabled = False
|
||||
if bld.env['ENABLE_SHARED_AND_STATIC_NS3']:
|
||||
static_enabled = True
|
||||
shared_enabled = True
|
||||
|
||||
assert self.name.startswith("ns3-")
|
||||
name = self.name.split("ns3-")[1]
|
||||
|
||||
if static_enabled:
|
||||
static = self._create_ns3_module(self.bld, name, self.dependencies, True)
|
||||
self.libs.append(static)
|
||||
else:
|
||||
static = None
|
||||
|
||||
if shared_enabled:
|
||||
shared = self._create_ns3_module(self.bld, name, self.dependencies, False)
|
||||
self.libs.append(shared)
|
||||
else:
|
||||
shared = None
|
||||
|
||||
if static is not None and shared is None:
|
||||
static.name = self.name + "--lib"
|
||||
static.uselib_local = ['ns3-%s--lib' % (dep,) for dep in self.dependencies]
|
||||
|
||||
elif shared is not None and static is None:
|
||||
shared.name = self.name + "--lib"
|
||||
shared.uselib_local = ['ns3-%s--lib' % (dep,) for dep in self.dependencies]
|
||||
else:
|
||||
shared.name = self.name + "--lib"
|
||||
shared.uselib_local = ['ns3-%s--lib' % (dep,) for dep in self.dependencies]
|
||||
static.name = self.name + "--static"
|
||||
static.uselib_local = ['ns3-%s--static' % (dep,) for dep in self.dependencies]
|
||||
|
||||
if not self.test:
|
||||
pcfile = bld.new_task_gen('ns3pcfile')
|
||||
pcfile.module = self
|
||||
|
||||
def _create_ns3_module(self, bld, name, dependencies, static):
|
||||
|
||||
# FIXME: env modifications are overwritten by parent caller
|
||||
|
||||
# Create a separate library for this module.
|
||||
if static:
|
||||
module = bld.new_task_gen('cxx', 'cstaticlib')
|
||||
else:
|
||||
module = bld.new_task_gen('cxx', 'cshlib')
|
||||
|
||||
module.source = self.source
|
||||
module.env = self.env.copy()
|
||||
features = list(self.features)
|
||||
features.remove("ns3module")
|
||||
module.features.extend(features)
|
||||
module.path = self.path
|
||||
module.uselib = self.uselib
|
||||
module.target = 'ns3-' + name
|
||||
if hasattr(self, 'includes'):
|
||||
module.includes = self.includes
|
||||
if hasattr(self, 'defines'):
|
||||
module.defines = self.defines
|
||||
else:
|
||||
module.defines = []
|
||||
if hasattr(self, 'add_objects'):
|
||||
module.add_objects = self.add_objects
|
||||
else:
|
||||
module.add_objects = []
|
||||
if hasattr(self, "is_ns3_module"):
|
||||
module.is_ns3_module = self.is_ns3_module
|
||||
if hasattr(self, 'add_objects'):
|
||||
module.add_objects = self.add_objects
|
||||
|
||||
linkflags = []
|
||||
cxxflags = []
|
||||
ccflags = []
|
||||
if not static:
|
||||
cxxflags = module.env['shlib_CXXFLAGS']
|
||||
ccflags = module.env['shlib_CXXFLAGS']
|
||||
# Turn on the link flags for shared libraries if we have the
|
||||
# proper compiler and platform.
|
||||
if module.env['CXX_NAME'] in ['gcc', 'icc'] and module.env['WL_SONAME_SUPPORTED']:
|
||||
# Get the module library name without any relative paths
|
||||
# at its beginning because all of the libraries will end
|
||||
# up in the same directory.
|
||||
module_library_name = os.path.basename(ccroot.get_target_name(module))
|
||||
linkflags = '-Wl,--soname=%s' % module_library_name
|
||||
elif module.env['CXX_NAME'] in ['gcc', 'icc'] and \
|
||||
os.uname()[4] == 'x86_64' and \
|
||||
sys.platform != 'darwin' 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)
|
||||
cxxflags = ['-mcmodel=large']
|
||||
ccflags = ['-mcmodel=large']
|
||||
cxxdefines = ["NS3_MODULE_COMPILATION"]
|
||||
ccdefines = ["NS3_MODULE_COMPILATION"]
|
||||
|
||||
module.env.append_value('CXXFLAGS', cxxflags)
|
||||
module.env.append_value('CCFLAGS', ccflags)
|
||||
module.env.append_value('LINKFLAGS', linkflags)
|
||||
module.env.append_value('CXXDEFINES', cxxdefines)
|
||||
module.env.append_value('CCDEFINES', ccdefines)
|
||||
|
||||
if len(module.source) > 0 and hasattr(self, 'ns3_dir_location'):
|
||||
uselib_cpppath = []
|
||||
for lib in module.uselib.split():
|
||||
if 'CPPPATH_%s' % lib in module.env:
|
||||
uselib_cpppath.extend(module.env['CPPPATH_%s' % lib])
|
||||
objects = []
|
||||
for src in module.source[0:-1]:
|
||||
full_src = os.path.join(self.ns3_dir_location, src)
|
||||
path = os.path.dirname(full_src)
|
||||
target = '%s_object' % src
|
||||
# XXX: calculate the features correctly here.
|
||||
obj = bld (source=[full_src], target=target, features='cxx cc',
|
||||
defines=['NS_TEST_SOURCEDIR="%s"' % path],
|
||||
includes=' '.join(uselib_cpppath),
|
||||
env = module.env)
|
||||
objects.append(target)
|
||||
last = module.source[-1]
|
||||
full_src = os.path.join(self.ns3_dir_location, last)
|
||||
path = os.path.dirname(full_src)
|
||||
module.defines.append('NS_TEST_SOURCEDIR="%s"' % path)
|
||||
module.source = [last]
|
||||
module.add_objects.extend(objects)
|
||||
|
||||
|
||||
module.is_static = static
|
||||
module.vnum = wutils.VNUM
|
||||
# Add the proper path to the module's name.
|
||||
module.target = '%s/ns3-%s' % (bld.srcnode.relpath_gen(self.path), name)
|
||||
# Set the libraries this module depends on.
|
||||
module.module_deps = list(dependencies)
|
||||
|
||||
module.install_path = "${LIBDIR}"
|
||||
|
||||
return module
|
||||
# we need the 'ns3module' waf "feature" to be created because code
|
||||
# elsewhere looks for it to find the ns3 module objects.
|
||||
@TaskGen.feature('ns3module')
|
||||
def _add_test_code(module):
|
||||
pass
|
||||
|
||||
|
||||
def create_ns3_module(bld, name, dependencies=(), test=False):
|
||||
module = bld.new_task_gen('ns3module')
|
||||
module.bld = bld
|
||||
static = bool(bld.env.ENABLE_STATIC_NS3)
|
||||
# Create a separate library for this module.
|
||||
if static:
|
||||
module = bld.new_task_gen(features=['cxx', 'cxxstlib', 'ns3module'])
|
||||
else:
|
||||
module = bld.new_task_gen(features=['cxx', 'cxxshlib', 'ns3module'])
|
||||
module.target = '%s/ns3-%s' % (bld.srcnode.relpath_gen(module.path), name)
|
||||
linkflags = []
|
||||
cxxflags = []
|
||||
ccflags = []
|
||||
if not static:
|
||||
cxxflags = module.env['shlib_CXXFLAGS']
|
||||
ccflags = module.env['shlib_CXXFLAGS']
|
||||
# Turn on the link flags for shared libraries if we have the
|
||||
# proper compiler and platform.
|
||||
if module.env['CXX_NAME'] in ['gcc', 'icc'] and module.env['WL_SONAME_SUPPORTED']:
|
||||
# Get the module library name without any relative paths
|
||||
# at its beginning because all of the libraries will end
|
||||
# up in the same directory.
|
||||
module_library_name = module.env.cshlib_PATTERN % (os.path.basename(module.target),)
|
||||
linkflags = '-Wl,--soname=' + module_library_name
|
||||
elif module.env['CXX_NAME'] in ['gcc', 'icc'] and \
|
||||
os.uname()[4] == 'x86_64' and \
|
||||
sys.platform != 'darwin' 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)
|
||||
cxxflags = ['-mcmodel=large']
|
||||
ccflags = ['-mcmodel=large']
|
||||
cxxdefines = ["NS3_MODULE_COMPILATION"]
|
||||
ccdefines = ["NS3_MODULE_COMPILATION"]
|
||||
|
||||
module.env.append_value('CXXFLAGS', cxxflags)
|
||||
module.env.append_value('CCFLAGS', ccflags)
|
||||
module.env.append_value('LINKFLAGS', linkflags)
|
||||
module.env.append_value('CXXDEFINES', cxxdefines)
|
||||
module.env.append_value('CCDEFINES', ccdefines)
|
||||
|
||||
module.is_static = static
|
||||
module.vnum = wutils.VNUM
|
||||
# Add the proper path to the module's name.
|
||||
# Set the libraries this module depends on.
|
||||
module.module_deps = list(dependencies)
|
||||
|
||||
module.install_path = "${LIBDIR}"
|
||||
|
||||
module.name = "ns3-" + name
|
||||
module.dependencies = dependencies
|
||||
# Initially create an empty value for this because the pcfile
|
||||
# writing task assumes every module has a uselib attribute.
|
||||
module.uselib = ''
|
||||
module.uselib_local = ['ns3-' + dep for dep in dependencies]
|
||||
module.module_deps = list(dependencies)
|
||||
module.use = ['ns3-' + dep for dep in dependencies]
|
||||
module.test = test
|
||||
module.is_ns3_module = True
|
||||
module.ns3_dir_location = bld.path.relpath_gen(bld.srcnode)
|
||||
|
||||
module.env.append_value("INCLUDES", '#')
|
||||
|
||||
return module
|
||||
|
||||
@TaskGen.feature("ns3testlib")
|
||||
@TaskGen.before_method("apply_incpaths")
|
||||
def apply_incpaths_ns3testlib(self):
|
||||
if not self.source:
|
||||
return
|
||||
testdir = self.source[-1].parent.relpath_gen(self.bld.srcnode)
|
||||
self.env.append_value("DEFINES", 'NS_TEST_SOURCEDIR="%s"' % (testdir,))
|
||||
|
||||
|
||||
def create_ns3_module_test_library(bld, name):
|
||||
# Create an ns3 module for the test library that depends only on
|
||||
# the module being tested.
|
||||
library_name = name + "-test"
|
||||
library = bld.create_ns3_module(library_name, [name], test = True)
|
||||
library = bld.create_ns3_module(library_name, [name], test=True)
|
||||
library.features.append("ns3testlib")
|
||||
|
||||
# Modify attributes for the test library that are different from a
|
||||
# normal module.
|
||||
@@ -282,7 +157,7 @@ def create_ns3_module_test_library(bld, name):
|
||||
library.module_name = 'ns3-' + name
|
||||
|
||||
# Add this module and test library to the list.
|
||||
bld.env.append_value('NS3_MODULES_WITH_TEST_LIBRARIES', (library.module_name, library.name))
|
||||
bld.env.append_value('NS3_MODULES_WITH_TEST_LIBRARIES', [(library.module_name, library.name)])
|
||||
|
||||
# Set the include path from the build directory to modules.
|
||||
relative_path_from_build_to_here = bld.path.relpath_gen(bld.bldnode)
|
||||
@@ -299,6 +174,9 @@ def create_obj(bld, *args):
|
||||
|
||||
|
||||
def ns3_python_bindings(bld):
|
||||
if Options.options.apiscan:
|
||||
return
|
||||
|
||||
# this method is called from a module wscript, so remember bld.path is not bindings/python!
|
||||
module_abs_src_path = bld.path.abspath()
|
||||
module = os.path.basename(module_abs_src_path)
|
||||
@@ -367,40 +245,40 @@ def ns3_python_bindings(bld):
|
||||
if was_enabled:
|
||||
features.append(name)
|
||||
|
||||
bindgen = bld.new_task_gen('command', source=source, target=target, command=argv)
|
||||
bindgen = bld.new_task_gen(features=['command'], source=source, target=target, command=argv)
|
||||
bindgen.env['FEATURES'] = ','.join(features)
|
||||
bindgen.dep_vars = ['FEATURES', "GCC_RTTI_ABI_COMPLETE"]
|
||||
bindgen.before = 'cxx'
|
||||
bindgen.after = 'gen_ns3_module_header_task'
|
||||
bindgen.after = 'gen_ns3_module_header'
|
||||
bindgen.name = "pybindgen(ns3 module %s)" % module
|
||||
|
||||
# generate the extension module
|
||||
pymod = bld.new_task_gen(features='cxx cshlib pyext')
|
||||
pymod = bld.new_task_gen(features='cxx cxxshlib pyext')
|
||||
pymod.source = ['bindings/ns3module.cc']
|
||||
pymod.target = '%s/%s' % (module_target_dir, extension_name)
|
||||
pymod.name = 'ns3module_%s' % module
|
||||
pymod.uselib_local = ["%s--lib" % mod for mod in pymod.env['NS3_ENABLED_MODULES']] # Should be '"ns3-"+module', but see bug 1117
|
||||
pymod.use = ["%s" % mod for mod in pymod.env['NS3_ENABLED_MODULES']] # Should be '"ns3-"+module', but see bug 1117
|
||||
if pymod.env['ENABLE_STATIC_NS3']:
|
||||
if sys.platform == 'darwin':
|
||||
pymod.env.append_value('LINKFLAGS', '-Wl,-all_load')
|
||||
for mod in pymod.uselib_local:
|
||||
mod = mod.split("--lib")[0]
|
||||
for mod in pymod.usel:
|
||||
#mod = mod.split("--lib")[0]
|
||||
pymod.env.append_value('LINKFLAGS', '-l' + mod)
|
||||
else:
|
||||
pymod.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic')
|
||||
for mod in pymod.uselib_local:
|
||||
mod = mod.split("--lib")[0]
|
||||
for mod in pymod.use:
|
||||
#mod = mod.split("--lib")[0]
|
||||
pymod.env.append_value('LINKFLAGS', '-l' + mod)
|
||||
pymod.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive')
|
||||
defines = list(pymod.env['CXXDEFINES'])
|
||||
defines = list(pymod.env['DEFINES'])
|
||||
defines.extend(['NS_DEPRECATED=', 'NS3_DEPRECATED_H'])
|
||||
if Options.platform == 'win32':
|
||||
try:
|
||||
defines.remove('_DEBUG') # causes undefined symbols on win32
|
||||
except ValueError:
|
||||
pass
|
||||
pymod.env['CXXDEFINES'] = defines
|
||||
pymod.includes = 'bindings'
|
||||
pymod.env['DEFINES'] = defines
|
||||
pymod.includes = '# bindings'
|
||||
pymod.install_path = '${PYTHONDIR}/ns'
|
||||
return pymod
|
||||
|
||||
@@ -427,7 +305,7 @@ def build(bld):
|
||||
bld.add_subdirs(list(all_modules))
|
||||
|
||||
for module in all_modules:
|
||||
modheader = bld.new_task_gen('ns3moduleheader')
|
||||
modheader = bld.new_task_gen(features=['ns3moduleheader'])
|
||||
modheader.module = module.split('/')[-1]
|
||||
|
||||
class ns3pcfile_task(Task.Task):
|
||||
@@ -480,7 +358,7 @@ class ns3pcfile_task(Task.Task):
|
||||
includes = self.env['CPPPATH_%s' % dep]
|
||||
return [self.env['CPPPATH_ST'] % include for include in includes]
|
||||
|
||||
def _generate_pcfile(self, name, use, uselib_local, env, outfilename):
|
||||
def _generate_pcfile(self, name, uselib, use, env, outfilename):
|
||||
outfile = open(outfilename, 'w')
|
||||
prefix = env.PREFIX
|
||||
includedir = env.INCLUDEDIR
|
||||
@@ -488,7 +366,7 @@ class ns3pcfile_task(Task.Task):
|
||||
libs = self._self_libs(self.env, name, '${libdir}')
|
||||
for dep in use:
|
||||
libs = libs + self._lib(self.env, dep)
|
||||
for dep in uselib_local:
|
||||
for dep in uselib:
|
||||
libs = libs + [self.env['LIB_ST'] % dep]
|
||||
cflags = [self.env['CPPPATH_ST'] % '${includedir}']
|
||||
for dep in use:
|
||||
@@ -511,7 +389,7 @@ Cflags: %s
|
||||
def run(self):
|
||||
output_filename = self.outputs[0].bldpath(self.env)
|
||||
self._generate_pcfile(self.module.name, self.module.uselib,
|
||||
self.module.uselib_local,
|
||||
self.module.use,
|
||||
self.env, output_filename)
|
||||
|
||||
class ns3pcfile_taskgen(TaskGen.task_gen):
|
||||
@@ -527,41 +405,33 @@ class ns3pcfile_taskgen(TaskGen.task_gen):
|
||||
task.module = self.module
|
||||
|
||||
|
||||
class ns3header_taskgen(TaskGen.task_gen):
|
||||
"""A set of NS-3 header files"""
|
||||
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
|
||||
self.mode = 'install'
|
||||
|
||||
def apply(self):
|
||||
for filename in set(self.to_list(self.source)):
|
||||
src_node = self.path.find_resource(filename)
|
||||
if self.module is None:
|
||||
raise Utils.WafError("'module' missing on ns3headers object %s" % self)
|
||||
ns3_dir_node = self.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 set(self.to_list(self.source)):
|
||||
src_node = self.path.find_resource(filename)
|
||||
if src_node is None:
|
||||
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', env=self.env)
|
||||
task.mode = self.mode
|
||||
if self.mode == 'install':
|
||||
self.bld.install_files('${PREFIX}/include/ns3', [src_node])
|
||||
task.set_inputs([src_node])
|
||||
task.set_outputs([dst_node])
|
||||
else:
|
||||
task.header_to_remove = dst_node
|
||||
@TaskGen.feature('ns3header')
|
||||
@TaskGen.after_method('process_rule')
|
||||
def apply_ns3header(self):
|
||||
if self.module is None:
|
||||
raise WafError("'module' missing on ns3headers object %s" % self)
|
||||
ns3_dir_node = self.bld.path.find_dir("ns3")
|
||||
for filename in set(self.to_list(self.source)):
|
||||
src_node = self.path.find_resource(filename)
|
||||
if src_node is None:
|
||||
raise WafError("source ns3 header file %s not found" % (filename,))
|
||||
dst_node = ns3_dir_node.find_or_declare(src_node.name)
|
||||
assert dst_node is not None
|
||||
task = self.create_task('ns3header')
|
||||
task.mode = getattr(self, 'mode', 'install')
|
||||
if task.mode == 'install':
|
||||
self.bld.install_files('${PREFIX}/include/ns3', [src_node])
|
||||
task.set_inputs([src_node])
|
||||
task.set_outputs([dst_node])
|
||||
else:
|
||||
task.header_to_remove = dst_node
|
||||
self.headers = set(self.to_list(self.source))
|
||||
self.source = '' # tell WAF not to process these files further
|
||||
|
||||
|
||||
class ns3header_task(Task.Task):
|
||||
before = 'cc cxx gen_ns3_module_header_task'
|
||||
before = 'cc cxx gen_ns3_module_header'
|
||||
color = 'BLUE'
|
||||
|
||||
def __str__(self):
|
||||
@@ -572,23 +442,41 @@ class ns3header_task(Task.Task):
|
||||
if self.outputs: sep = ' -> '
|
||||
else: sep = ''
|
||||
if self.mode == 'remove':
|
||||
return 'rm-ns3-header %s\n' % (self.header_to_remove.bldpath(self.env),)
|
||||
return 'rm-ns3-header %s\n' % (self.header_to_remove.abspath(),)
|
||||
return 'install-ns3-header: %s%s%s\n' % (src_str, sep, tgt_str)
|
||||
|
||||
def __repr__(self):
|
||||
return str(self)
|
||||
|
||||
def uid(self):
|
||||
try:
|
||||
return self.uid_
|
||||
except AttributeError:
|
||||
m = Utils.md5()
|
||||
up = m.update
|
||||
up(self.__class__.__name__.encode())
|
||||
for x in self.inputs + self.outputs:
|
||||
up(x.abspath().encode())
|
||||
up(self.mode)
|
||||
if self.mode == 'remove':
|
||||
up(self.header_to_remove.abspath().encode())
|
||||
self.uid_ = m.digest()
|
||||
return self.uid_
|
||||
|
||||
def runnable_status(self):
|
||||
if self.mode == 'remove':
|
||||
if os.path.exists(self.header_to_remove.bldpath(self.env)):
|
||||
return Constants.RUN_ME
|
||||
if os.path.exists(self.header_to_remove.abspath()):
|
||||
return Task.RUN_ME
|
||||
else:
|
||||
return Constants.SKIP_ME
|
||||
return Task.SKIP_ME
|
||||
else:
|
||||
return super(ns3header_task, self).runnable_status()
|
||||
|
||||
def run(self):
|
||||
if self.mode == 'install':
|
||||
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]
|
||||
inputs = [node.abspath() for node in self.inputs]
|
||||
outputs = [node.abspath() for node in self.outputs]
|
||||
for src, dst in zip(inputs, outputs):
|
||||
try:
|
||||
os.chmod(dst, 0600)
|
||||
@@ -602,7 +490,7 @@ class ns3header_task(Task.Task):
|
||||
else:
|
||||
assert len(self.inputs) == 0
|
||||
assert len(self.outputs) == 0
|
||||
out_file_name = self.header_to_remove.bldpath(self.env)
|
||||
out_file_name = self.header_to_remove.abspath()
|
||||
try:
|
||||
os.unlink(out_file_name)
|
||||
except OSError, ex:
|
||||
@@ -613,15 +501,15 @@ class ns3header_task(Task.Task):
|
||||
|
||||
class gen_ns3_module_header_task(Task.Task):
|
||||
before = 'cc cxx'
|
||||
after = 'ns3header_task'
|
||||
after = 'ns3header'
|
||||
color = 'BLUE'
|
||||
|
||||
def runnable_status(self):
|
||||
if self.mode == 'remove':
|
||||
if os.path.exists(self.header_to_remove.bldpath(self.env)):
|
||||
return Constants.RUN_ME
|
||||
if os.path.exists(self.header_to_remove.abspath()):
|
||||
return Task.RUN_ME
|
||||
else:
|
||||
return Constants.SKIP_ME
|
||||
return Task.SKIP_ME
|
||||
else:
|
||||
return super(gen_ns3_module_header_task, self).runnable_status()
|
||||
|
||||
@@ -633,24 +521,23 @@ class gen_ns3_module_header_task(Task.Task):
|
||||
if self.outputs: sep = ' -> '
|
||||
else: sep = ''
|
||||
if self.mode == 'remove':
|
||||
return 'rm-module-header %s\n' % (self.header_to_remove.bldpath(self.env),)
|
||||
return 'rm-module-header %s\n' % (self.header_to_remove.abspath(),)
|
||||
return 'gen-module-header: %s%s%s\n' % (src_str, sep, tgt_str)
|
||||
|
||||
def run(self):
|
||||
if self.mode == 'remove':
|
||||
assert len(self.inputs) == 0
|
||||
assert len(self.outputs) == 0
|
||||
out_file_name = self.header_to_remove.bldpath(self.env)
|
||||
out_file_name = self.header_to_remove.abspath()
|
||||
try:
|
||||
os.unlink(out_file_name)
|
||||
except OSError, ex:
|
||||
if ex.errno != 2:
|
||||
raise
|
||||
return 0
|
||||
|
||||
assert len(self.outputs) == 1
|
||||
out_file_name = self.outputs[0].bldpath(self.env)
|
||||
header_files = [os.path.basename(node.abspath(self.env)) for node in self.inputs]
|
||||
out_file_name = self.outputs[0].get_bld().abspath()#self.env)
|
||||
header_files = [os.path.basename(node.abspath()) for node in self.inputs]
|
||||
outfile = file(out_file_name, "w")
|
||||
header_files.sort()
|
||||
|
||||
@@ -678,7 +565,7 @@ class gen_ns3_module_header_task(Task.Task):
|
||||
return 0
|
||||
|
||||
def sig_explicit_deps(self):
|
||||
self.m.update('\n'.join([node.abspath(self.env) for node in self.inputs]))
|
||||
self.m.update('\n'.join([node.abspath() for node in self.inputs]))
|
||||
return self.m.digest()
|
||||
|
||||
def unique_id(self):
|
||||
@@ -692,50 +579,46 @@ class gen_ns3_module_header_task(Task.Task):
|
||||
return self.uid
|
||||
|
||||
|
||||
class ns3moduleheader_taskgen(TaskGen.task_gen):
|
||||
"""
|
||||
Generates a 'ns3/foo-module.h' header file that includes all
|
||||
public ns3 headers of a certain module.
|
||||
"""
|
||||
COLOR = 'BLUE'
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ns3moduleheader_taskgen, self).__init__(*args, **kwargs)
|
||||
self.mode = 'install'
|
||||
# Generates a 'ns3/foo-module.h' header file that includes all public
|
||||
# ns3 headers of a certain module.
|
||||
@TaskGen.feature('ns3moduleheader')
|
||||
@TaskGen.after_method('process_rule')
|
||||
def apply_ns3moduleheader(self):
|
||||
## get all of the ns3 headers
|
||||
ns3_dir_node = self.bld.path.find_dir("ns3")
|
||||
all_headers_inputs = []
|
||||
found_the_module = False
|
||||
for ns3headers in self.bld.all_task_gen:
|
||||
if 'ns3header' in getattr(ns3headers, "features", []):
|
||||
if ns3headers.module != self.module:
|
||||
continue
|
||||
found_the_module = True
|
||||
for source in ns3headers.headers:
|
||||
source = 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)
|
||||
if not found_the_module:
|
||||
raise WafError("error finding headers for module %s" % self.module)
|
||||
if not all_headers_inputs:
|
||||
return
|
||||
|
||||
def apply(self):
|
||||
## get all of the ns3 headers
|
||||
ns3_dir_node = self.bld.path.find_dir("ns3")
|
||||
all_headers_inputs = []
|
||||
found_the_module = False
|
||||
for ns3headers in self.bld.all_task_gen:
|
||||
if isinstance(ns3headers, ns3header_taskgen):
|
||||
if ns3headers.module != self.module:
|
||||
continue
|
||||
found_the_module = True
|
||||
for source in set(ns3headers.to_list(ns3headers.source)):
|
||||
source = 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)
|
||||
if not found_the_module:
|
||||
raise Utils.WscriptError("error finding headers for module %s" % self.module)
|
||||
if not all_headers_inputs:
|
||||
return
|
||||
all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self.module)]
|
||||
task = self.create_task('gen_ns3_module_header', env=self.env)
|
||||
task.module = self.module
|
||||
task.mode = self.mode
|
||||
if self.mode == 'install':
|
||||
self.bld.install_files('${PREFIX}/include/ns3',
|
||||
ns3_dir_node.find_or_declare("%s-module.h" % self.module))
|
||||
task.set_inputs(all_headers_inputs)
|
||||
task.set_outputs(all_headers_outputs)
|
||||
module_obj = self.bld.name_to_obj("ns3-" + self.module, self.env)
|
||||
assert module_obj is not None, self.module
|
||||
task.module_deps = module_obj.module_deps
|
||||
else:
|
||||
task.header_to_remove = all_headers_outputs[0]
|
||||
try:
|
||||
module_obj = self.bld.get_tgen_by_name("ns3-" + self.module)
|
||||
except WafError: # maybe the module was disabled, and therefore removed
|
||||
return
|
||||
|
||||
def install(self):
|
||||
pass
|
||||
all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self.module)]
|
||||
task = self.create_task('gen_ns3_module_header')
|
||||
task.module = self.module
|
||||
task.mode = getattr(self, "mode", "install")
|
||||
if task.mode == 'install':
|
||||
assert module_obj is not None, self.module
|
||||
self.bld.install_files('${PREFIX}/include/ns3',
|
||||
ns3_dir_node.find_or_declare("%s-module.h" % self.module))
|
||||
task.set_inputs(all_headers_inputs)
|
||||
task.set_outputs(all_headers_outputs)
|
||||
task.module_deps = module_obj.module_deps
|
||||
else:
|
||||
task.header_to_remove = all_headers_outputs[0]
|
||||
|
||||
38
test.py
38
test.py
@@ -42,7 +42,6 @@ from utils import get_list_from_file
|
||||
# found in the associated subdirectory wscript files.
|
||||
#
|
||||
interesting_config_items = [
|
||||
"NS3_BUILDDIR",
|
||||
"NS3_ENABLED_MODULES",
|
||||
"NS3_MODULE_PATH",
|
||||
"NSC_ENABLED",
|
||||
@@ -483,24 +482,6 @@ def sigint_hook(signal, frame):
|
||||
thread_exit = True
|
||||
return 0
|
||||
|
||||
#
|
||||
# Waf can be configured to compile in debug or optimized modes. In each
|
||||
# case, the resulting built goes into a different directory. If we want
|
||||
# test tests to run from the correct code-base, we have to figure out which
|
||||
# mode waf is running in. This is called its active variant.
|
||||
#
|
||||
# XXX This function pokes around in the waf internal state file. To be a
|
||||
# little less hacky, we should add a commmand to waf to return this info
|
||||
# and use that result.
|
||||
#
|
||||
def read_waf_active_variant():
|
||||
for line in open("build/c4che/default.cache.py").readlines():
|
||||
if line.startswith("NS3_ACTIVE_VARIANT"):
|
||||
exec(line, globals())
|
||||
break
|
||||
|
||||
if options.verbose:
|
||||
print "NS3_ACTIVE_VARIANT == %s" % NS3_ACTIVE_VARIANT
|
||||
|
||||
#
|
||||
# In general, the build process itself naturally takes care of figuring out
|
||||
@@ -519,7 +500,13 @@ def read_waf_active_variant():
|
||||
# and use that result.
|
||||
#
|
||||
def read_waf_config():
|
||||
for line in open("build/c4che/%s.cache.py" % NS3_ACTIVE_VARIANT).readlines():
|
||||
for line in open(".lock-wafbuild", "rt"):
|
||||
if line.startswith("out_dir ="):
|
||||
key, val = line.split('=')
|
||||
out_dir = eval(val.strip())
|
||||
global NS3_BUILDDIR
|
||||
NS3_BUILDDIR = out_dir
|
||||
for line in open("%s/c4che/_cache.py" % out_dir).readlines():
|
||||
for item in interesting_config_items:
|
||||
if line.startswith(item):
|
||||
exec(line, globals())
|
||||
@@ -555,7 +542,7 @@ def make_paths():
|
||||
if key == "PYTHONPATH":
|
||||
have_PYTHONPATH = True
|
||||
|
||||
pypath = os.environ["PYTHONPATH"] = os.path.join (NS3_BUILDDIR, NS3_ACTIVE_VARIANT, "bindings", "python")
|
||||
pypath = os.environ["PYTHONPATH"] = os.path.join (NS3_BUILDDIR, "bindings", "python")
|
||||
|
||||
if not have_PYTHONPATH:
|
||||
os.environ["PYTHONPATH"] = pypath
|
||||
@@ -684,7 +671,7 @@ def run_job_synchronously(shell_command, directory, valgrind, is_python, build_p
|
||||
if len(build_path):
|
||||
path_cmd = os.path.join (build_path, shell_command)
|
||||
else:
|
||||
path_cmd = os.path.join (NS3_BUILDDIR, NS3_ACTIVE_VARIANT, shell_command)
|
||||
path_cmd = os.path.join (NS3_BUILDDIR, shell_command)
|
||||
|
||||
if valgrind:
|
||||
cmd = "valgrind --suppressions=%s --leak-check=full --show-reachable=yes --error-exitcode=2 %s" % (suppressions_path,
|
||||
@@ -991,12 +978,11 @@ def run_tests():
|
||||
# pieces of the system have been built. This will tell us what examples
|
||||
# are runnable.
|
||||
#
|
||||
read_waf_active_variant()
|
||||
read_waf_config()
|
||||
make_paths()
|
||||
|
||||
# Get the information from the build status file.
|
||||
build_status_file = os.path.join (NS3_BUILDDIR, NS3_ACTIVE_VARIANT, 'build-status.py')
|
||||
build_status_file = os.path.join (NS3_BUILDDIR, 'build-status.py')
|
||||
if os.path.exists(build_status_file):
|
||||
ns3_runnable_programs = get_list_from_file(build_status_file, "ns3_runnable_programs")
|
||||
ns3_runnable_scripts = get_list_from_file(build_status_file, "ns3_runnable_scripts")
|
||||
@@ -1013,7 +999,7 @@ def run_tests():
|
||||
# Set the directories and paths for this example.
|
||||
example_directory = os.path.join("examples", directory)
|
||||
examples_to_run_path = os.path.join(example_directory, "examples-to-run.py")
|
||||
cpp_executable_dir = os.path.join(NS3_BUILDDIR, NS3_ACTIVE_VARIANT, example_directory)
|
||||
cpp_executable_dir = os.path.join(NS3_BUILDDIR, example_directory)
|
||||
python_script_dir = os.path.join(example_directory)
|
||||
|
||||
# Parse this example directory's file.
|
||||
@@ -1032,7 +1018,7 @@ def run_tests():
|
||||
module_directory = os.path.join("src", module)
|
||||
example_directory = os.path.join(module_directory, "examples")
|
||||
examples_to_run_path = os.path.join(module_directory, "test", "examples-to-run.py")
|
||||
cpp_executable_dir = os.path.join(NS3_BUILDDIR, NS3_ACTIVE_VARIANT, example_directory)
|
||||
cpp_executable_dir = os.path.join(NS3_BUILDDIR, example_directory)
|
||||
python_script_dir = os.path.join(example_directory)
|
||||
|
||||
# Parse this module's file.
|
||||
|
||||
@@ -10,7 +10,7 @@ def build(bld):
|
||||
|
||||
# Set the libraries the testrunner depends on equal to the list of
|
||||
# enabled modules plus the list of enabled module test libraries.
|
||||
test_runner.uselib_local = [mod+"--lib" for mod in (env['NS3_ENABLED_MODULES'] + env['NS3_ENABLED_MODULE_TEST_LIBRARIES'])]
|
||||
test_runner.use = [mod for mod in (env['NS3_ENABLED_MODULES'] + env['NS3_ENABLED_MODULE_TEST_LIBRARIES'])]
|
||||
|
||||
obj = bld.create_ns3_program('bench-simulator', ['core'])
|
||||
obj.source = 'bench-simulator.cc'
|
||||
@@ -28,5 +28,5 @@ def build(bld):
|
||||
|
||||
obj = bld.create_ns3_program('print-introspected-doxygen', ['network'])
|
||||
obj.source = 'print-introspected-doxygen.cc'
|
||||
obj.uselib_local = [mod+"--lib" for mod in env['NS3_ENABLED_MODULES']]
|
||||
obj.use = [mod for mod in env['NS3_ENABLED_MODULES']]
|
||||
|
||||
|
||||
269
waf-tools/boost.py
Normal file
269
waf-tools/boost.py
Normal file
@@ -0,0 +1,269 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
#
|
||||
# partially based on boost.py written by Gernot Vormayr
|
||||
# written by Ruediger Sonderfeld <ruediger@c-plusplus.de>, 2008
|
||||
# modified by Bjoern Michaelsen, 2008
|
||||
# modified by Luca Fossati, 2008
|
||||
# rewritten for waf 1.5.1, Thomas Nagy, 2008
|
||||
# rewritten for waf 1.6.2, Sylvain Rouquette, 2011
|
||||
|
||||
'''
|
||||
To add the boost tool to the waf file:
|
||||
$ ./waf-light --tools=compat15,boost
|
||||
or, if you have waf >= 1.6.2
|
||||
$ ./waf update --files=boost
|
||||
|
||||
The wscript will look like:
|
||||
|
||||
def options(opt):
|
||||
opt.load('compiler_cxx boost')
|
||||
|
||||
def configure(conf):
|
||||
conf.load('compiler_cxx boost')
|
||||
conf.check_boost(lib='system filesystem', mt=True, static=True)
|
||||
|
||||
def build(bld):
|
||||
bld(source='main.cpp', target='app', use='BOOST')
|
||||
'''
|
||||
|
||||
import sys
|
||||
import re
|
||||
from waflib import Utils, Logs
|
||||
from waflib.Configure import conf
|
||||
|
||||
BOOST_LIBS = ('/usr/lib', '/usr/local/lib',
|
||||
'/opt/local/lib', '/sw/lib', '/lib')
|
||||
BOOST_INCLUDES = ('/usr/include', '/usr/local/include',
|
||||
'/opt/local/include', '/sw/include')
|
||||
BOOST_VERSION_FILE = 'boost/version.hpp'
|
||||
BOOST_VERSION_CODE = '''
|
||||
#include <iostream>
|
||||
#include <boost/version.hpp>
|
||||
int main() { std::cout << BOOST_LIB_VERSION << std::endl; }
|
||||
'''
|
||||
|
||||
# toolsets from {boost_dir}/tools/build/v2/tools/common.jam
|
||||
PLATFORM = Utils.unversioned_sys_platform()
|
||||
detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
|
||||
detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang'
|
||||
detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc'
|
||||
BOOST_TOOLSETS = {
|
||||
'borland': 'bcb',
|
||||
'clang': detect_clang,
|
||||
'como': 'como',
|
||||
'cw': 'cw',
|
||||
'darwin': 'xgcc',
|
||||
'edg': 'edg',
|
||||
'g++': detect_mingw,
|
||||
'gcc': detect_mingw,
|
||||
'icpc': detect_intel,
|
||||
'intel': detect_intel,
|
||||
'kcc': 'kcc',
|
||||
'kylix': 'bck',
|
||||
'mipspro': 'mp',
|
||||
'mingw': 'mgw',
|
||||
'msvc': 'vc',
|
||||
'qcc': 'qcc',
|
||||
'sun': 'sw',
|
||||
'sunc++': 'sw',
|
||||
'tru64cxx': 'tru',
|
||||
'vacpp': 'xlc'
|
||||
}
|
||||
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--boost-includes', type='string',
|
||||
default='', dest='boost_includes',
|
||||
help='''path to the boost directory where the includes are
|
||||
e.g. /boost_1_45_0/include''')
|
||||
opt.add_option('--boost-libs', type='string',
|
||||
default='', dest='boost_libs',
|
||||
help='''path to the directory where the boost libs are
|
||||
e.g. /boost_1_45_0/stage/lib''')
|
||||
opt.add_option('--boost-static', action='store_true',
|
||||
default=False, dest='boost_static',
|
||||
help='link static libraries')
|
||||
opt.add_option('--boost-mt', action='store_true',
|
||||
default=False, dest='boost_mt',
|
||||
help='select multi-threaded libraries')
|
||||
opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
|
||||
help='''select libraries with tags (dgsyp, d for debug),
|
||||
see doc Boost, Getting Started, chapter 6.1''')
|
||||
opt.add_option('--boost-toolset', type='string',
|
||||
default='', dest='boost_toolset',
|
||||
help='force a toolset e.g. msvc, vc90, \
|
||||
gcc, mingw, mgw45 (default: auto)')
|
||||
py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
|
||||
opt.add_option('--boost-python', type='string',
|
||||
default=py_version, dest='boost_python',
|
||||
help='select the lib python with this version \
|
||||
(default: %s)' % py_version)
|
||||
|
||||
|
||||
@conf
|
||||
def __boost_get_version_file(self, dir):
|
||||
try:
|
||||
return self.root.find_dir(dir).find_node(BOOST_VERSION_FILE)
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
@conf
|
||||
def boost_get_version(self, dir):
|
||||
"""silently retrieve the boost version number"""
|
||||
re_but = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.*)"$', re.M)
|
||||
try:
|
||||
val = re_but.search(self.__boost_get_version_file(dir).read()).group(1)
|
||||
except:
|
||||
val = self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[dir],
|
||||
execute=True, define_ret=True)
|
||||
return val
|
||||
|
||||
|
||||
@conf
|
||||
def boost_get_includes(self, *k, **kw):
|
||||
includes = k and k[0] or kw.get('includes', None)
|
||||
if includes and self.__boost_get_version_file(includes):
|
||||
return includes
|
||||
for dir in BOOST_INCLUDES:
|
||||
if self.__boost_get_version_file(dir):
|
||||
return dir
|
||||
if includes:
|
||||
self.fatal('headers not found in %s' % includes)
|
||||
else:
|
||||
self.fatal('headers not found, use --boost-includes=/path/to/boost')
|
||||
|
||||
|
||||
@conf
|
||||
def boost_get_toolset(self, cc):
|
||||
toolset = cc
|
||||
if not cc:
|
||||
build_platform = Utils.unversioned_sys_platform()
|
||||
if build_platform in BOOST_TOOLSETS:
|
||||
cc = build_platform
|
||||
else:
|
||||
cc = self.env.CXX_NAME
|
||||
if cc in BOOST_TOOLSETS:
|
||||
toolset = BOOST_TOOLSETS[cc]
|
||||
return isinstance(toolset, str) and toolset or toolset(self.env)
|
||||
|
||||
|
||||
@conf
|
||||
def __boost_get_libs_path(self, *k, **kw):
|
||||
''' return the lib path and all the files in it '''
|
||||
if 'files' in kw:
|
||||
return self.root.find_dir('.'), Utils.to_list(kw['files'])
|
||||
libs = k and k[0] or kw.get('libs', None)
|
||||
if libs:
|
||||
path = self.root.find_dir(libs)
|
||||
files = path.ant_glob('*boost_*')
|
||||
if not libs or not files:
|
||||
for dir in BOOST_LIBS:
|
||||
try:
|
||||
path = self.root.find_dir(dir)
|
||||
files = path.ant_glob('*boost_*')
|
||||
if files:
|
||||
break
|
||||
path = self.root.find_dir(dir + '64')
|
||||
files = path.ant_glob('*boost_*')
|
||||
if files:
|
||||
break
|
||||
except:
|
||||
path = None
|
||||
if not path:
|
||||
if libs:
|
||||
self.fatal('libs not found in %s' % libs)
|
||||
else:
|
||||
self.fatal('libs not found, \
|
||||
use --boost-includes=/path/to/boost/lib')
|
||||
return path, files
|
||||
|
||||
|
||||
@conf
|
||||
def boost_get_libs(self, *k, **kw):
|
||||
'''
|
||||
return the lib path and the required libs
|
||||
according to the parameters
|
||||
'''
|
||||
path, files = self.__boost_get_libs_path(**kw)
|
||||
t = []
|
||||
if kw.get('mt', False):
|
||||
t.append('mt')
|
||||
if kw.get('abi', None):
|
||||
t.append(kw['abi'])
|
||||
tags = t and '(-%s)+' % '-'.join(t) or ''
|
||||
toolset = '(-%s[0-9]{0,3})+' % self.boost_get_toolset(kw.get('toolset', ''))
|
||||
version = '(-%s)+' % self.env.BOOST_VERSION
|
||||
|
||||
def find_lib(re_lib, files):
|
||||
for file in files:
|
||||
if re_lib.search(file.name):
|
||||
return file
|
||||
return None
|
||||
|
||||
def format_lib_name(name):
|
||||
if name.startswith('lib'):
|
||||
name = name[3:]
|
||||
return name.split('.')[0]
|
||||
|
||||
libs = []
|
||||
for lib in Utils.to_list(k and k[0] or kw.get('lib', None)):
|
||||
py = (lib == 'python') and '(-py%s)+' % kw['python'] or ''
|
||||
# Trying libraries, from most strict match to least one
|
||||
for pattern in ['boost_%s%s%s%s%s' % (lib, toolset, tags, py, version),
|
||||
'boost_%s%s%s%s' % (lib, tags, py, version),
|
||||
'boost_%s%s%s' % (lib, tags, version),
|
||||
# Give up trying to find the right version
|
||||
'boost_%s%s%s%s' % (lib, toolset, tags, py),
|
||||
'boost_%s%s%s' % (lib, tags, py),
|
||||
'boost_%s%s' % (lib, tags)]:
|
||||
file = find_lib(re.compile(pattern), files)
|
||||
if file:
|
||||
libs.append(format_lib_name(file.name))
|
||||
break
|
||||
else:
|
||||
self.fatal('lib %s not found in %s' % (lib, path))
|
||||
|
||||
return path.abspath(), libs
|
||||
|
||||
|
||||
@conf
|
||||
def check_boost(self, *k, **kw):
|
||||
"""
|
||||
initialize boost
|
||||
|
||||
You can pass the same parameters as the command line (without "--boost-"),
|
||||
but the command line has the priority.
|
||||
"""
|
||||
if not self.env['CXX']:
|
||||
self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
|
||||
|
||||
params = {'lib': k and k[0] or kw.get('lib', None)}
|
||||
for key, value in self.options.__dict__.items():
|
||||
if not key.startswith('boost_'):
|
||||
continue
|
||||
key = key[len('boost_'):]
|
||||
params[key] = value and value or kw.get(key, '')
|
||||
|
||||
var = kw.get('uselib_store', 'BOOST')
|
||||
|
||||
self.start_msg('Checking boost includes')
|
||||
self.env['INCLUDES_%s' % var] = self.boost_get_includes(**params)
|
||||
self.env.BOOST_VERSION = self.boost_get_version(self.env['INCLUDES_%s' % var])
|
||||
self.end_msg(self.env.BOOST_VERSION)
|
||||
if Logs.verbose:
|
||||
Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var])
|
||||
|
||||
if not params['lib']:
|
||||
return
|
||||
self.start_msg('Checking boost libs')
|
||||
suffix = params.get('static', 'ST') or ''
|
||||
path, libs = self.boost_get_libs(**params)
|
||||
self.env['%sLIBPATH_%s' % (suffix, var)] = [path]
|
||||
self.env['%sLIB_%s' % (suffix, var)] = libs
|
||||
self.end_msg('ok')
|
||||
if Logs.verbose:
|
||||
Logs.pprint('CYAN', ' path : %s' % path)
|
||||
Logs.pprint('CYAN', ' libs : %s' % libs)
|
||||
|
||||
@@ -144,7 +144,7 @@ profiles = {
|
||||
|
||||
default_profile = 'default'
|
||||
|
||||
def set_options(opt):
|
||||
def options(opt):
|
||||
assert default_profile in profiles
|
||||
opt.add_option('-d', '--build-profile',
|
||||
action='store',
|
||||
@@ -157,7 +157,7 @@ def set_options(opt):
|
||||
choices=profiles.keys(),
|
||||
dest='build_profile')
|
||||
|
||||
def detect(conf):
|
||||
def configure(conf):
|
||||
cc = conf.env['COMPILER_CC'] or None
|
||||
cxx = conf.env['COMPILER_CXX'] or None
|
||||
if not (cc or cxx):
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from TaskGen import feature, taskgen, before, task_gen
|
||||
import Node, Task, Utils, Build, pproc, Constants
|
||||
import TaskGen# import feature, taskgen_method, before_method, task_gen
|
||||
import Node, Task, Utils, Build
|
||||
import subprocess
|
||||
import Options
|
||||
|
||||
import shellcmd
|
||||
shellcmd.subprocess = pproc # the WAF version of the subprocess module is supposedly less buggy
|
||||
#shellcmd.subprocess = pproc # the WAF version of the subprocess module is supposedly less buggy
|
||||
|
||||
from Logs import debug, error
|
||||
shellcmd.debug = debug
|
||||
@@ -18,7 +19,7 @@ arg_rx = re.compile(r"(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\}
|
||||
class command_task(Task.Task):
|
||||
color = "BLUE"
|
||||
def __init__(self, env, generator):
|
||||
Task.Task.__init__(self, env, normal=1, generator=generator)
|
||||
Task.Task.__init__(self, env=env, normal=1, generator=generator)
|
||||
|
||||
def __str__(self):
|
||||
"string to display to the user"
|
||||
@@ -33,7 +34,6 @@ class command_task(Task.Task):
|
||||
pipeline = shellcmd.Pipeline()
|
||||
pipeline.parse(self.generator.command)
|
||||
cmd = pipeline.get_abbreviated_command()
|
||||
|
||||
return 'command (%s): %s%s%s\n' % (cmd, src_str, sep, tgt_str)
|
||||
|
||||
def _subst_arg(self, arg, direction, namespace):
|
||||
@@ -50,21 +50,24 @@ class command_task(Task.Task):
|
||||
result = eval(var+code, namespace)
|
||||
if isinstance(result, Node.Node):
|
||||
if var == 'TGT':
|
||||
return result.bldpath(self.env)
|
||||
return result.get_bld().abspath()
|
||||
elif var == 'SRC':
|
||||
return result.srcpath(self.env)
|
||||
return result.srcpath()
|
||||
else:
|
||||
raise ValueError("Bad subst variable %r" % var)
|
||||
elif result is self.inputs:
|
||||
if len(self.inputs) == 1:
|
||||
return result[0].srcpath(self.env)
|
||||
return result[0].srcpath()
|
||||
else:
|
||||
raise ValueError("${SRC} requested but have multiple sources; which one?")
|
||||
elif result is self.outputs:
|
||||
if len(self.outputs) == 1:
|
||||
return result[0].bldpath(self.env)
|
||||
return result[0].get_bld().abspath()
|
||||
else:
|
||||
raise ValueError("${TGT} requested but have multiple targets; which one?")
|
||||
elif isinstance(result, list):
|
||||
assert len(result) == 1
|
||||
return result[0]
|
||||
else:
|
||||
return result
|
||||
return None
|
||||
@@ -95,40 +98,37 @@ class command_task(Task.Task):
|
||||
cmd.env_vars = env_vars
|
||||
elif isinstance(cmd, shellcmd.Chdir):
|
||||
cmd.dir = self._subst_arg(cmd.dir, None, namespace)
|
||||
|
||||
return pipeline.run(verbose=(Options.options.verbose > 0))
|
||||
|
||||
@taskgen
|
||||
@feature('command')
|
||||
@TaskGen.taskgen_method
|
||||
@TaskGen.feature('command')
|
||||
def init_command(self):
|
||||
Utils.def_attrs(self,
|
||||
# other variables that can be used in the command: ${VARIABLE}
|
||||
variables = None)
|
||||
# other variables that can be used in the command: ${VARIABLE}
|
||||
variables = None,
|
||||
rule='')
|
||||
|
||||
|
||||
|
||||
@taskgen
|
||||
@feature('command')
|
||||
@before('apply_core')
|
||||
@TaskGen.feature('command')
|
||||
@TaskGen.after_method('process_rule')
|
||||
def apply_command(self):
|
||||
self.meths.remove('apply_core')
|
||||
#self.meths.remove('apply_core')
|
||||
# create the task
|
||||
task = self.create_task('command')
|
||||
setattr(task, "dep_vars", getattr(self, "dep_vars", None))
|
||||
# process the sources
|
||||
inputs = []
|
||||
for src in self.to_list(self.source):
|
||||
node = self.path.find_resource(src)
|
||||
if node is None:
|
||||
raise Utils.WafError("source %s not found" % src)
|
||||
inputs.append(node)
|
||||
for node in self.source:
|
||||
inputs.append(node)
|
||||
task.set_inputs(inputs)
|
||||
task.set_outputs([self.path.find_or_declare(tgt) for tgt in self.to_list(self.target)])
|
||||
self.source = ''
|
||||
#Task.file_deps = Task.extract_deps
|
||||
|
||||
|
||||
|
||||
class command_taskgen(task_gen):
|
||||
def __init__(self, *k, **kw):
|
||||
task_gen.__init__(self, *k, **kw)
|
||||
self.features.append('command')
|
||||
# class command_taskgen(task_gen):
|
||||
# def __init__(self, *k, **kw):
|
||||
# task_gen.__init__(self, *k, **kw)
|
||||
# self.features.append('command')
|
||||
|
||||
416
waf-tools/misc.py
Normal file
416
waf-tools/misc.py
Normal file
@@ -0,0 +1,416 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
# Thomas Nagy, 2006-2010 (ita)
|
||||
|
||||
"""
|
||||
This tool is totally deprecated
|
||||
|
||||
Try using:
|
||||
.pc.in files for .pc files
|
||||
the feature intltool_in - see demos/intltool
|
||||
make-like rules
|
||||
"""
|
||||
|
||||
import shutil, re, os
|
||||
from waflib import TaskGen, Node, Task, Utils, Build, Errors
|
||||
from waflib.TaskGen import feature, after_method, before_method
|
||||
from waflib.Logs import debug
|
||||
|
||||
def copy_attrs(orig, dest, names, only_if_set=False):
|
||||
"""
|
||||
copy class attributes from an object to another
|
||||
"""
|
||||
for a in Utils.to_list(names):
|
||||
u = getattr(orig, a, ())
|
||||
if u or not only_if_set:
|
||||
setattr(dest, a, u)
|
||||
|
||||
def copy_func(tsk):
|
||||
"Make a file copy. This might be used to make other kinds of file processing (even calling a compiler is possible)"
|
||||
env = tsk.env
|
||||
infile = tsk.inputs[0].abspath()
|
||||
outfile = tsk.outputs[0].abspath()
|
||||
try:
|
||||
shutil.copy2(infile, outfile)
|
||||
except (OSError, IOError):
|
||||
return 1
|
||||
else:
|
||||
if tsk.chmod: os.chmod(outfile, tsk.chmod)
|
||||
return 0
|
||||
|
||||
def action_process_file_func(tsk):
|
||||
"Ask the function attached to the task to process it"
|
||||
if not tsk.fun: raise Errors.WafError('task must have a function attached to it for copy_func to work!')
|
||||
return tsk.fun(tsk)
|
||||
|
||||
@feature('cmd')
|
||||
def apply_cmd(self):
|
||||
"call a command everytime"
|
||||
if not self.fun: raise Errors.WafError('cmdobj needs a function!')
|
||||
tsk = Task.TaskBase()
|
||||
tsk.fun = self.fun
|
||||
tsk.env = self.env
|
||||
self.tasks.append(tsk)
|
||||
tsk.install_path = self.install_path
|
||||
|
||||
@feature('copy')
|
||||
@before_method('process_source')
|
||||
def apply_copy(self):
|
||||
Utils.def_attrs(self, fun=copy_func)
|
||||
self.default_install_path = 0
|
||||
|
||||
lst = self.to_list(self.source)
|
||||
self.meths.remove('process_source')
|
||||
|
||||
for filename in lst:
|
||||
node = self.path.find_resource(filename)
|
||||
if not node: raise Errors.WafError('cannot find input file %s for processing' % filename)
|
||||
|
||||
target = self.target
|
||||
if not target or len(lst)>1: target = node.name
|
||||
|
||||
# TODO the file path may be incorrect
|
||||
newnode = self.path.find_or_declare(target)
|
||||
|
||||
tsk = self.create_task('copy', node, newnode)
|
||||
tsk.fun = self.fun
|
||||
tsk.chmod = getattr(self, 'chmod', Utils.O644)
|
||||
|
||||
if not tsk.env:
|
||||
tsk.debug()
|
||||
raise Errors.WafError('task without an environment')
|
||||
|
||||
def subst_func(tsk):
|
||||
"Substitutes variables in a .in file"
|
||||
|
||||
m4_re = re.compile('@(\w+)@', re.M)
|
||||
|
||||
code = tsk.inputs[0].read() #Utils.readf(infile)
|
||||
|
||||
# replace all % by %% to prevent errors by % signs in the input file while string formatting
|
||||
code = code.replace('%', '%%')
|
||||
|
||||
s = m4_re.sub(r'%(\1)s', code)
|
||||
|
||||
env = tsk.env
|
||||
di = getattr(tsk, 'dict', {}) or getattr(tsk.generator, 'dict', {})
|
||||
if not di:
|
||||
names = m4_re.findall(code)
|
||||
for i in names:
|
||||
di[i] = env.get_flat(i) or env.get_flat(i.upper())
|
||||
|
||||
tsk.outputs[0].write(s % di)
|
||||
|
||||
@feature('subst')
|
||||
@before_method('process_source')
|
||||
def apply_subst(self):
|
||||
Utils.def_attrs(self, fun=subst_func)
|
||||
lst = self.to_list(self.source)
|
||||
self.meths.remove('process_source')
|
||||
|
||||
self.dict = getattr(self, 'dict', {})
|
||||
|
||||
for filename in lst:
|
||||
node = self.path.find_resource(filename)
|
||||
if not node: raise Errors.WafError('cannot find input file %s for processing' % filename)
|
||||
|
||||
if self.target:
|
||||
newnode = self.path.find_or_declare(self.target)
|
||||
else:
|
||||
newnode = node.change_ext('')
|
||||
|
||||
try:
|
||||
self.dict = self.dict.get_merged_dict()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
if self.dict and not self.env['DICT_HASH']:
|
||||
self.env = self.env.derive()
|
||||
keys = list(self.dict.keys())
|
||||
keys.sort()
|
||||
lst = [self.dict[x] for x in keys]
|
||||
self.env['DICT_HASH'] = str(Utils.h_list(lst))
|
||||
|
||||
tsk = self.create_task('copy', node, newnode)
|
||||
tsk.fun = self.fun
|
||||
tsk.dict = self.dict
|
||||
tsk.dep_vars = ['DICT_HASH']
|
||||
tsk.chmod = getattr(self, 'chmod', Utils.O644)
|
||||
|
||||
if not tsk.env:
|
||||
tsk.debug()
|
||||
raise Errors.WafError('task without an environment')
|
||||
|
||||
####################
|
||||
## command-output ####
|
||||
####################
|
||||
|
||||
class cmd_arg(object):
|
||||
"""command-output arguments for representing files or folders"""
|
||||
def __init__(self, name, template='%s'):
|
||||
self.name = name
|
||||
self.template = template
|
||||
self.node = None
|
||||
|
||||
class input_file(cmd_arg):
|
||||
def find_node(self, base_path):
|
||||
assert isinstance(base_path, Node.Node)
|
||||
self.node = base_path.find_resource(self.name)
|
||||
if self.node is None:
|
||||
raise Errors.WafError("Input file %s not found in " % (self.name, base_path))
|
||||
|
||||
def get_path(self, env, absolute):
|
||||
if absolute:
|
||||
return self.template % self.node.abspath()
|
||||
else:
|
||||
return self.template % self.node.srcpath()
|
||||
|
||||
class output_file(cmd_arg):
|
||||
def find_node(self, base_path):
|
||||
assert isinstance(base_path, Node.Node)
|
||||
self.node = base_path.find_or_declare(self.name)
|
||||
if self.node is None:
|
||||
raise Errors.WafError("Output file %s not found in " % (self.name, base_path))
|
||||
|
||||
def get_path(self, env, absolute):
|
||||
if absolute:
|
||||
return self.template % self.node.abspath()
|
||||
else:
|
||||
return self.template % self.node.bldpath()
|
||||
|
||||
class cmd_dir_arg(cmd_arg):
|
||||
def find_node(self, base_path):
|
||||
assert isinstance(base_path, Node.Node)
|
||||
self.node = base_path.find_dir(self.name)
|
||||
if self.node is None:
|
||||
raise Errors.WafError("Directory %s not found in " % (self.name, base_path))
|
||||
|
||||
class input_dir(cmd_dir_arg):
|
||||
def get_path(self, dummy_env, dummy_absolute):
|
||||
return self.template % self.node.abspath()
|
||||
|
||||
class output_dir(cmd_dir_arg):
|
||||
def get_path(self, env, dummy_absolute):
|
||||
return self.template % self.node.abspath()
|
||||
|
||||
|
||||
class command_output(Task.Task):
|
||||
color = "BLUE"
|
||||
def __init__(self, env, command, command_node, command_args, stdin, stdout, cwd, os_env, stderr):
|
||||
Task.Task.__init__(self, env=env)
|
||||
assert isinstance(command, (str, Node.Node))
|
||||
self.command = command
|
||||
self.command_args = command_args
|
||||
self.stdin = stdin
|
||||
self.stdout = stdout
|
||||
self.cwd = cwd
|
||||
self.os_env = os_env
|
||||
self.stderr = stderr
|
||||
|
||||
if command_node is not None: self.dep_nodes = [command_node]
|
||||
self.dep_vars = [] # additional environment variables to look
|
||||
|
||||
def run(self):
|
||||
task = self
|
||||
#assert len(task.inputs) > 0
|
||||
|
||||
def input_path(node, template):
|
||||
if task.cwd is None:
|
||||
return template % node.bldpath()
|
||||
else:
|
||||
return template % node.abspath()
|
||||
def output_path(node, template):
|
||||
fun = node.abspath
|
||||
if task.cwd is None: fun = node.bldpath
|
||||
return template % fun()
|
||||
|
||||
if isinstance(task.command, Node.Node):
|
||||
argv = [input_path(task.command, '%s')]
|
||||
else:
|
||||
argv = [task.command]
|
||||
|
||||
for arg in task.command_args:
|
||||
if isinstance(arg, str):
|
||||
argv.append(arg)
|
||||
else:
|
||||
assert isinstance(arg, cmd_arg)
|
||||
argv.append(arg.get_path(task.env, (task.cwd is not None)))
|
||||
|
||||
if task.stdin:
|
||||
stdin = open(input_path(task.stdin, '%s'))
|
||||
else:
|
||||
stdin = None
|
||||
|
||||
if task.stdout:
|
||||
stdout = open(output_path(task.stdout, '%s'), "w")
|
||||
else:
|
||||
stdout = None
|
||||
|
||||
if task.stderr:
|
||||
stderr = open(output_path(task.stderr, '%s'), "w")
|
||||
else:
|
||||
stderr = None
|
||||
|
||||
if task.cwd is None:
|
||||
cwd = ('None (actually %r)' % os.getcwd())
|
||||
else:
|
||||
cwd = repr(task.cwd)
|
||||
debug("command-output: cwd=%s, stdin=%r, stdout=%r, argv=%r" %
|
||||
(cwd, stdin, stdout, argv))
|
||||
|
||||
if task.os_env is None:
|
||||
os_env = os.environ
|
||||
else:
|
||||
os_env = task.os_env
|
||||
command = Utils.subprocess.Popen(argv, stdin=stdin, stdout=stdout, stderr=stderr, cwd=task.cwd, env=os_env)
|
||||
return command.wait()
|
||||
|
||||
@feature('command-output')
|
||||
def init_cmd_output(self):
|
||||
Utils.def_attrs(self,
|
||||
stdin = None,
|
||||
stdout = None,
|
||||
stderr = None,
|
||||
# the command to execute
|
||||
command = None,
|
||||
|
||||
# whether it is an external command; otherwise it is assumed
|
||||
# to be an executable binary or script that lives in the
|
||||
# source or build tree.
|
||||
command_is_external = False,
|
||||
|
||||
# extra parameters (argv) to pass to the command (excluding
|
||||
# the command itself)
|
||||
argv = [],
|
||||
|
||||
# dependencies to other objects -> this is probably not what you want (ita)
|
||||
# values must be 'task_gen' instances (not names!)
|
||||
dependencies = [],
|
||||
|
||||
# dependencies on env variable contents
|
||||
dep_vars = [],
|
||||
|
||||
# input files that are implicit, i.e. they are not
|
||||
# stdin, nor are they mentioned explicitly in argv
|
||||
hidden_inputs = [],
|
||||
|
||||
# output files that are implicit, i.e. they are not
|
||||
# stdout, nor are they mentioned explicitly in argv
|
||||
hidden_outputs = [],
|
||||
|
||||
# change the subprocess to this cwd (must use obj.input_dir() or output_dir() here)
|
||||
cwd = None,
|
||||
|
||||
# OS environment variables to pass to the subprocess
|
||||
# if None, use the default environment variables unchanged
|
||||
os_env = None)
|
||||
|
||||
@feature('command-output')
|
||||
@after_method('init_cmd_output')
|
||||
def apply_cmd_output(self):
|
||||
if self.command is None:
|
||||
raise Errors.WafError("command-output missing command")
|
||||
if self.command_is_external:
|
||||
cmd = self.command
|
||||
cmd_node = None
|
||||
else:
|
||||
cmd_node = self.path.find_resource(self.command)
|
||||
assert cmd_node is not None, ('''Could not find command '%s' in source tree.
|
||||
Hint: if this is an external command,
|
||||
use command_is_external=True''') % (self.command,)
|
||||
cmd = cmd_node
|
||||
|
||||
if self.cwd is None:
|
||||
cwd = None
|
||||
else:
|
||||
assert isinstance(cwd, CmdDirArg)
|
||||
self.cwd.find_node(self.path)
|
||||
|
||||
args = []
|
||||
inputs = []
|
||||
outputs = []
|
||||
|
||||
for arg in self.argv:
|
||||
if isinstance(arg, cmd_arg):
|
||||
arg.find_node(self.path)
|
||||
if isinstance(arg, input_file):
|
||||
inputs.append(arg.node)
|
||||
if isinstance(arg, output_file):
|
||||
outputs.append(arg.node)
|
||||
|
||||
if self.stdout is None:
|
||||
stdout = None
|
||||
else:
|
||||
assert isinstance(self.stdout, str)
|
||||
stdout = self.path.find_or_declare(self.stdout)
|
||||
if stdout is None:
|
||||
raise Errors.WafError("File %s not found" % (self.stdout,))
|
||||
outputs.append(stdout)
|
||||
|
||||
if self.stderr is None:
|
||||
stderr = None
|
||||
else:
|
||||
assert isinstance(self.stderr, str)
|
||||
stderr = self.path.find_or_declare(self.stderr)
|
||||
if stderr is None:
|
||||
raise Errors.WafError("File %s not found" % (self.stderr,))
|
||||
outputs.append(stderr)
|
||||
|
||||
if self.stdin is None:
|
||||
stdin = None
|
||||
else:
|
||||
assert isinstance(self.stdin, str)
|
||||
stdin = self.path.find_resource(self.stdin)
|
||||
if stdin is None:
|
||||
raise Errors.WafError("File %s not found" % (self.stdin,))
|
||||
inputs.append(stdin)
|
||||
|
||||
for hidden_input in self.to_list(self.hidden_inputs):
|
||||
node = self.path.find_resource(hidden_input)
|
||||
if node is None:
|
||||
raise Errors.WafError("File %s not found in dir %s" % (hidden_input, self.path))
|
||||
inputs.append(node)
|
||||
|
||||
for hidden_output in self.to_list(self.hidden_outputs):
|
||||
node = self.path.find_or_declare(hidden_output)
|
||||
if node is None:
|
||||
raise Errors.WafError("File %s not found in dir %s" % (hidden_output, self.path))
|
||||
outputs.append(node)
|
||||
|
||||
if not (inputs or getattr(self, 'no_inputs', None)):
|
||||
raise Errors.WafError('command-output objects must have at least one input file or give self.no_inputs')
|
||||
if not (outputs or getattr(self, 'no_outputs', None)):
|
||||
raise Errors.WafError('command-output objects must have at least one output file or give self.no_outputs')
|
||||
|
||||
cwd = self.bld.variant_dir
|
||||
task = command_output(self.env, cmd, cmd_node, self.argv, stdin, stdout, cwd, self.os_env, stderr)
|
||||
task.generator = self
|
||||
copy_attrs(self, task, 'before after ext_in ext_out', only_if_set=True)
|
||||
self.tasks.append(task)
|
||||
|
||||
task.inputs = inputs
|
||||
task.outputs = outputs
|
||||
task.dep_vars = self.to_list(self.dep_vars)
|
||||
|
||||
for dep in self.dependencies:
|
||||
assert dep is not self
|
||||
dep.post()
|
||||
for dep_task in dep.tasks:
|
||||
task.set_run_after(dep_task)
|
||||
|
||||
if not task.inputs:
|
||||
# the case for svnversion, always run, and update the output nodes
|
||||
task.runnable_status = type(Task.TaskBase.run)(runnable_status, task, task.__class__) # always run
|
||||
task.post_run = type(Task.TaskBase.run)(post_run, task, task.__class__)
|
||||
|
||||
# TODO the case with no outputs?
|
||||
|
||||
def post_run(self):
|
||||
for x in self.outputs:
|
||||
x.sig = Utils.h_file(x.abspath())
|
||||
|
||||
def runnable_status(self):
|
||||
return self.RUN_ME
|
||||
|
||||
Task.task_factory('copy', vars=[], func=action_process_file_func)
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
import Options
|
||||
import Configure
|
||||
import pproc as subprocess
|
||||
import subprocess
|
||||
import config_c
|
||||
import sys
|
||||
|
||||
def detect(conf):
|
||||
def configure(conf):
|
||||
pkg_config = conf.find_program('pkg-config', var='PKG_CONFIG')
|
||||
if not pkg_config: return
|
||||
|
||||
@@ -19,25 +20,31 @@ def pkg_check_modules(conf, uselib_name, expression, mandatory=True):
|
||||
else:
|
||||
return False
|
||||
|
||||
if Options.options.verbose:
|
||||
extra_msg = ' (%s)' % expression
|
||||
else:
|
||||
extra_msg = ''
|
||||
|
||||
conf.start_msg('pkg-config flags for %s%s' % (uselib_name, extra_msg))
|
||||
|
||||
argv = [pkg_config, '--cflags', '--libs', expression]
|
||||
cmd = subprocess.Popen(argv, stdout=subprocess.PIPE)
|
||||
out, dummy = cmd.communicate()
|
||||
cmd = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
out, err = cmd.communicate()
|
||||
retval = cmd.wait()
|
||||
|
||||
msg_checking = ("pkg-config flags for %s" % (uselib_name,))
|
||||
if Options.options.verbose:
|
||||
if retval == 0:
|
||||
conf.check_message_custom(msg_checking,
|
||||
('(%s)' % expression), out)
|
||||
else:
|
||||
conf.check_message(msg_checking, ('(%s)' % expression), False)
|
||||
conf.to_log('%r: %r (exit code %i)\n%s' % (argv, out, retval, err))
|
||||
|
||||
if retval != 0:
|
||||
conf.end_msg(False)
|
||||
sys.stderr.write(err)
|
||||
else:
|
||||
conf.check_message(msg_checking, '', (retval == 0), '')
|
||||
conf.log.write('%r: %r (exit code %i)\n' % (argv, out, retval))
|
||||
if Options.options.verbose:
|
||||
conf.end_msg(out)
|
||||
else:
|
||||
conf.end_msg(True)
|
||||
|
||||
if retval == 0:
|
||||
|
||||
config_c.parse_flags(out, uselib_name, conf.env)
|
||||
conf.parse_flags(out, uselib_name, conf.env)
|
||||
conf.env[uselib_name] = True
|
||||
return True
|
||||
|
||||
|
||||
434
wscript
434
wscript
@@ -11,24 +11,21 @@ import shlex
|
||||
import textwrap
|
||||
|
||||
# WAF modules
|
||||
import pproc as subprocess
|
||||
import subprocess
|
||||
import Options
|
||||
|
||||
import Logs
|
||||
import TaskGen
|
||||
import Constants
|
||||
|
||||
import ccroot
|
||||
ccroot.USE_TOP_LEVEL = True
|
||||
|
||||
import Task
|
||||
Task.algotype = Constants.JOBCONTROL # so that Task.maxjobs=1 takes effect
|
||||
|
||||
import Utils
|
||||
import Build
|
||||
import Configure
|
||||
import Scripting
|
||||
|
||||
from waflib.Errors import WafError
|
||||
|
||||
from utils import read_config_file
|
||||
|
||||
# By default, all modules will be enabled, examples will be disabled,
|
||||
@@ -58,7 +55,7 @@ cflags.default_profile = 'debug'
|
||||
# local modules
|
||||
import wutils
|
||||
|
||||
Configure.autoconfig = 1
|
||||
Configure.autoconfig = 0
|
||||
|
||||
# the following two variables are used by the target "waf dist"
|
||||
VERSION = file("VERSION", "rt").read().strip()
|
||||
@@ -73,8 +70,8 @@ if sys.platform != 'darwin' and re.match(r"^\d+\.\d+(\.\d+)?$", VERSION) is not
|
||||
wutils.VNUM = VERSION
|
||||
|
||||
# these variables are mandatory ('/' are converted automatically)
|
||||
srcdir = '.'
|
||||
blddir = 'build'
|
||||
top = '.'
|
||||
out = 'build'
|
||||
|
||||
def load_env():
|
||||
bld_cls = getattr(Utils.g_module, 'build_context', Utils.Context)
|
||||
@@ -124,12 +121,12 @@ def print_module_names(names):
|
||||
if i != 1:
|
||||
print
|
||||
|
||||
def set_options(opt):
|
||||
def options(opt):
|
||||
# options provided by the modules
|
||||
opt.tool_options('compiler_cc')
|
||||
opt.tool_options('compiler_cxx')
|
||||
opt.tool_options('cflags')
|
||||
opt.tool_options('gnu_dirs')
|
||||
opt.load('compiler_c')
|
||||
opt.load('compiler_cxx')
|
||||
opt.load('cflags')
|
||||
opt.load('gnu_dirs')
|
||||
|
||||
opt.add_option('--cwd',
|
||||
help=('Set the working directory for a program.'),
|
||||
@@ -208,10 +205,6 @@ def set_options(opt):
|
||||
help=('Compile NS-3 statically: works only on linux, without python'),
|
||||
dest='enable_static', action='store_true',
|
||||
default=False)
|
||||
opt.add_option('--enable-shared-and-static',
|
||||
help=('Compile NS-3 both shared and static libraries at the same time: static works only on linux'),
|
||||
dest='enable_shared_and_static', action='store_true',
|
||||
default=False)
|
||||
opt.add_option('--enable-mpi',
|
||||
help=('Compile NS-3 with MPI and distributed simulation support'),
|
||||
dest='enable_mpi', action='store_true',
|
||||
@@ -234,6 +227,7 @@ def _check_compilation_flag(conf, flag, mode='cxx'):
|
||||
flag: can be a string or a list of strings
|
||||
"""
|
||||
|
||||
conf.start_msg('Checking for compilation flag %r support' % (flag,))
|
||||
env = conf.env.copy()
|
||||
if mode == 'cxx':
|
||||
fname = 'test.cc'
|
||||
@@ -244,26 +238,36 @@ def _check_compilation_flag(conf, flag, mode='cxx'):
|
||||
try:
|
||||
retval = conf.run_c_code(code='#include <stdio.h>\nint main() { return 0; }\n',
|
||||
env=env, compile_filename=fname,
|
||||
compile_mode=mode, type='cprogram', execute=False)
|
||||
compile_mode=mode, features='c cprogram', execute=False)
|
||||
except Configure.ConfigurationError:
|
||||
ok = False
|
||||
else:
|
||||
ok = (retval == 0)
|
||||
conf.check_message_custom(flag, 'support', (ok and 'yes' or 'no'))
|
||||
conf.end_msg(ok)
|
||||
return ok
|
||||
|
||||
|
||||
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))
|
||||
conf.env.append_value('NS3_OPTIONAL_FEATURES', [(name, caption, was_enabled, reason_not_enabled)])
|
||||
|
||||
|
||||
# starting with waf 1.6, conf.check() becomes fatal by default if the
|
||||
# test fails, this alternative method makes the test non-fatal, as it
|
||||
# was in waf <= 1.5
|
||||
def _check_nonfatal(conf, *args, **kwargs):
|
||||
try:
|
||||
return conf.check(*args, **kwargs)
|
||||
except conf.errors.ConfigurationError:
|
||||
return None
|
||||
|
||||
def configure(conf):
|
||||
# attach some extra methods
|
||||
conf.check_nonfatal = types.MethodType(_check_nonfatal, conf)
|
||||
conf.check_compilation_flag = types.MethodType(_check_compilation_flag, conf)
|
||||
conf.report_optional_feature = types.MethodType(report_optional_feature, conf)
|
||||
conf.env['NS3_OPTIONAL_FEATURES'] = []
|
||||
|
||||
conf.env['NS3_BUILDDIR'] = conf.blddir
|
||||
conf.check_tool('compiler_cc')
|
||||
conf.check_tool('compiler_c')
|
||||
conf.check_tool('compiler_cxx')
|
||||
conf.check_tool('cflags', ['waf-tools'])
|
||||
try:
|
||||
@@ -273,31 +277,19 @@ def configure(conf):
|
||||
conf.check_tool('command', ['waf-tools'])
|
||||
conf.check_tool('gnu_dirs')
|
||||
|
||||
#if os.path.exists('/usr/lib64'):
|
||||
# conf.env.LIBDIR = os.path.join(conf.env.PREFIX, "lib64")
|
||||
|
||||
# create the second environment, set the variant and set its name
|
||||
variant_env = conf.env.copy()
|
||||
variant_name = Options.options.build_profile
|
||||
env = conf.env
|
||||
|
||||
if Options.options.enable_gcov:
|
||||
variant_name += '-gcov'
|
||||
variant_env.append_value('CCFLAGS', '-fprofile-arcs')
|
||||
variant_env.append_value('CCFLAGS', '-ftest-coverage')
|
||||
variant_env.append_value('CXXFLAGS', '-fprofile-arcs')
|
||||
variant_env.append_value('CXXFLAGS', '-ftest-coverage')
|
||||
variant_env.append_value('LINKFLAGS', '-fprofile-arcs')
|
||||
|
||||
conf.env['NS3_ACTIVE_VARIANT'] = variant_name
|
||||
variant_env['NS3_ACTIVE_VARIANT'] = variant_name
|
||||
variant_env.set_variant(variant_name)
|
||||
conf.set_env_name(variant_name, variant_env)
|
||||
conf.setenv(variant_name)
|
||||
env = variant_env
|
||||
env['GCOV_ENABLED'] = True
|
||||
env.append_value('CCFLAGS', '-fprofile-arcs')
|
||||
env.append_value('CCFLAGS', '-ftest-coverage')
|
||||
env.append_value('CXXFLAGS', '-fprofile-arcs')
|
||||
env.append_value('CXXFLAGS', '-ftest-coverage')
|
||||
env.append_value('LINKFLAGS', '-fprofile-arcs')
|
||||
|
||||
if Options.options.build_profile == 'debug':
|
||||
env.append_value('CXXDEFINES', 'NS3_ASSERT_ENABLE')
|
||||
env.append_value('CXXDEFINES', 'NS3_LOG_ENABLE')
|
||||
env.append_value('DEFINES', 'NS3_ASSERT_ENABLE')
|
||||
env.append_value('DEFINES', 'NS3_LOG_ENABLE')
|
||||
|
||||
env['PLATFORM'] = sys.platform
|
||||
|
||||
@@ -325,15 +317,13 @@ def configure(conf):
|
||||
env['WL_SONAME_SUPPORTED'] = True
|
||||
|
||||
env['ENABLE_STATIC_NS3'] = False
|
||||
if Options.options.enable_static or Options.options.enable_shared_and_static:
|
||||
if Options.options.enable_static:
|
||||
if env['PLATFORM'].startswith('linux') and \
|
||||
env['CXX_NAME'] in ['gcc', 'icc']:
|
||||
if re.match('i[3-6]86', os.uname()[4]):
|
||||
conf.report_optional_feature("static", "Static build", True, '')
|
||||
if Options.options.enable_static:
|
||||
env['ENABLE_STATIC_NS3'] = True
|
||||
if Options.options.enable_shared_and_static:
|
||||
env['ENABLE_SHARED_AND_STATIC_NS3'] = True
|
||||
elif os.uname()[4] == 'x86_64':
|
||||
if env['ENABLE_PYTHON_BINDINGS'] and \
|
||||
not conf.check_compilation_flag('-mcmodel=large'):
|
||||
@@ -346,16 +336,12 @@ def configure(conf):
|
||||
conf.report_optional_feature("static", "Static build", True, '')
|
||||
if Options.options.enable_static:
|
||||
env['ENABLE_STATIC_NS3'] = True
|
||||
if Options.options.enable_shared_and_static:
|
||||
env['ENABLE_SHARED_AND_STATIC_NS3'] = True
|
||||
elif env['CXX_NAME'] == 'gcc' and \
|
||||
(env['PLATFORM'].startswith('darwin') or \
|
||||
env['PLATFORM'].startswith('cygwin')):
|
||||
conf.report_optional_feature("static", "Static build", True, '')
|
||||
if Options.options.enable_static:
|
||||
env['ENABLE_STATIC_NS3'] = True
|
||||
if Options.options.enable_shared_and_static:
|
||||
env['ENABLE_SHARED_AND_STATIC_NS3'] = True
|
||||
else:
|
||||
conf.report_optional_feature("static", "Static build", False,
|
||||
"Unsupported platform")
|
||||
@@ -395,7 +381,7 @@ def configure(conf):
|
||||
if not_built_name in conf.env['NS3_ENABLED_MODULES']:
|
||||
conf.env['NS3_ENABLED_MODULES'].remove(not_built_name)
|
||||
if not conf.env['NS3_ENABLED_MODULES']:
|
||||
raise Utils.WafError('Exiting because the ' + not_built + ' module can not be built and it was the only one enabled.')
|
||||
raise WafError('Exiting because the ' + not_built + ' module can not be built and it was the only one enabled.')
|
||||
|
||||
conf.sub_config('bindings/python')
|
||||
|
||||
@@ -483,12 +469,10 @@ def configure(conf):
|
||||
conf.env['ENABLE_GSL'],
|
||||
"GSL not found")
|
||||
if have_gsl:
|
||||
conf.env.append_value('CXXDEFINES', "ENABLE_GSL")
|
||||
conf.env.append_value('CCDEFINES', "ENABLE_GSL")
|
||||
conf.env.append_value('DEFINES', "ENABLE_GSL")
|
||||
|
||||
# for compiling C code, copy over the CXX* flags
|
||||
conf.env.append_value('CCFLAGS', conf.env['CXXFLAGS'])
|
||||
conf.env.append_value('CCDEFINES', conf.env['CXXDEFINES'])
|
||||
|
||||
def add_gcc_flag(flag):
|
||||
if env['COMPILER_CXX'] == 'g++' and 'CXXFLAGS' not in os.environ:
|
||||
@@ -502,7 +486,10 @@ def configure(conf):
|
||||
add_gcc_flag('-fstrict-aliasing')
|
||||
add_gcc_flag('-Wstrict-aliasing')
|
||||
|
||||
conf.find_program('doxygen', var='DOXYGEN')
|
||||
try:
|
||||
conf.find_program('doxygen', var='DOXYGEN')
|
||||
except WafError:
|
||||
pass
|
||||
|
||||
# append user defined flags after all our ones
|
||||
for (confvar, envvar) in [['CCFLAGS', 'CCFLAGS_EXTRA'],
|
||||
@@ -522,23 +509,20 @@ def configure(conf):
|
||||
status = 'not enabled (%s)' % reason_not_enabled
|
||||
print "%-30s: %s" % (caption, status)
|
||||
|
||||
class SuidBuildTask(Task.TaskBase):
|
||||
|
||||
class SuidBuild_task(Task.TaskBase):
|
||||
"""task that makes a binary Suid
|
||||
"""
|
||||
after = 'cxx_link cc_link'
|
||||
maxjobs = 1
|
||||
def __init__(self, bld, program):
|
||||
self.bld = bld
|
||||
after = 'link'
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SuidBuild_task, self).__init__(*args, **kwargs)
|
||||
self.m_display = 'build-suid'
|
||||
self.__program = program
|
||||
self.__env = bld.env.copy ()
|
||||
super(SuidBuildTask, self).__init__(generator=self)
|
||||
try:
|
||||
program_obj = wutils.find_program(self.__program.target, self.__env)
|
||||
program_obj = wutils.find_program(self.generator.target, self.generator.env)
|
||||
except ValueError, ex:
|
||||
raise Utils.WafError(str(ex))
|
||||
program_node = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj))
|
||||
self.filename = program_node.abspath(self.__env)
|
||||
raise WafError(str(ex))
|
||||
program_node = program_obj.path.find_or_declare(program_obj.target)
|
||||
self.filename = program_node.abspath()
|
||||
|
||||
|
||||
def run(self):
|
||||
@@ -553,38 +537,49 @@ class SuidBuildTask(Task.TaskBase):
|
||||
"RUN_ME SKIP_ME or ASK_LATER"
|
||||
st = os.stat(self.filename)
|
||||
if st.st_uid == 0:
|
||||
return Constants.SKIP_ME
|
||||
return Task.SKIP_ME
|
||||
else:
|
||||
return Constants.RUN_ME
|
||||
|
||||
return Task.RUN_ME
|
||||
|
||||
def create_suid_program(bld, name):
|
||||
program = bld.new_task_gen('cxx', 'program')
|
||||
grp = bld.current_group
|
||||
bld.add_group() # this to make sure no two sudo tasks run at the same time
|
||||
program = bld.new_task_gen(features=['cxx', 'cxxprogram'])
|
||||
program.is_ns3_program = True
|
||||
program.module_deps = list()
|
||||
program.name = name
|
||||
program.target = name
|
||||
|
||||
if bld.env['ENABLE_SUDO']:
|
||||
SuidBuildTask(bld, program)
|
||||
program.create_task("SuidBuild")
|
||||
|
||||
bld.set_group(grp)
|
||||
|
||||
return program
|
||||
|
||||
def create_ns3_program(bld, name, dependencies=('core',)):
|
||||
program = bld.new_task_gen('cxx', 'program')
|
||||
program = bld.new_task_gen(features=['cxx', 'cxxprogram'])
|
||||
program.is_ns3_program = True
|
||||
program.name = name
|
||||
program.target = program.name
|
||||
# Each of the modules this program depends on has its own library.
|
||||
program.ns3_module_dependencies = ['ns3-'+dep for dep in dependencies]
|
||||
program.includes = "# #/.."
|
||||
program.use = program.ns3_module_dependencies
|
||||
if program.env['ENABLE_STATIC_NS3']:
|
||||
if sys.platform == 'darwin':
|
||||
program.env.STLIB_MARKER = '-Wl,-all_load'
|
||||
else:
|
||||
program.env.STLIB_MARKER = '-Wl,--whole-archive,-Bstatic'
|
||||
program.env.SHLIB_MARKER = '-Wl,-Bdynamic,--no-whole-archive'
|
||||
return program
|
||||
|
||||
def register_ns3_script(bld, name, dependencies=('core',)):
|
||||
ns3_module_dependencies = ['ns3-'+dep for dep in dependencies]
|
||||
bld.env.append_value('NS3_SCRIPT_DEPENDENCIES', (name, ns3_module_dependencies))
|
||||
bld.env.append_value('NS3_SCRIPT_DEPENDENCIES', [(name, ns3_module_dependencies)])
|
||||
|
||||
def add_examples_programs(bld):
|
||||
env = bld.env_of_name('default')
|
||||
env = bld.env
|
||||
if env['ENABLE_EXAMPLES']:
|
||||
for dir in os.listdir('examples'):
|
||||
if dir.startswith('.') or dir == 'CVS':
|
||||
@@ -613,23 +608,30 @@ def add_scratch_programs(bld):
|
||||
obj.name = obj.target
|
||||
|
||||
|
||||
def _add_ns3_program_missing_deps(bld, program):
|
||||
deps_found = program.ns3_module_dependencies
|
||||
program.uselib_local = getattr(program, "uselib_local", []) + [dep + "--lib" for dep in deps_found]
|
||||
if program.env['ENABLE_STATIC_NS3'] and not program.env['ENABLE_SHARED_AND_STATIC_NS3']:
|
||||
if sys.platform == 'darwin':
|
||||
program.env.append_value('LINKFLAGS', '-Wl,-all_load')
|
||||
for dep in deps_found:
|
||||
program.env.append_value('LINKFLAGS', '-l' + dep)
|
||||
else:
|
||||
program.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic')
|
||||
for dep in deps_found:
|
||||
program.env.append_value('LINKFLAGS', '-l' + dep)
|
||||
program.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive')
|
||||
def _get_all_task_gen(self):
|
||||
for group in self.groups:
|
||||
for taskgen in group:
|
||||
yield taskgen
|
||||
|
||||
|
||||
# ok, so WAF does not provide an API to prevent an
|
||||
# arbitrary taskgen from running; we have to muck around with
|
||||
# WAF internal state, something that might stop working if
|
||||
# WAF is upgraded...
|
||||
def _exclude_taskgen(self, taskgen):
|
||||
for group in self.groups:
|
||||
for tg1 in group:
|
||||
if tg1 is taskgen:
|
||||
group.remove(tg1)
|
||||
break
|
||||
else:
|
||||
continue
|
||||
break
|
||||
|
||||
|
||||
def build(bld):
|
||||
env = bld.env
|
||||
|
||||
# If --enabled-modules option was given, then print a warning
|
||||
# message and exit this function.
|
||||
if Options.options.enable_modules:
|
||||
@@ -653,17 +655,12 @@ def build(bld):
|
||||
bld.create_ns3_program = types.MethodType(create_ns3_program, bld)
|
||||
bld.register_ns3_script = types.MethodType(register_ns3_script, 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.all_envs['default'] = variant_env
|
||||
bld.__class__.all_task_gen = property(_get_all_task_gen)
|
||||
bld.exclude_taskgen = types.MethodType(_exclude_taskgen, bld)
|
||||
|
||||
# process subfolders from here
|
||||
bld.add_subdirs('src')
|
||||
|
||||
env = bld.env
|
||||
|
||||
# If modules have been enabled, then set lists of enabled modules
|
||||
# and enabled module test libraries.
|
||||
if env['NS3_ENABLED_MODULES']:
|
||||
@@ -675,11 +672,11 @@ def build(bld):
|
||||
while changed:
|
||||
changed = False
|
||||
for module in modules:
|
||||
module_obj = bld.name_to_obj(module, env)
|
||||
module_obj = bld.get_tgen_by_name(module)
|
||||
if module_obj is None:
|
||||
raise ValueError("module %s not found" % module)
|
||||
# Each enabled module has its own library.
|
||||
for dep in module_obj.uselib_local:
|
||||
for dep in module_obj.use:
|
||||
if not dep.startswith('ns3-'):
|
||||
continue
|
||||
if dep not in modules:
|
||||
@@ -701,25 +698,11 @@ def build(bld):
|
||||
if env['NS3_ENABLED_MODULES']:
|
||||
modules = env['NS3_ENABLED_MODULES']
|
||||
|
||||
def exclude_taskgen(bld, taskgen):
|
||||
# ok, so WAF does not provide an API to prevent an
|
||||
# arbitrary taskgen from running; we have to muck around with
|
||||
# WAF internal state, something that might stop working if
|
||||
# WAF is upgraded...
|
||||
bld.all_task_gen.remove(taskgen)
|
||||
for group in bld.task_manager.groups:
|
||||
try:
|
||||
group.tasks_gen.remove(taskgen)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
||||
# Exclude the programs other misc task gens that depend on disabled modules
|
||||
for obj in list(bld.all_task_gen):
|
||||
|
||||
# check for ns3moduleheader_taskgen
|
||||
if type(obj).__name__ == 'ns3moduleheader_taskgen':
|
||||
if 'ns3moduleheader' in getattr(obj, "features", []):
|
||||
if ("ns3-%s" % obj.module) not in modules:
|
||||
obj.mode = 'remove' # tell it to remove headers instead of installing
|
||||
|
||||
@@ -729,7 +712,7 @@ def build(bld):
|
||||
program_built = True
|
||||
for dep in obj.ns3_module_dependencies:
|
||||
if dep not in modules: # prog. depends on a module that isn't enabled?
|
||||
exclude_taskgen(bld, obj)
|
||||
bld.exclude_taskgen(obj)
|
||||
program_built = False
|
||||
break
|
||||
|
||||
@@ -740,15 +723,15 @@ def build(bld):
|
||||
|
||||
# disable the modules themselves
|
||||
if hasattr(obj, "is_ns3_module") and obj.name not in modules:
|
||||
exclude_taskgen(bld, obj) # kill the module
|
||||
bld.exclude_taskgen(obj) # kill the module
|
||||
|
||||
# disable the module test libraries
|
||||
if hasattr(obj, "is_ns3_module_test_library"):
|
||||
if not env['ENABLE_TESTS'] or (obj.module_name not in modules):
|
||||
exclude_taskgen(bld, obj) # kill the module test library
|
||||
bld.exclude_taskgen(obj) # kill the module test library
|
||||
|
||||
# disable the ns3header_taskgen
|
||||
if type(obj).__name__ == 'ns3header_taskgen':
|
||||
if 'ns3header' in getattr(obj, "features", []):
|
||||
if ("ns3-%s" % obj.module) not in modules:
|
||||
obj.mode = 'remove' # tell it to remove headers instead of installing
|
||||
|
||||
@@ -770,35 +753,10 @@ def build(bld):
|
||||
|
||||
bld.add_subdirs('bindings/python')
|
||||
|
||||
## do a topological sort on the modules graph
|
||||
dep_graph = []
|
||||
for gen in bld.all_task_gen:
|
||||
if type(gen).__name__ in ['ns3module_taskgen']:
|
||||
for dep in gen.dependencies:
|
||||
dep_graph.append(("ns3-"+dep, gen.name))
|
||||
dep_graph.sort()
|
||||
sys.path.insert(0, "bindings/python")
|
||||
from topsort import topsort
|
||||
sorted_ns3_modules = topsort(dep_graph)
|
||||
#print sorted_ns3_modules
|
||||
|
||||
# we need to post() the ns3 modules, so they create libraries underneath, and programs can list them in uselib_local
|
||||
for module in sorted_ns3_modules:
|
||||
gen = bld.name_to_obj(module, bld.env)
|
||||
if type(gen).__name__ in ['ns3module_taskgen']:
|
||||
gen.post()
|
||||
for lib in gen.libs:
|
||||
lib.post()
|
||||
|
||||
# Process this subfolder here after the lists of enabled modules
|
||||
# and module test libraries have been set.
|
||||
bld.add_subdirs('utils')
|
||||
|
||||
for gen in bld.all_task_gen:
|
||||
if not getattr(gen, "is_ns3_program", False) or not hasattr(gen, "ns3_module_dependencies"):
|
||||
continue
|
||||
_add_ns3_program_missing_deps(bld, gen)
|
||||
|
||||
if Options.options.run:
|
||||
# Check that the requested program name is valid
|
||||
program_name, dummy_program_argv = wutils.get_run_program(Options.options.run, wutils.get_command_template(env))
|
||||
@@ -806,7 +764,7 @@ def build(bld):
|
||||
# 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.
|
||||
Options.options.compile_targets += ',' + os.path.basename(program_name)
|
||||
Options.options.targets += ',' + os.path.basename(program_name)
|
||||
for gen in bld.all_task_gen:
|
||||
if type(gen).__name__ in ['ns3header_taskgen', 'ns3moduleheader_taskgen']:
|
||||
gen.post()
|
||||
@@ -815,6 +773,8 @@ def build(bld):
|
||||
_doxygen(bld)
|
||||
raise SystemExit(0)
|
||||
|
||||
|
||||
|
||||
def shutdown(ctx):
|
||||
bld = wutils.bld
|
||||
if wutils.bld is None:
|
||||
@@ -826,9 +786,9 @@ def shutdown(ctx):
|
||||
# clean.
|
||||
if ((not Options.options.run)
|
||||
and (not Options.options.pyrun)
|
||||
and ('clean' not in Options.arg_line)
|
||||
and ('distclean' not in Options.arg_line)
|
||||
and ('shell' not in Options.arg_line)):
|
||||
and ('clean' not in Options.commands)
|
||||
and ('distclean' not in Options.commands)
|
||||
and ('shell' not in Options.commands)):
|
||||
|
||||
# Print the list of built modules.
|
||||
print
|
||||
@@ -844,7 +804,7 @@ def shutdown(ctx):
|
||||
print
|
||||
|
||||
# Write the build status file.
|
||||
build_status_file = os.path.join (env['NS3_BUILDDIR'], env['NS3_ACTIVE_VARIANT'], 'build-status.py')
|
||||
build_status_file = os.path.join(bld.out_dir, 'build-status.py')
|
||||
out = open(build_status_file, 'w')
|
||||
out.write('#! /usr/bin/env python\n')
|
||||
out.write('\n')
|
||||
@@ -857,7 +817,7 @@ def shutdown(ctx):
|
||||
out.close()
|
||||
|
||||
if Options.options.lcov_report:
|
||||
lcov_report()
|
||||
lcov_report(bld)
|
||||
|
||||
if Options.options.run:
|
||||
wutils.run_program(Options.options.run, env, wutils.get_command_template(env),
|
||||
@@ -870,22 +830,23 @@ def shutdown(ctx):
|
||||
raise SystemExit(0)
|
||||
|
||||
if Options.options.shell:
|
||||
raise Utils.WafError("Please run `./waf shell' now, instead of `./waf --shell'")
|
||||
raise WafError("Please run `./waf shell' now, instead of `./waf --shell'")
|
||||
|
||||
if Options.options.check:
|
||||
raise Utils.WafError("Please run `./test.py' now, instead of `./waf --check'")
|
||||
raise WafError("Please run `./test.py' now, instead of `./waf --check'")
|
||||
|
||||
check_shell(bld)
|
||||
|
||||
check_context = Build.BuildContext
|
||||
|
||||
check_context = Build.BuildContext
|
||||
def check(bld):
|
||||
"""run the equivalent of the old ns-3 unit tests using test.py"""
|
||||
env = wutils.bld.env
|
||||
wutils.run_python_program("test.py -n -c core", env)
|
||||
|
||||
|
||||
class print_introspected_doxygen_task(Task.TaskBase):
|
||||
after = 'cc cxx cc_link cxx_link'
|
||||
after = 'cc cxx link'
|
||||
color = 'BLUE'
|
||||
|
||||
def __init__(self, bld):
|
||||
@@ -916,7 +877,7 @@ class print_introspected_doxygen_task(Task.TaskBase):
|
||||
out.close()
|
||||
|
||||
class run_python_unit_tests_task(Task.TaskBase):
|
||||
after = 'cc cxx cc_link cxx_link'
|
||||
after = 'cc cxx link'
|
||||
color = 'BLUE'
|
||||
|
||||
def __init__(self, bld):
|
||||
@@ -952,24 +913,34 @@ def check_shell(bld):
|
||||
"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")
|
||||
raise Utils.WafError(msg)
|
||||
raise WafError(msg)
|
||||
|
||||
|
||||
shell_context = Build.BuildContext
|
||||
def shell(ctx):
|
||||
from waflib import Context, Build
|
||||
class Ns3ShellContext(Context.Context):
|
||||
"""run a shell with an environment suitably modified to run locally built programs"""
|
||||
cmd = 'shell'
|
||||
|
||||
#make sure we build first"
|
||||
Scripting.build(ctx)
|
||||
def execute(self):
|
||||
|
||||
if sys.platform == 'win32':
|
||||
shell = os.environ.get("COMSPEC", "cmd.exe")
|
||||
else:
|
||||
shell = os.environ.get("SHELL", "/bin/sh")
|
||||
# first we execute the build
|
||||
bld = Context.create_context("build")
|
||||
bld.options = Options.options # provided for convenience
|
||||
bld.cmd = "build"
|
||||
bld.execute()
|
||||
|
||||
if sys.platform == 'win32':
|
||||
shell = os.environ.get("COMSPEC", "cmd.exe")
|
||||
else:
|
||||
shell = os.environ.get("SHELL", "/bin/sh")
|
||||
|
||||
env = bld.env
|
||||
os_env = {
|
||||
'NS3_MODULE_PATH': os.pathsep.join(env['NS3_MODULE_PATH']),
|
||||
'NS3_EXECUTABLE_PATH': os.pathsep.join(env['NS3_EXECUTABLE_PATH']),
|
||||
}
|
||||
wutils.run_argv([shell], env, os_env)
|
||||
|
||||
env = wutils.bld.env
|
||||
os_env = {'NS3_MODULE_PATH': os.pathsep.join(env['NS3_MODULE_PATH']), 'NS3_EXECUTABLE_PATH': os.pathsep.join(env['NS3_EXECUTABLE_PATH'])}
|
||||
wutils.run_argv([shell], env, os_env)
|
||||
|
||||
def _doxygen(bld):
|
||||
env = wutils.bld.env
|
||||
@@ -1010,28 +981,26 @@ def doxygen(bld):
|
||||
Scripting.build(bld)
|
||||
_doxygen(bld)
|
||||
|
||||
def lcov_report():
|
||||
env = Build.bld.env
|
||||
variant_name = env['NS3_ACTIVE_VARIANT']
|
||||
def lcov_report(bld):
|
||||
env = bld.env
|
||||
|
||||
if 'gcov' not in variant_name:
|
||||
raise Utils.WafError("project not configured for code coverage;"
|
||||
" reconfigure with --enable-gcov")
|
||||
if not env['GCOV_ENABLED']:
|
||||
raise WafError("project not configured for code coverage;"
|
||||
" reconfigure with --enable-gcov")
|
||||
|
||||
os.chdir(blddir)
|
||||
os.chdir(out)
|
||||
try:
|
||||
lcov_report_dir = os.path.join(variant_name, 'lcov-report')
|
||||
lcov_report_dir = 'lcov-report'
|
||||
create_dir_command = "rm -rf " + lcov_report_dir
|
||||
create_dir_command += " && mkdir " + lcov_report_dir + ";"
|
||||
|
||||
if subprocess.Popen(create_dir_command, shell=True).wait():
|
||||
raise SystemExit(1)
|
||||
|
||||
info_file = os.path.join(lcov_report_dir, variant_name + '.info')
|
||||
info_file = os.path.join(lcov_report_dir, 'report.info')
|
||||
lcov_command = "../utils/lcov/lcov -c -d . -o " + info_file
|
||||
lcov_command += " --source-dirs=" + os.getcwd()
|
||||
lcov_command += ":" + os.path.join(
|
||||
os.getcwd(), variant_name, 'include')
|
||||
lcov_command += ":" + os.path.join(os.getcwd(), 'include')
|
||||
if subprocess.Popen(lcov_command, shell=True).wait():
|
||||
raise SystemExit(1)
|
||||
|
||||
@@ -1042,116 +1011,3 @@ def lcov_report():
|
||||
finally:
|
||||
os.chdir("..")
|
||||
|
||||
##
|
||||
## The default WAF DistDir implementation is rather slow, because it
|
||||
## first copies everything and only later removes unwanted files and
|
||||
## directories; this means that it needless copies the full build dir
|
||||
## and the .hg repository tree. Here we provide a replacement DistDir
|
||||
## implementation that is more efficient.
|
||||
##
|
||||
import Scripting
|
||||
from Scripting import dist_exts, excludes, BLDDIR
|
||||
import Utils
|
||||
import os
|
||||
|
||||
def _copytree(src, dst, symlinks=False, excludes=(), build_dir=None):
|
||||
"""Recursively copy a directory tree using copy2().
|
||||
|
||||
The destination directory must not already exist.
|
||||
If exception(s) occur, an Error is raised with a list of reasons.
|
||||
|
||||
If the optional symlinks flag is true, symbolic links in the
|
||||
source tree result in symbolic links in the destination tree; if
|
||||
it is false, the contents of the files pointed to by symbolic
|
||||
links are copied.
|
||||
|
||||
XXX Consider this example code rather than the ultimate tool.
|
||||
|
||||
Note: this is a modified version of shutil.copytree from python
|
||||
2.5.2 library; modified for WAF purposes to exclude dot dirs and
|
||||
another list of files.
|
||||
"""
|
||||
names = os.listdir(src)
|
||||
os.makedirs(dst)
|
||||
errors = []
|
||||
for name in names:
|
||||
srcname = os.path.join(src, name)
|
||||
dstname = os.path.join(dst, name)
|
||||
try:
|
||||
if symlinks and os.path.islink(srcname):
|
||||
linkto = os.readlink(srcname)
|
||||
os.symlink(linkto, dstname)
|
||||
elif os.path.isdir(srcname):
|
||||
if name in excludes:
|
||||
continue
|
||||
elif name.startswith('.') or name.startswith(',,') or name.startswith('++') or name.startswith('CVS'):
|
||||
continue
|
||||
elif name == build_dir:
|
||||
continue
|
||||
else:
|
||||
## build_dir is not passed into the recursive
|
||||
## copytree, but that is intentional; it is a
|
||||
## directory name valid only at the top level.
|
||||
copytree(srcname, dstname, symlinks, excludes)
|
||||
else:
|
||||
ends = name.endswith
|
||||
to_remove = False
|
||||
if name.startswith('.') or name.startswith('++'):
|
||||
to_remove = True
|
||||
else:
|
||||
for x in dist_exts:
|
||||
if ends(x):
|
||||
to_remove = True
|
||||
break
|
||||
if not to_remove:
|
||||
shutil.copy2(srcname, dstname)
|
||||
# XXX What about devices, sockets etc.?
|
||||
except (IOError, os.error), why:
|
||||
errors.append((srcname, dstname, str(why)))
|
||||
# catch the Error from the recursive copytree so that we can
|
||||
# continue with other files
|
||||
except shutil.Error, err:
|
||||
errors.extend(err.args[0])
|
||||
try:
|
||||
shutil.copystat(src, dst)
|
||||
except WindowsError:
|
||||
# can't copy file access times on Windows
|
||||
pass
|
||||
except OSError, why:
|
||||
errors.extend((src, dst, str(why)))
|
||||
if errors:
|
||||
raise shutil.Error, errors
|
||||
|
||||
|
||||
def DistDir(appname, version):
|
||||
#"make a distribution directory with all the sources in it"
|
||||
import shutil
|
||||
|
||||
# Our temporary folder where to put our files
|
||||
TMPFOLDER=appname+'-'+version
|
||||
|
||||
# Remove an old package directory
|
||||
if os.path.exists(TMPFOLDER): shutil.rmtree(TMPFOLDER)
|
||||
|
||||
global g_dist_exts, g_excludes
|
||||
|
||||
# Remove the Build dir
|
||||
build_dir = getattr(Utils.g_module, BLDDIR, None)
|
||||
|
||||
# Copy everything into the new folder
|
||||
_copytree('.', TMPFOLDER, excludes=excludes, build_dir=build_dir)
|
||||
|
||||
# TODO undocumented hook
|
||||
dist_hook = getattr(Utils.g_module, 'dist_hook', None)
|
||||
if dist_hook:
|
||||
os.chdir(TMPFOLDER)
|
||||
try:
|
||||
dist_hook()
|
||||
finally:
|
||||
# go back to the root directory
|
||||
os.chdir('..')
|
||||
return TMPFOLDER
|
||||
|
||||
Scripting.DistDir = DistDir
|
||||
|
||||
|
||||
|
||||
35
wutils.py
35
wutils.py
@@ -1,18 +1,17 @@
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
import pproc as subprocess
|
||||
import subprocess
|
||||
import shlex
|
||||
|
||||
# WAF modules
|
||||
import ccroot
|
||||
import Options
|
||||
import Utils
|
||||
import Logs
|
||||
import TaskGen
|
||||
import Build
|
||||
import re
|
||||
|
||||
from waflib.Errors import WafError
|
||||
|
||||
# these are set from the main wscript file
|
||||
APPNAME=None
|
||||
@@ -48,10 +47,10 @@ else:
|
||||
return os.path.curdir
|
||||
return os.path.join(*rel_list)
|
||||
|
||||
|
||||
from waflib import Context
|
||||
def find_program(program_name, env):
|
||||
launch_dir = os.path.abspath(Options.cwd_launch)
|
||||
top_dir = os.path.abspath(Options.launch_dir)
|
||||
launch_dir = os.path.abspath(Context.launch_dir)
|
||||
#top_dir = os.path.abspath(Options.cwd_launch)
|
||||
found_programs = []
|
||||
for obj in bld.all_task_gen:
|
||||
if not getattr(obj, 'is_ns3_program', False):
|
||||
@@ -63,7 +62,7 @@ def find_program(program_name, env):
|
||||
continue
|
||||
|
||||
name1 = obj.target
|
||||
name2 = os.path.join(relpath(obj.path.abspath(), top_dir), obj.target)
|
||||
name2 = os.path.join(relpath(obj.path.abspath(), launch_dir), obj.target)
|
||||
names = [name1, name2]
|
||||
found_programs.extend(names)
|
||||
if program_name in names:
|
||||
@@ -99,7 +98,7 @@ def get_proc_env(os_env=None):
|
||||
else:
|
||||
proc_env[pathvar] = os.pathsep.join(list(env['NS3_MODULE_PATH']))
|
||||
|
||||
pymoddir = bld.path.find_dir('bindings/python').abspath(env)
|
||||
pymoddir = bld.path.find_dir('bindings/python').get_bld().abspath()
|
||||
pyvizdir = bld.path.find_dir('src/visualizer').abspath()
|
||||
if 'PYTHONPATH' in proc_env:
|
||||
proc_env['PYTHONPATH'] = os.pathsep.join([pymoddir, pyvizdir] + [proc_env['PYTHONPATH']])
|
||||
@@ -117,9 +116,9 @@ def run_argv(argv, env, os_env=None, cwd=None, force_no_valgrind=False):
|
||||
proc_env = get_proc_env(os_env)
|
||||
if Options.options.valgrind and not force_no_valgrind:
|
||||
if Options.options.command_template:
|
||||
raise Utils.WafError("Options --command-template and --valgrind are conflicting")
|
||||
raise WafError("Options --command-template and --valgrind are conflicting")
|
||||
if not env['VALGRIND']:
|
||||
raise Utils.WafError("valgrind is not installed")
|
||||
raise WafError("valgrind is not installed")
|
||||
argv = [env['VALGRIND'], "--leak-check=full", "--show-reachable=yes", "--error-exitcode=1"] + argv
|
||||
proc = subprocess.Popen(argv, env=proc_env, cwd=cwd, stderr=subprocess.PIPE)
|
||||
error = False
|
||||
@@ -139,7 +138,7 @@ def run_argv(argv, env, os_env=None, cwd=None, force_no_valgrind=False):
|
||||
try:
|
||||
retval = subprocess.Popen(argv, env=proc_env, cwd=cwd).wait()
|
||||
except WindowsError, ex:
|
||||
raise Utils.WafError("Command %s raised exception %s" % (argv, ex))
|
||||
raise WafError("Command %s raised exception %s" % (argv, ex))
|
||||
if retval:
|
||||
signame = None
|
||||
if retval < 0: # signal?
|
||||
@@ -150,11 +149,11 @@ def run_argv(argv, env, os_env=None, cwd=None, force_no_valgrind=False):
|
||||
signame = name
|
||||
break
|
||||
if signame:
|
||||
raise Utils.WafError("Command %s terminated with signal %s."
|
||||
raise WafError("Command %s terminated with signal %s."
|
||||
" Run it under a debugger to get more information "
|
||||
"(./waf --run <program> --command-template=\"gdb --args %%s <args>\")." % (argv, signame))
|
||||
else:
|
||||
raise Utils.WafError("Command %s exited with code %i" % (argv, retval))
|
||||
raise WafError("Command %s exited with code %i" % (argv, retval))
|
||||
return retval
|
||||
|
||||
def get_run_program(program_string, command_template=None):
|
||||
@@ -173,15 +172,15 @@ def get_run_program(program_string, command_template=None):
|
||||
try:
|
||||
program_obj = find_program(program_name, env)
|
||||
except ValueError, ex:
|
||||
raise Utils.WafError(str(ex))
|
||||
raise WafError(str(ex))
|
||||
|
||||
program_node = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj))
|
||||
program_node = program_obj.path.find_or_declare(program_obj.target)
|
||||
#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:]
|
||||
execvec = [program_node.abspath()] + argv[1:]
|
||||
|
||||
else:
|
||||
|
||||
@@ -189,9 +188,9 @@ def get_run_program(program_string, command_template=None):
|
||||
try:
|
||||
program_obj = find_program(program_name, env)
|
||||
except ValueError, ex:
|
||||
raise Utils.WafError(str(ex))
|
||||
raise WafError(str(ex))
|
||||
|
||||
program_node = program_obj.path.find_or_declare(ccroot.get_target_name(program_obj))
|
||||
program_node = program_obj.path.find_or_declare(program_obj.target)
|
||||
#try:
|
||||
# program_node = program_obj.path.find_build(ccroot.get_target_name(program_obj))
|
||||
#except AttributeError:
|
||||
|
||||
Reference in New Issue
Block a user