## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- import os, os.path import shutil import types import Action import Common import Object import Params all_modules = ( 'core', 'common', 'simulator', 'contrib', 'node', 'internet-stack', 'devices/point-to-point', 'devices/csma', 'devices/bridge', 'devices/tap', 'devices/emulated', 'applications/onoff', 'applications/packet-sink', 'applications/udp-echo', 'routing/olsr', 'routing/global-routing', 'mobility', 'devices/wifi', 'helper', 'contrib/stats', 'applications/v4ping', ) def set_options(opt): opt.sub_options('simulator') opt.add_option('--enable-rpath', help=("Link programs with rpath" " (normally not needed, see " " --run and --shell; moreover, only works in some" " specific platforms, such as Linux and Solaris)"), action="store_true", dest='enable_rpath', default=False) opt.add_option('--enable-modules', help=("Build only these modules (and dependencies)"), dest='enable_modules') def configure(conf): conf.sub_config('core') conf.sub_config('simulator') conf.sub_config('contrib') conf.sub_config('internet-stack') blddir = os.path.abspath(os.path.join(conf.m_blddir, conf.env.variant())) conf.env.append_value('NS3_MODULE_PATH', blddir) if Params.g_options.enable_rpath: conf.env.append_value('RPATH', '-Wl,-rpath=%s' % (os.path.join(blddir),)) ## Used to link the 'run-tests' program with all of ns-3 code conf.env['NS3_MODULES'] = ['ns3-' + module.split('/')[-1] for module in all_modules] def create_ns3_module(bld, name, dependencies=()): module = bld.create_obj('cpp', 'objects') module.name = 'ns3-' + name module.target = module.name module.add_objects = ['ns3-' + dep for dep in dependencies] module.module_deps = list(dependencies) module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS']) module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION") return module def build(bld): #Object.register('ns3header', Ns3Header) Action.Action('ns3header', func=_ns3_headers_inst, color='BLUE') #Object.register('ns3-module-header', Ns3ModuleHeader) Action.Action('gen-ns3-module-header', func=gen_ns3_module_header, color='BLUE') bld.create_ns3_module = types.MethodType(create_ns3_module, bld) bld.add_subdirs(list(all_modules)) for module in all_modules: modheader = bld.create_obj('ns3moduleheader') modheader.module = module.split('/')[-1] class ns3header_taskgen(Object.task_gen): """A set of NS-3 header files""" def __init__(self, *features): Object.task_gen.__init__(self, *features) self.inst_var = 'INCLUDEDIR' self.inst_dir = 'ns3' self.sub_dir = None # if not None, header files will be published as ns3/sub_dir/file.h self.module = None # module name def apply(self): if self.module is None: Params.fatal("'module' missing on ns3headers object %s" % self) ns3_dir_node = Params.g_build.m_srcnode.find_dir("ns3") if self.sub_dir is not None: ns3_dir_node = ns3_dir_node.find_dir(self.sub_dir) for filename in self.to_list(self.source): src_node = self.path.find_source(filename) if src_node is None: Params.fatal("source ns3 header file %s not found" % (filename,)) dst_node = ns3_dir_node.find_build(os.path.basename(filename)) assert dst_node is not None task = self.create_task('ns3header', self.env, 1) task.set_inputs([src_node]) task.set_outputs([dst_node]) def install(self): if self.sub_dir is None: inst_dir = self.inst_dir else: inst_dir = os.path.join(self.inst_dir, self.sub_dir) for i in self.m_tasks: current = Params.g_build.m_curdirnode lst = map(lambda a: a.relpath_gen(current), i.m_outputs) Common.install_files(self.inst_var, inst_dir, lst) def _ns3_headers_inst(task): assert len(task.m_inputs) == len(task.m_outputs) inputs = [node.srcpath(task.m_env) for node in task.m_inputs] outputs = [node.bldpath(task.m_env) for node in task.m_outputs] for src, dst in zip(inputs, outputs): try: os.chmod(dst, 0600) except OSError: pass shutil.copy2(src, dst) ## make the headers in builddir read-only, to prevent ## accidental modification os.chmod(dst, 0400) return 0 def gen_ns3_module_header(task): assert len(task.m_outputs) == 1 header_files = [os.path.basename(node.abspath(task.m_env)) for node in task.m_inputs] outfile = file(task.m_outputs[0].bldpath(task.m_env), "w") header_files.sort() print >> outfile, """ #ifdef NS3_MODULE_COMPILATION # error "Do not include ns3 module aggregator headers from other modules; these are meant only for end user scripts." #endif #ifndef NS3_MODULE_%s """ % (task.module.upper().replace('-', '_'),) # if task.module_deps: # print >> outfile, "// Module dependencies:" # for dep in task.module_deps: # print >> outfile, "#include \"%s-module.h\"" % dep print >> outfile print >> outfile, "// Module headers:" for header in header_files: print >> outfile, "#include \"%s\"" % (header,) print >> outfile, "#endif" outfile.close() return 0 class ns3moduleheader_taskgen(Object.task_gen): """ Generates a 'ns3/foo-module.h' header file that includes all public ns3 headers of a certain module. """ def __init__(self, *features): Object.task_gen.__init__(self, *features) self.module_name = None def apply(self): ## get all of the ns3 headers ns3_dir_node = Params.g_build.m_srcnode.find_dir("ns3") all_headers_inputs = [] for ns3headers in Object.g_allobjs: if isinstance(ns3headers, ns3header_taskgen): if ns3headers.module != self.module: continue for source in ns3headers.to_list(ns3headers.source): source = os.path.basename(source) node = ns3_dir_node.find_build(os.path.basename(source)) if node is None: fatal("missing header file %s" % (source,)) all_headers_inputs.append(node) assert all_headers_inputs module_obj = Object.name_to_obj("ns3-" + self.module) assert module_obj is not None all_headers_outputs = [ns3_dir_node.find_build("%s-module.h" % self.module)] task = self.create_task('gen-ns3-module-header', self.env, 4) task.set_inputs(all_headers_inputs) task.set_outputs(all_headers_outputs) task.module = self.module task.module_deps = module_obj.module_deps def install(self): pass