From 0edf3776b342befab651c581082d5bbb027c9a42 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Tue, 26 Oct 2010 15:11:17 +0100 Subject: [PATCH] When a module is disabled, remove xxx-module.h and module header files from build/variant/ns3 --- src/wscript | 120 ++++++++++++++++++++++++++++++++++++++++++---------- wscript | 16 +++---- 2 files changed, 106 insertions(+), 30 deletions(-) diff --git a/src/wscript b/src/wscript index ced393512..f285329a0 100644 --- a/src/wscript +++ b/src/wscript @@ -10,6 +10,7 @@ import Task import Options import Build import Utils +import Constants try: set @@ -143,6 +144,7 @@ class ns3header_taskgen(TaskGen.task_gen): 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): if self.module is None: @@ -157,37 +159,106 @@ class ns3header_taskgen(TaskGen.task_gen): 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.set_inputs([src_node]) - task.set_outputs([dst_node]) + task.mode = self.mode + if self.mode == 'install': + 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' color = 'BLUE' - def run(self): - assert len(self.inputs) == len(self.outputs) - inputs = [node.srcpath(self.env) for node in self.inputs] - outputs = [node.bldpath(self.env) for node in self.outputs] - for src, dst in zip(inputs, outputs): - try: - os.chmod(dst, 0600) - except OSError: - pass - shutil.copy2(src, dst) - ## make the headers in builddir read-only, to prevent - ## accidental modification - os.chmod(dst, 0400) - return 0 + def __str__(self): + "string to display to the user" + env = self.env + src_str = ' '.join([a.nice_path(env) for a in self.inputs]) + tgt_str = ' '.join([a.nice_path(env) for a in self.outputs]) + if self.outputs: sep = ' -> ' + else: sep = '' + if self.mode == 'remove': + return 'rm-ns3-header %s\n' % (self.header_to_remove.bldpath(self.env),) + return 'install-ns3-header: %s%s%s\n' % (src_str, sep, tgt_str) + + def runnable_status(self): + if self.mode == 'remove': + if os.path.exists(self.header_to_remove.bldpath(self.env)): + return Constants.RUN_ME + else: + return Constants.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] + 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 + else: + assert len(self.inputs) == 0 + assert len(self.outputs) == 0 + out_file_name = self.header_to_remove.bldpath(self.env) + try: + os.unlink(out_file_name) + except OSError, ex: + if ex.errno != 2: + raise + return 0 + class gen_ns3_module_header_task(Task.Task): before = 'cc cxx' after = 'ns3header_task' 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 + else: + return Constants.SKIP_ME + else: + return super(gen_ns3_module_header_task, self).runnable_status() + + def __str__(self): + "string to display to the user" + env = self.env + src_str = ' '.join([a.nice_path(env) for a in self.inputs]) + tgt_str = ' '.join([a.nice_path(env) for a in self.outputs]) + if self.outputs: sep = ' -> ' + else: sep = '' + if self.mode == 'remove': + return 'rm-module-header %s\n' % (self.header_to_remove.bldpath(self.env),) + 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) + 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] - outfile = file(self.outputs[0].bldpath(self.env), "w") + outfile = file(out_file_name, "w") header_files.sort() print >> outfile, """ @@ -237,6 +308,7 @@ class ns3moduleheader_taskgen(TaskGen.task_gen): COLOR = 'BLUE' def __init__(self, *args, **kwargs): super(ns3moduleheader_taskgen, self).__init__(*args, **kwargs) + self.mode = 'install' def apply(self): ## get all of the ns3 headers @@ -258,14 +330,18 @@ class ns3moduleheader_taskgen(TaskGen.task_gen): raise Utils.WscriptError("error finding headers for module %s" % self.module) if not all_headers_inputs: return - module_obj = self.bld.name_to_obj("ns3-" + self.module, self.env) - assert module_obj is not None, self.module 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.set_inputs(all_headers_inputs) - task.set_outputs(all_headers_outputs) task.module = self.module - task.module_deps = module_obj.module_deps + task.mode = self.mode + if self.mode == 'install': + 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] def install(self): pass diff --git a/wscript b/wscript index 441657de5..fa5a5a24e 100644 --- a/wscript +++ b/wscript @@ -549,15 +549,15 @@ def build(bld): env['NS3_ENABLED_MODULES'] = modules print "Modules to build:", modules - def exclude_task(bld, task): + def exclude_taskgen(bld, taskgen): # ok, so WAF does not provide an API to prevent an - # arbitrary task from running; we have to muck around with + # 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(task) + bld.all_task_gen.remove(taskgen) for group in bld.task_manager.groups: try: - group.tasks_gen.remove(task) + group.tasks_gen.remove(taskgen) except ValueError: pass else: @@ -569,24 +569,24 @@ def build(bld): # check for ns3moduleheader_taskgen if type(obj).__name__ == 'ns3moduleheader_taskgen': if ("ns3-%s" % obj.module) not in modules: - exclude_task(bld, obj) + obj.mode = 'remove' # tell it to remove headers instead of installing # check for programs if hasattr(obj, 'ns3_module_dependencies'): # this is an NS-3 program (bld.create_ns3_program) for dep in obj.ns3_module_dependencies: if dep not in modules: # prog. depends on a module that isn't enabled? - exclude_task(bld, obj) + exclude_taskgen(bld, obj) break # disable the modules themselves if hasattr(obj, "is_ns3_module") and obj.name not in modules: - exclude_task(bld, obj) + exclude_taskgen(bld, obj) # kill the module # disable the ns3header_taskgen if type(obj).__name__ == 'ns3header_taskgen': if ("ns3-%s" % obj.module) not in modules: - exclude_task(bld, obj) + obj.mode = 'remove' # tell it to remove headers instead of installing ## Create a single ns3 library containing all enabled modules if env['ENABLE_STATIC_NS3']: