diff -r cc60191ad0d4 -r 6faee3d1d1d0 src/wscript --- a/src/wscript Tue Oct 04 10:16:06 2011 +0200 +++ b/src/wscript Mon Oct 10 18:05:18 2011 +0200 @@ -6,15 +6,13 @@ 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,54 +21,21 @@ 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', - 'buildings', - ] -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 " @@ -82,20 +47,15 @@ help=("Build only these modules (and dependencies)"), dest='enable_modules') + for module in all_modules: + opt.sub_options(module, mandatory=False) + + 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: + conf.sub_config(module, mandatory=False) - blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant())) + 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),)) @@ -104,131 +64,85 @@ 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 - if hasattr(self, 'includes'): - module.includes = self.includes - if hasattr(self, "is_ns3_module"): - module.is_ns3_module = self.is_ns3_module - - 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) - if not static: - module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS']) - module.env.append_value('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)) - module.env.append_value('LINKFLAGS', '-Wl,--soname=%s' % module_library_name) - elif module.env['CXX_NAME'] in ['gcc', 'icc'] and \ - os.uname()[4] == 'x86_64' and \ - module.env['ENABLE_PYTHON_BINDINGS']: - # enable that flag for static builds only on x86-64 platforms - # when gcc is present and only when we want python bindings - # (it's more efficient to not use this option if we can avoid it) - module.env.append_value('CXXFLAGS', '-mcmodel=large') - module.env.append_value('CCFLAGS', '-mcmodel=large') - module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION") - module.env.append_value('CCDEFINES', "NS3_MODULE_COMPILATION") - - 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 + 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", '#') + + pcfilegen = bld(features='ns3pcfile') + pcfilegen.module = module + 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. @@ -237,7 +151,7 @@ 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) @@ -254,6 +168,9 @@ 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) @@ -262,8 +179,6 @@ if not env['ENABLE_PYTHON_BINDINGS']: return - if env['BINDINGS_TYPE'] not in ('modular', 'both'): - return bindings_dir = bld.path.find_dir("bindings") if bindings_dir is None or not os.path.exists(bindings_dir.abspath()): @@ -301,6 +216,7 @@ source=("bindings/%s.py" % (module_py_name,)), target=('%s/%s.py' % (module_target_dir, module_py_name))) extension_name = '_%s' % (module_py_name,) + bld.install_files('${PYTHONDIR}/ns', ["bindings/%s.py" % (module_py_name,)]) else: extension_name = module_py_name @@ -308,7 +224,9 @@ #if not debug: # target.append('ns3modulegen.log') - argv = ['NS3_ENABLED_FEATURES=${FEATURES}', '${PYTHON}'] + argv = ['NS3_ENABLED_FEATURES=${FEATURES}', + 'GCC_RTTI_ABI_COMPLETE=${GCC_RTTI_ABI_COMPLETE}', + '${PYTHON}'] #if debug: # argv.extend(["-m", "pdb"]) @@ -321,40 +239,42 @@ 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'] + 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 + bindgen.install_path = None # 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 @@ -380,30 +300,35 @@ 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): after = 'cc cxx' + def __str__(self): "string to display to the user" tgt_str = ' '.join([a.nice_path(self.env) for a in self.outputs]) return 'pcfile: %s\n' % (tgt_str) + def runnable_status(self): return super(ns3pcfile_task, self).runnable_status() + def _self_libs(self, env, name, libdir): if env['ENABLE_STATIC_NS3']: - path_st = 'STATICLIBPATH_ST' - lib_st = 'STATICLIB_ST' - lib_marker = 'STATICLIB_MARKER' + 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' - retval = [env[path_st] % libdir, - env[lib_marker], - env[lib_st] % name] + retval = [env[path_st] % libdir] + if env[lib_marker]: + retval.append(env[lib_marker]) + retval.append(env[lib_st] % name) return retval + def _lib(self, env, dep): libpath = env['LIBPATH_%s' % dep] linkflags = env['LINKFLAGS_%s' % dep] @@ -415,37 +340,44 @@ for lib in libs: retval.append(env['LIB_ST'] % lib) return retval + def _listify(self, v): if isinstance(v, list): return v else: return [v] + def _cflags(self, dep): flags = self.env['CFLAGS_%s' % dep] return self._listify(flags) + def _cxxflags(self, dep): return self._listify(self.env['CXXFLAGS_%s' % dep]) + def _defines(self, dep): - defines = self.env['CCDEFINES_%s' % dep] + self.env['CXXDEFINES_%s' % dep] - return [self.env['CCDEFINES_ST'] % define for define in self.env['CCDEFINES_%s' % dep]] + \ - [self.env['CXXDEFINES_ST'] % define for define in self.env['CXXDEFINES_%s' % dep]] + return [self.env['DEFINES_ST'] % define for define in self.env['DEFINES_%s' % dep]] + def _includes(self, dep): - includes = self.env['CPPPATH_%s' % dep] + includes = self.env['INCLUDES_%s' % dep] return [self.env['CPPPATH_ST'] % include for include in includes] - def _generate_pcfile(self, name, use, uselib_local, prefix, outfilename): - outfile = open(outfilename, 'w') - includedir = os.path.join(prefix, 'include') - libdir = os.path.join(prefix, 'lib') - libs = self._self_libs(self.env, name, '${libdir}') + def _generate_pcfile(self, name, use, env, outfilename): + outfile = open(outfilename, 'wt') + prefix = env.PREFIX + includedir = env.INCLUDEDIR + libdir = env.LIBDIR + libs = self._self_libs(env, name, '${libdir}') for dep in use: - libs = libs + self._lib(self.env, dep) - for dep in uselib_local: - libs = libs + [self.env['LIB_ST'] % dep] + libs += self._lib(env, dep) + for dep in env.LIBS: + libs += self.env['LIB_ST'] % dep cflags = [self.env['CPPPATH_ST'] % '${includedir}'] + requires = [] for dep in use: cflags = cflags + self._cflags(dep) + self._cxxflags(dep) + \ self._defines(dep) + self._includes(dep) + if dep.startswith('ns3-'): + requires.append("lib"+dep) print >> outfile, """ prefix=%s libdir=%s @@ -456,65 +388,57 @@ Version: devel Libs: %s Cflags: %s +Requires: %s """ % (prefix, libdir, includedir, - name, name, ' '.join(libs), ' '.join(cflags)) + name, name, ' '.join(libs), ' '.join(cflags), ' '.join(requires)) outfile.close() 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.env['PREFIX'], output_filename) + output_filename = self.outputs[0].abspath() + self._generate_pcfile(self.module.name, + self.module.to_list(self.module.use), + self.env, output_filename) + -class ns3pcfile_taskgen(TaskGen.task_gen): - def __init__(self, *args, **kwargs): - super(ns3pcfile_taskgen, self).__init__(*args, **kwargs) - def apply(self): - output_filename = 'lib%s.pc' % self.module.name - output_node = self.path.find_or_declare(output_filename) - assert output_node is not None, str(self) - task = self.create_task('ns3pcfile', env=self.env) - self.bld.install_files(os.path.join('${PREFIX}', 'lib', 'pkgconfig'), - output_node) - task.set_outputs([output_node]) - task.module = self.module +@TaskGen.feature('ns3pcfile') +@TaskGen.after_method('process_rule') +def apply(self): + output_filename = 'lib%s.pc' % self.module.name + output_node = self.path.find_or_declare(output_filename) + assert output_node is not None, str(self) + task = self.create_task('ns3pcfile') + self.bld.install_files('${LIBDIR}/pkgconfig', output_node) + task.set_outputs([output_node]) + 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' +@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 - 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 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): @@ -525,23 +449,41 @@ 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) @@ -555,7 +497,7 @@ 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: @@ -566,15 +508,15 @@ 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() @@ -586,24 +528,23 @@ 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() @@ -631,7 +572,7 @@ 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): @@ -645,50 +586,46 @@ 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]