--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ns3waf/__init__.py Mon Apr 11 13:27:31 2011 +0200
@@ -0,0 +1,374 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+import waflib
+
+def options(opt):
+ opt.tool_options('compiler_cc')
+ opt.tool_options('compiler_cxx')
+ opt.add_option('--enable-static',
+ help=('Compile module statically: works only on linux, without python'),
+ dest='enable_static', action='store_true',
+ default=False)
+ opt.add_option('--disable-log',
+ help=('Do not compile into the code the log output instructions.'),
+ dest='enable_log', action='store_false',
+ default=True)
+ opt.add_option('--disable-assert',
+ help='Do not compile into the code the assert checks.',
+ dest='enable_assert', action='store_false',
+ default=True)
+ opt.add_option('--enable-gcov',
+ help='Enable code coverage collection.',
+ dest='enable_gcov', action='store_true',
+ default=False)
+ opt.add_option('--disable-examples', help='Disable compilation of examples',
+ dest='enable_examples', action='store_false',
+ default=True)
+ opt.add_option('--disable-tests', help='Disable compilation of tests',
+ dest='enable_tests', action='store_false',
+ default=True)
+
+def _report_optional_feature(conf, name, caption, was_enabled, reason_not_enabled):
+ if not 'NS3_OPTIONAL_FEATURES' in conf.env:
+ conf.env['NS3_OPTIONAL_FEATURES'] = []
+ conf.env['NS3_OPTIONAL_FEATURES'].append((name, caption, was_enabled, reason_not_enabled))
+
+
+def _check_compilation_flag(conf, flag, mode='cxx'):
+ """
+ Checks if the C++ compiler accepts a certain compilation flag or flags
+ flag: can be a string or a list of strings
+ """
+ try:
+ if mode == 'cxx':
+ conf.check_cc(fragment='#include <stdio.h>\nint main() { return 0; }\n',
+ cflags=flag,
+ execute = False, msg = "Checking for %s" % flag)
+ else:
+ conf.check_cxx(fragment='#include <stdio.h>\nint main() { return 0; }\n',
+ cxxflags=flag,
+ execute = False, msg = "Checking for %s" % flag)
+
+ except conf.errors.ConfigurationError:
+ ok = False
+ else:
+ ok = True
+ return ok
+
+
+def _print_optional_features(conf):
+ # Write a summary of optional features status
+ print "---- Summary of optional NS-3 features:"
+ for (name, caption, was_enabled, reason_not_enabled) in conf.env['NS3_OPTIONAL_FEATURES']:
+ if was_enabled:
+ status = 'enabled'
+ else:
+ status = 'not enabled (%s)' % reason_not_enabled
+ print "%-30s: %s" % (caption, status)
+
+def _check_static(conf):
+ import Options
+ import sys
+ import re
+ import os
+ env = conf.env
+ env['NS3_ENABLE_STATIC'] = False
+ if Options.options.enable_static:
+ if sys.platform.startswith('linux') and \
+ env['CXX_NAME'] in ['gcc', 'icc']:
+ if re.match('i[3-6]86', os.uname()[4]):
+ _report_optional_feature(conf, "static", "Static build", True, '')
+ env['NS3_ENABLE_STATIC'] = True
+ elif os.uname()[4] == 'x86_64':
+ if env['NS3_ENABLE_PYTHON_BINDINGS'] and \
+ not _check_compilation_flag(conf, '-mcmodel=large'):
+ _report_optional_feature(conf, "static", "Static build", False,
+ "Can't enable static builds because " + \
+ "no -mcmodel=large compiler " \
+ "option. Try --disable-python or upgrade your " \
+ "compiler to at least gcc 4.3.x.")
+ else:
+ _report_optional_feature(conf, "static", "Static build", True, '')
+ env['NS3_ENABLE_STATIC'] = True
+ elif env['CXX_NAME'] == 'gcc' and \
+ (sys.platform.startswith('darwin') or \
+ sys.platform.startswith('cygwin')):
+ _report_optional_feature(conf, "static", "Static build", True, '')
+ env['NS3_ENABLE_STATIC'] = True
+ else:
+ _report_optional_feature(conf, "static", "Static build", False,
+ "Unsupported platform")
+ else:
+ _report_optional_feature(conf, "static", "Static build", False,
+ "option --enable-static not selected")
+ # These flags are used for the implicitly dependent modules.
+ if env['NS3_ENABLE_STATIC']:
+ if sys.platform == 'darwin':
+ env['STLIB_MARKER'] = '-Wl,-all_load'
+ else:
+ env['STLIB_MARKER'] = '-Wl,--whole-archive,-Bstatic'
+ env['SHLIB_MARKER'] = '-Wl,-Bdynamic,--no-whole-archive'
+
+def _check_win32(conf):
+ import Options
+ import sys
+ import subprocess
+ import os
+ env = conf.env
+ if conf.env['CXX_NAME'] in ['gcc', 'icc']:
+ if sys.platform == 'win32':
+ env.append_value("LINKFLAGS", "-Wl,--enable-runtime-pseudo-reloc")
+ elif sys.platform == 'cygwin':
+ env.append_value("LINKFLAGS", "-Wl,--enable-auto-import")
+
+ cxx, = env['CXX']
+
+ p = subprocess.Popen([cxx, '-print-file-name=libstdc++.so'], stdout=subprocess.PIPE)
+ libstdcxx_location = os.path.dirname(p.stdout.read().strip())
+ p.wait()
+ if libstdcxx_location:
+ conf.env.append_value('NS3_MODULE_PATH', libstdcxx_location)
+
+ if Options.platform in ['linux']:
+ if _check_compilation_flag(conf, '-Wl,--soname=foo'):
+ env['WL_SONAME_SUPPORTED'] = True
+
+
+def _check_dependencies(conf, required, mandatory):
+ found = []
+ for module in required:
+ retval = conf.check_cfg(package = 'libns3-%s' % module.lower(),
+ args='--cflags --libs', mandatory=mandatory,
+ msg="Checking for ns3-%s" % module.lower(),
+ uselib_store='NS3_%s' % module.upper())
+ if not retval is None:
+ found.append(module)
+ import copy
+ if not 'NS3_MODULES_FOUND' in conf.env:
+ conf.env['NS3_MODULES_FOUND'] = []
+ conf.env['NS3_MODULES_FOUND'] = conf.env['NS3_MODULES_FOUND'] + copy.copy(found)
+
+def modules_uselib(bld, names):
+ return ['NS3_%s' % name.upper() for name in names] + \
+ ['NS3_LIBRARY_%s' % name.upper() for name in names] + \
+ ['NS3_HEADERS_%s' % name.upper() for name in names]
+
+def modules_found(bld):
+ return bld.env['NS3_MODULES_FOUND']
+
+def _c_libname(bld, name):
+ libname = 'ns3-' + name
+ if bld.env['NS3_ENABLE_STATIC']:
+ return bld.env['cstlib_PATTERN'] % libname
+ else:
+ return bld.env['cshlib_PATTERN'] % libname
+
+def check_modules(conf, modules, mandatory = True):
+ import Options
+ import os
+
+ if not 'NS3_CHECK_MODULE_ONCE' in conf.env:
+ conf.env['NS3_CHECK_MODULE_ONCE'] = ''
+ conf.check_tool('compiler_cc')
+ conf.check_tool('compiler_cxx')
+ conf.check_cfg(atleast_pkgconfig_version='0.0.0')
+ _check_win32(conf)
+ _check_static(conf)
+ if Options.options.enable_log:
+ _report_optional_feature(conf, "log", "Logging", True, '')
+ conf.env.append_value('DEFINES', 'NS3_LOG_ENABLE')
+ else:
+ _report_optional_feature(conf, "log", "Logging", False,
+ 'option --disable-log selected')
+ if Options.options.enable_assert:
+ _report_optional_feature(conf, "assert", "Assert checks", True, '')
+ conf.env.append_value('DEFINES', 'NS3_ASSERT_ENABLE')
+ else:
+ _report_optional_feature(conf, "assert", "Assert checks", False,
+ 'option --disable-assert selected')
+ if Options.options.enable_gcov:
+ _report_optional_feature(conf, "coverage", "Code coverage", True, '')
+ conf.env.append_value('CCFLAGS', '-fprofile-arcs')
+ conf.env.append_value('CCFLAGS', '-ftest-coverage')
+ conf.env.append_value('CXXFLAGS', '-fprofile-arcs')
+ conf.env.append_value('CXXFLAGS', '-ftest-coverage')
+ conf.env.append_value('LINKFLAGS', '-fprofile-arcs')
+ else:
+ _report_optional_feature(conf, "coverage", "Code coverage", False,
+ 'option --enable-gcov not selected')
+ if Options.options.enable_examples:
+ _report_optional_feature(conf, "examples", "Example programs", True, '')
+ conf.env['NS3_ENABLE_EXAMPLES'] = True
+ else:
+ _report_optional_feature(conf, "examples", "Example programs", False,
+ 'option --disable-examples selected')
+ conf.env['NS3_ENABLE_EXAMPLES'] = False
+
+ if Options.options.enable_tests:
+ _report_optional_feature(conf, "tests", "Test programs", True, '')
+ conf.env['NS3_ENABLE_TESTS'] = True
+ else:
+ _report_optional_feature(conf, "tests", "Test programs", False,
+ 'option --disable-tests selected')
+ conf.env['NS3_ENABLE_TESTS'] = False
+
+ _check_dependencies(conf, modules, mandatory)
+
+def print_feature_summary(conf):
+ _print_optional_features(conf)
+
+def _build_library(bld, name, source, use):
+ import os
+ if source is None:
+ return
+ cxxflags = []
+ cflags = []
+ linkflags = []
+ ccdefines = ['NS3_MODULE_COMPILATION']
+ cxxdefines = ['NS3_MODULE_COMPILATION']
+ target = os.path.join('lib', 'ns3-%s' % name)
+ if not bld.env['NS3_ENABLE_STATIC']:
+ if bld.env['CXX_NAME'] in ['gcc', 'icc'] and bld.env['WL_SONAME_SUPPORTED']:
+ linkflags.append('-Wl,--soname=%s' % _c_libname(bld, name))
+ pass
+ elif bld.env['CXX_NAME'] in ['gcc', 'icc'] and \
+ os.uname()[4] == 'x86_64' and \
+ bld.env['NS3_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.append('-mcmodel=large')
+ cflags.append('-mcmodel=large')
+ if bld.env['NS3_ENABLE_STATIC']:
+ lib_type = 'stlib'
+ else:
+ lib_type = 'shlib'
+ features = waflib.Tools.c_aliases.sniff_features(source=source, _type=lib_type)
+ bld(features=features, source=source, target=target, use = use,
+ cxxflags = cxxflags, cflags=cflags, linkflags=linkflags,
+ ccdefines=ccdefines, cxxdefines=cxxdefines)
+ bld(name='NS3_LIBRARY_%s' % name.upper(), use=[target])
+
+
+def _build_headers(bld, name, headers):
+ if headers is None:
+ return
+ import os
+ import shutil
+ def run(task):
+ out_dir = os.path.dirname(task.outputs[0].abspath())
+ for header in task.inputs:
+ dst = os.path.join(out_dir, os.path.basename(header.abspath()))
+ src = header.abspath()
+ shutil.copyfile(src, dst)
+
+ outfile = file(task.outputs[0].abspath(), "w")
+
+ print >> outfile, """
+#ifdef NS3_MODULE_COMPILATION
+# error "Do not include ns3 module aggregator headers from other modules; these are meant only for end user scripts."
+#endif
+
+#ifndef NS3_MODULE_%s
+ """ % (name.upper().replace('-', '_'),)
+
+ print >> outfile
+ print >> outfile, "// Module headers:"
+ for header in [src.abspath() for src in task.inputs]:
+ print >> outfile, "#include \"%s\"" % (os.path.basename(header),)
+
+ print >> outfile, "#endif"
+
+ outfile.close()
+ target = os.path.join('include', 'ns3', '%s-module.h' % name)
+ bld(rule=run, source=headers, target=target)
+ bld(use=[target], target='NS3_HEADERS_%s' % name.upper(),
+ export_includes=['include'])
+
+
+
+def _lib(bld, dep):
+ libpath = bld.env['LIBPATH_%s' % dep.upper()]
+ linkflags = bld.env['LINKFLAGS_%s' % dep.upper()]
+ libs = bld.env['LIB_%s' % dep.upper()]
+ retval = []
+ for path in libpath:
+ retval.append(bld.env['LIBPATH_ST'] % path)
+ retval = retval + linkflags
+ for lib in libs:
+ retval.append(bld.env['LIB_ST'] % lib)
+ return retval
+
+def _cflags(bld, dep):
+ return bld.env['CFLAGS_%s' % dep]
+def _cxxflags(bld, dep):
+ return bld.env['CXXFLAGS_%s' % dep]
+def _defines(bld, dep):
+ return ['-D' + define for define in bld.env['DEFINES_%s' % dep]]
+def _includes(bld, dep):
+ return ['-I' + include for include in bld.env['INCLUDES_%s' % dep]]
+
+def _self_lib(bld, name, libdir):
+ if bld.env['NS3_ENABLE_STATIC']:
+ path_st = 'STLIBPATH_ST'
+ lib_st = 'STLIB_ST'
+ lib_marker = 'STLIB_MARKER'
+ else:
+ path_st = 'LIBPATH_ST'
+ lib_st = 'LIB_ST'
+ lib_marker = 'SHLIB_MARKER'
+ libname = 'ns3-' + name
+ return [bld.env[path_st] % libdir,
+ bld.env[lib_marker],
+ bld.env[lib_st] % libname]
+
+
+def _build_pkgconfig(bld, name, use):
+ import os
+ def run(task):
+ outfilename = task.outputs[0].abspath()
+ outfile = open(outfilename, 'w')
+ prefix = os.path.normpath(os.path.join(os.path.dirname(task.outputs[0].abspath()), os.pardir))
+ includedir = os.path.join(prefix, 'include')
+ libdir = os.path.join(prefix, 'lib')
+ libs = _self_lib(bld, name, '%{libdir}')
+ for dep in use:
+ libs = libs + _lib(bld,dep)
+ cflags = ['-I${includedir}']
+ for dep in use:
+ cflags = cflags + _cflags(bld, dep) + _cxxflags(bld, dep) + \
+ _defines(bld, dep) + _includes(bld, dep)
+ print >> outfile, """
+prefix=%s
+libdir=%s
+includedir=%s
+
+Name: libns3-%s
+Description: ns-3 module %s
+Version: devel
+Libs: %s
+Cflags: %s
+""" % (prefix, libdir, includedir,
+ name, name, ' '.join(libs), ' '.join(cflags))
+ outfile.close()
+ target = os.path.join('pkgconfig', 'libns3-%s.pc' % name)
+ bld(rule=run, target=target, always=True)
+
+
+
+def build_module(bld, name, source = None, use = None, headers = None, test = None):
+ _build_library(bld, name=name, source=source, use=use)
+ _build_headers(bld, name, headers)
+ _build_pkgconfig(bld, name, use)
+# _build_test(bld, name, test)
+
+def build_program(bld, target=None, source = None, use = None):
+ print bld.env
+ bld.program(source=source, target=target, use=use)
+
+def build_example(bld, target=None, source = None, use = None):
+ if bld.env['NS3_ENABLE_EXAMPLES']:
+ bld.program(source=source, target=target, use=use)
+
+
+