When a module is disabled, remove xxx-module.h and module header files from build/variant/ns3
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Tue, 26 Oct 2010 15:11:17 +0100
changeset 6647 bdbbfbc6bda7
parent 6646 da7b76739b64
child 6648 d1785ce489c5
When a module is disabled, remove xxx-module.h and module header files from build/variant/ns3
src/wscript
wscript
--- a/src/wscript	Tue Oct 26 15:10:23 2010 +0100
+++ b/src/wscript	Tue Oct 26 15:11:17 2010 +0100
@@ -10,6 +10,7 @@
 import Options
 import Build
 import Utils
+import Constants
 
 try:
     set
@@ -143,6 +144,7 @@
         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 @@
             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 __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):
-        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):
+        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.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
-
+                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 @@
     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 @@
             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
--- a/wscript	Tue Oct 26 15:10:23 2010 +0100
+++ b/wscript	Tue Oct 26 15:11:17 2010 +0100
@@ -549,15 +549,15 @@
         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 @@
             # 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']: