LEFT | RIGHT |
1 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8;
-*- | 1 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8;
-*- |
2 | 2 |
3 import os, os.path | 3 import os, os.path |
4 import shutil | 4 import shutil |
5 import types | 5 import types |
6 import warnings | 6 import warnings |
7 | 7 |
8 import TaskGen | 8 import TaskGen |
9 import Task | 9 import Task |
10 import Options | 10 import Options |
11 import Build | 11 import Build |
12 import Utils | 12 import Utils |
| 13 import Constants |
13 | 14 |
14 try: | 15 try: |
15 set | 16 set |
16 except NameError: | 17 except NameError: |
17 from sets import Set as set # Python 2.3 fallback | 18 from sets import Set as set # Python 2.3 fallback |
18 | 19 |
19 all_modules = ( | 20 all_modules = ( |
20 'core', | 21 'core', |
21 'common', | 22 'common', |
22 'simulator', | 23 'simulator', |
23 'contrib', | 24 'contrib', |
24 'node', | 25 'node', |
25 'internet-stack', | 26 'internet-stack', |
| 27 'propagation', |
26 'devices/point-to-point', | 28 'devices/point-to-point', |
27 'devices/csma', | 29 'devices/csma', |
28 'devices/emu', | 30 'devices/emu', |
29 'devices/bridge', | 31 'devices/bridge', |
30 'devices/switch', | 32 'devices/switch', |
31 'devices/tap-bridge', | 33 'devices/tap-bridge', |
32 'devices/virtual-net-device', | 34 'devices/virtual-net-device', |
33 'applications/onoff', | 35 'applications/onoff', |
34 'applications/packet-sink', | 36 'applications/packet-sink', |
35 'applications/udp-echo', | 37 'applications/udp-echo', |
| 38 'applications/bulk-send', |
36 'routing/nix-vector-routing', | 39 'routing/nix-vector-routing', |
37 'routing/olsr', | 40 'routing/olsr', |
38 'routing/global-routing', | 41 'routing/global-routing', |
39 'routing/static-routing', | 42 'routing/static-routing', |
40 'routing/list-routing', | 43 'routing/list-routing', |
41 'routing/aodv', | 44 'routing/aodv', |
| 45 'routing/dsdv', |
42 'mobility', | 46 'mobility', |
43 'devices/wifi', | 47 'devices/wifi', |
44 'helper', | 48 'helper', |
45 'contrib/stats', | 49 'contrib/stats', |
46 'applications/v4ping', | 50 'applications/v4ping', |
47 'devices/uan', | 51 'devices/uan', |
48 'devices/spectrum', | 52 'spectrum', |
49 'devices/mesh',··· | 53 'devices/mesh',··· |
50 'devices/mesh/dot11s', | 54 'devices/mesh/dot11s', |
51 'devices/mesh/flame', | 55 'devices/mesh/flame', |
52 'applications/ping6', | 56 'applications/ping6', |
53 'applications/radvd', | 57 'applications/radvd', |
54 'test', | 58 'test', |
55 'test/perf', | 59 'test/perf', |
56 'test/ns3tcp', | 60 'test/ns3tcp', |
57 'test/nsctcp', | 61 'test/nsctcp', |
58 'test/ns3wifi', | 62 'test/ns3wifi', |
59 'contrib/flow-monitor', | 63 'contrib/flow-monitor', |
60 'applications/udp-client-server', | 64 'applications/udp-client-server', |
61 'devices/wimax', | 65 'devices/wimax', |
| 66 'devices/lte', |
62 'mpi', | 67 'mpi', |
63 'contrib/topology-read', | 68 'contrib/topology-read', |
64 'contrib/energy', | 69 'contrib/energy', |
| 70 'tools/visualizer', |
65 ) | 71 ) |
66 | 72 |
67 def set_options(opt): | 73 def set_options(opt): |
68 opt.sub_options('simulator') | 74 opt.sub_options('simulator') |
69 | 75 |
70 opt.add_option('--enable-rpath', | 76 opt.add_option('--enable-rpath', |
71 help=("Link programs with rpath" | 77 help=("Link programs with rpath" |
72 " (normally not needed, see " | 78 " (normally not needed, see " |
73 " --run and --shell; moreover, only works in some" | 79 " --run and --shell; moreover, only works in some" |
74 " specific platforms, such as Linux and Solaris)"), | 80 " specific platforms, such as Linux and Solaris)"), |
75 action="store_true", dest='enable_rpath', default=False) | 81 action="store_true", dest='enable_rpath', default=False) |
76 ···· | 82 ···· |
77 opt.add_option('--enable-modules', | 83 opt.add_option('--enable-modules', |
78 help=("Build only these modules (and dependencies)"), | 84 help=("Build only these modules (and dependencies)"), |
79 dest='enable_modules') | 85 dest='enable_modules') |
80 | 86 |
81 def configure(conf): | 87 def configure(conf): |
82 conf.sub_config('core') | 88 conf.sub_config('core') |
83 conf.sub_config('simulator') | 89 conf.sub_config('simulator') |
84 conf.sub_config('devices/emu') | 90 conf.sub_config('devices/emu') |
85 conf.sub_config('devices/tap-bridge') | 91 conf.sub_config('devices/tap-bridge') |
86 conf.sub_config('contrib') | 92 conf.sub_config('contrib') |
87 conf.sub_config('internet-stack') | 93 conf.sub_config('internet-stack') |
88 conf.sub_config('helper') | 94 conf.sub_config('helper') |
89 conf.sub_config('test') | 95 conf.sub_config('test') |
| 96 conf.sub_config('devices/switch') |
90 | 97 |
91 blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant())) | 98 blddir = os.path.abspath(os.path.join(conf.blddir, conf.env.variant())) |
92 conf.env.append_value('NS3_MODULE_PATH', blddir) | 99 conf.env.append_value('NS3_MODULE_PATH', blddir) |
93 if Options.options.enable_rpath: | 100 if Options.options.enable_rpath: |
94 conf.env.append_value('RPATH', '-Wl,-rpath=%s' % (os.path.join(blddir),)
) | 101 conf.env.append_value('RPATH', '-Wl,-rpath=%s' % (os.path.join(blddir),)
) |
95 | 102 |
96 ## Used to link the 'test-runner' program with all of ns-3 code | 103 ## Used to link the 'test-runner' program with all of ns-3 code |
97 conf.env['NS3_MODULES'] = ['ns3-' + module.split('/')[-1] for module in all_
modules] | 104 conf.env['NS3_MODULES'] = ['ns3-' + module.split('/')[-1] for module in all_
modules] |
98 | 105 |
99 | 106 |
100 def create_ns3_module(bld, name, dependencies=()): | 107 def create_ns3_module(bld, name, dependencies=()): |
101 module = bld.new_task_gen('cxx', 'cc') | 108 module = bld.new_task_gen('cxx', 'cc') |
| 109 module.is_ns3_module = True |
102 module.name = 'ns3-' + name | 110 module.name = 'ns3-' + name |
103 module.target = module.name | 111 module.target = module.name |
104 module.add_objects = ['ns3-' + dep for dep in dependencies] | 112 module.add_objects = ['ns3-' + dep for dep in dependencies] |
105 module.module_deps = list(dependencies) | 113 module.module_deps = list(dependencies) |
106 if not module.env['ENABLE_STATIC_NS3']: | 114 if not module.env['ENABLE_STATIC_NS3']: |
107 module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS']) | 115 module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS']) |
108 module.env.append_value('CCFLAGS', module.env['shlib_CXXFLAGS']) | 116 module.env.append_value('CCFLAGS', module.env['shlib_CXXFLAGS']) |
109 elif module.env['CXX_NAME'] in ['gcc', 'icc'] and \ | 117 elif module.env['CXX_NAME'] in ['gcc', 'icc'] and \ |
110 os.uname()[4] == 'x86_64' and \ | 118 os.uname()[4] == 'x86_64' and \ |
111 module.env['ENABLE_PYTHON_BINDINGS']: | 119 module.env['ENABLE_PYTHON_BINDINGS']: |
(...skipping 24 matching lines...) Expand all Loading... |
136 | 144 |
137 | 145 |
138 class ns3header_taskgen(TaskGen.task_gen): | 146 class ns3header_taskgen(TaskGen.task_gen): |
139 """A set of NS-3 header files""" | 147 """A set of NS-3 header files""" |
140 COLOR = 'BLUE' | 148 COLOR = 'BLUE' |
141 def __init__(self, *args, **kwargs): | 149 def __init__(self, *args, **kwargs): |
142 super(ns3header_taskgen, self).__init__(*args, **kwargs) | 150 super(ns3header_taskgen, self).__init__(*args, **kwargs) |
143 self.install_path = None | 151 self.install_path = None |
144 self.sub_dir = None # if not None, header files will be published as ns3
/sub_dir/file.h | 152 self.sub_dir = None # if not None, header files will be published as ns3
/sub_dir/file.h |
145 self.module = None # module name | 153 self.module = None # module name |
| 154 self.mode = 'install' |
146 | 155 |
147 def apply(self): | 156 def apply(self): |
148 if self.module is None: | 157 if self.module is None: |
149 raise Utils.WafError("'module' missing on ns3headers object %s" % se
lf) | 158 raise Utils.WafError("'module' missing on ns3headers object %s" % se
lf) |
150 ns3_dir_node = self.bld.path.find_dir("ns3") | 159 ns3_dir_node = self.bld.path.find_dir("ns3") |
151 if self.sub_dir is not None: | 160 if self.sub_dir is not None: |
152 ns3_dir_node = ns3_dir_node.find_dir(self.sub_dir) | 161 ns3_dir_node = ns3_dir_node.find_dir(self.sub_dir) |
153 for filename in set(self.to_list(self.source)): | 162 for filename in set(self.to_list(self.source)): |
154 src_node = self.path.find_resource(filename) | 163 src_node = self.path.find_resource(filename) |
155 if src_node is None: | 164 if src_node is None: |
156 raise Utils.WafError("source ns3 header file %s not found" % (fi
lename,)) | 165 raise Utils.WafError("source ns3 header file %s not found" % (fi
lename,)) |
157 dst_node = ns3_dir_node.find_or_declare(os.path.basename(filename)) | 166 dst_node = ns3_dir_node.find_or_declare(os.path.basename(filename)) |
158 assert dst_node is not None | 167 assert dst_node is not None |
159 task = self.create_task('ns3header', env=self.env) | 168 task = self.create_task('ns3header', env=self.env) |
160 task.set_inputs([src_node]) | 169 task.mode = self.mode |
161 task.set_outputs([dst_node]) | 170 if self.mode == 'install': |
| 171 task.set_inputs([src_node]) |
| 172 task.set_outputs([dst_node]) |
| 173 else: |
| 174 task.header_to_remove = dst_node |
162 | 175 |
163 class ns3header_task(Task.Task): | 176 class ns3header_task(Task.Task): |
164 before = 'cc cxx gen_ns3_module_header_task' | 177 before = 'cc cxx gen_ns3_module_header_task' |
165 color = 'BLUE' | 178 color = 'BLUE' |
| 179 |
| 180 def __str__(self): |
| 181 "string to display to the user" |
| 182 env = self.env |
| 183 src_str = ' '.join([a.nice_path(env) for a in self.inputs]) |
| 184 tgt_str = ' '.join([a.nice_path(env) for a in self.outputs]) |
| 185 if self.outputs: sep = ' -> ' |
| 186 else: sep = '' |
| 187 if self.mode == 'remove': |
| 188 return 'rm-ns3-header %s\n' % (self.header_to_remove.bldpath(self.en
v),) |
| 189 return 'install-ns3-header: %s%s%s\n' % (src_str, sep, tgt_str) |
| 190 |
| 191 def runnable_status(self): |
| 192 if self.mode == 'remove': |
| 193 if os.path.exists(self.header_to_remove.bldpath(self.env)): |
| 194 return Constants.RUN_ME |
| 195 else: |
| 196 return Constants.SKIP_ME |
| 197 else: |
| 198 return super(ns3header_task, self).runnable_status() |
| 199 |
166 def run(self): | 200 def run(self): |
167 assert len(self.inputs) == len(self.outputs) | 201 if self.mode == 'install': |
168 inputs = [node.srcpath(self.env) for node in self.inputs] | 202 assert len(self.inputs) == len(self.outputs) |
169 outputs = [node.bldpath(self.env) for node in self.outputs] | 203 inputs = [node.srcpath(self.env) for node in self.inputs] |
170 for src, dst in zip(inputs, outputs): | 204 outputs = [node.bldpath(self.env) for node in self.outputs] |
| 205 for src, dst in zip(inputs, outputs): |
| 206 try: |
| 207 os.chmod(dst, 0600) |
| 208 except OSError: |
| 209 pass |
| 210 shutil.copy2(src, dst) |
| 211 ## make the headers in builddir read-only, to prevent |
| 212 ## accidental modification |
| 213 os.chmod(dst, 0400) |
| 214 return 0 |
| 215 else: |
| 216 assert len(self.inputs) == 0 |
| 217 assert len(self.outputs) == 0 |
| 218 out_file_name = self.header_to_remove.bldpath(self.env) |
171 try: | 219 try: |
172 os.chmod(dst, 0600) | 220 os.unlink(out_file_name) |
173 except OSError: | 221 except OSError, ex: |
174 pass | 222 if ex.errno != 2: |
175 shutil.copy2(src, dst) | 223 raise |
176 ## make the headers in builddir read-only, to prevent | 224 return 0 |
177 ## accidental modification | 225 ············ |
178 os.chmod(dst, 0400) | |
179 return 0 | |
180 | |
181 | 226 |
182 | 227 |
183 class gen_ns3_module_header_task(Task.Task): | 228 class gen_ns3_module_header_task(Task.Task): |
184 before = 'cc cxx' | 229 before = 'cc cxx' |
185 after = 'ns3header_task' | 230 after = 'ns3header_task' |
186 color = 'BLUE' | 231 color = 'BLUE' |
| 232 |
| 233 def runnable_status(self): |
| 234 if self.mode == 'remove': |
| 235 if os.path.exists(self.header_to_remove.bldpath(self.env)): |
| 236 return Constants.RUN_ME |
| 237 else: |
| 238 return Constants.SKIP_ME |
| 239 else: |
| 240 return super(gen_ns3_module_header_task, self).runnable_status() |
| 241 |
| 242 def __str__(self): |
| 243 "string to display to the user" |
| 244 env = self.env |
| 245 src_str = ' '.join([a.nice_path(env) for a in self.inputs]) |
| 246 tgt_str = ' '.join([a.nice_path(env) for a in self.outputs]) |
| 247 if self.outputs: sep = ' -> ' |
| 248 else: sep = '' |
| 249 if self.mode == 'remove': |
| 250 return 'rm-module-header %s\n' % (self.header_to_remove.bldpath(self
.env),) |
| 251 return 'gen-module-header: %s%s%s\n' % (src_str, sep, tgt_str) |
| 252 |
187 def run(self): | 253 def run(self): |
| 254 if self.mode == 'remove': |
| 255 assert len(self.inputs) == 0 |
| 256 assert len(self.outputs) == 0 |
| 257 out_file_name = self.header_to_remove.bldpath(self.env) |
| 258 try: |
| 259 os.unlink(out_file_name) |
| 260 except OSError, ex: |
| 261 if ex.errno != 2: |
| 262 raise |
| 263 return 0 |
| 264 ········ |
188 assert len(self.outputs) == 1 | 265 assert len(self.outputs) == 1 |
| 266 out_file_name = self.outputs[0].bldpath(self.env) |
189 header_files = [os.path.basename(node.abspath(self.env)) for node in sel
f.inputs] | 267 header_files = [os.path.basename(node.abspath(self.env)) for node in sel
f.inputs] |
190 outfile = file(self.outputs[0].bldpath(self.env), "w") | 268 outfile = file(out_file_name, "w") |
191 header_files.sort() | 269 header_files.sort() |
192 | 270 |
193 print >> outfile, """ | 271 print >> outfile, """ |
194 #ifdef NS3_MODULE_COMPILATION | 272 #ifdef NS3_MODULE_COMPILATION |
195 # error "Do not include ns3 module aggregator headers from other modules; these
are meant only for end user scripts." | 273 # error "Do not include ns3 module aggregator headers from other modules; these
are meant only for end user scripts." |
196 #endif | 274 #endif |
197 | 275 |
198 #ifndef NS3_MODULE_%s | 276 #ifndef NS3_MODULE_%s |
199 """ % (self.module.upper().replace('-', '_'),) | 277 """ % (self.module.upper().replace('-', '_'),) |
200 | 278 |
201 # if self.module_deps: | 279 # if self.module_deps: |
202 # print >> outfile, "// Module dependencies:" | 280 # print >> outfile, "// Module dependencies:" |
203 # for dep in self.module_deps: | 281 # for dep in self.module_deps: |
204 # print >> outfile, "#include \"%s-module.h\"" % dep | 282 # print >> outfile, "#include \"%s-module.h\"" % dep |
205 | 283 |
206 print >> outfile | 284 print >> outfile |
207 print >> outfile, "// Module headers:" | 285 print >> outfile, "// Module headers:" |
208 for header in header_files: | 286 for header in header_files: |
209 print >> outfile, "#include \"%s\"" % (header,) | 287 print >> outfile, "#include \"%s\"" % (header,) |
210 | 288 |
211 print >> outfile, "#endif" | 289 print >> outfile, "#endif" |
212 | 290 |
213 outfile.close() | 291 outfile.close() |
214 return 0 | 292 return 0 |
215 | 293 |
216 def sig_explicit_deps(self): | 294 def sig_explicit_deps(self): |
217 m = Utils.md5() | 295 self.m.update('\n'.join([node.abspath(self.env) for node in self.inputs]
)) |
218 m.update('\n'.join([node.abspath(self.env) for node in self.inputs])) | 296 return self.m.digest() |
219 return m.digest() | |
220 | 297 |
221 def unique_id(self): | 298 def unique_id(self): |
222 try: | 299 try: |
223 return self.uid | 300 return self.uid |
224 except AttributeError: | 301 except AttributeError: |
225 "this is not a real hot zone, but we want to avoid surprizes here" | 302 "this is not a real hot zone, but we want to avoid surprizes here" |
226 m = Utils.md5() | 303 m = Utils.md5() |
227 m.update("ns-3-module-header-%s" % self.module) | 304 m.update("ns-3-module-header-%s" % self.module) |
228 self.uid = m.digest() | 305 self.uid = m.digest() |
229 return self.uid | 306 return self.uid |
230 | 307 |
231 | 308 |
232 class ns3moduleheader_taskgen(TaskGen.task_gen): | 309 class ns3moduleheader_taskgen(TaskGen.task_gen): |
233 """ | 310 """ |
234 Generates a 'ns3/foo-module.h' header file that includes all | 311 Generates a 'ns3/foo-module.h' header file that includes all |
235 public ns3 headers of a certain module. | 312 public ns3 headers of a certain module. |
236 """ | 313 """ |
237 COLOR = 'BLUE' | 314 COLOR = 'BLUE' |
238 def __init__(self, *args, **kwargs): | 315 def __init__(self, *args, **kwargs): |
239 super(ns3moduleheader_taskgen, self).__init__(*args, **kwargs) | 316 super(ns3moduleheader_taskgen, self).__init__(*args, **kwargs) |
| 317 self.mode = 'install' |
240 | 318 |
241 def apply(self): | 319 def apply(self): |
242 ## get all of the ns3 headers | 320 ## get all of the ns3 headers |
243 ns3_dir_node = self.bld.path.find_dir("ns3") | 321 ns3_dir_node = self.bld.path.find_dir("ns3") |
244 all_headers_inputs = [] | 322 all_headers_inputs = [] |
245 found_the_module = False | 323 found_the_module = False |
246 for ns3headers in self.bld.all_task_gen: | 324 for ns3headers in self.bld.all_task_gen: |
247 if isinstance(ns3headers, ns3header_taskgen): | 325 if isinstance(ns3headers, ns3header_taskgen): |
248 if ns3headers.module != self.module: | 326 if ns3headers.module != self.module: |
249 continue | 327 continue |
250 found_the_module = True | 328 found_the_module = True |
251 for source in set(ns3headers.to_list(ns3headers.source)): | 329 for source in set(ns3headers.to_list(ns3headers.source)): |
252 source = os.path.basename(source) | 330 source = os.path.basename(source) |
253 node = ns3_dir_node.find_or_declare(os.path.basename(source)
) | 331 node = ns3_dir_node.find_or_declare(os.path.basename(source)
) |
254 if node is None: | 332 if node is None: |
255 fatal("missing header file %s" % (source,)) | 333 fatal("missing header file %s" % (source,)) |
256 all_headers_inputs.append(node) | 334 all_headers_inputs.append(node) |
257 if not found_the_module: | 335 if not found_the_module: |
258 raise Utils.WscriptError("error finding headers for module %s" % sel
f.module) | 336 raise Utils.WscriptError("error finding headers for module %s" % sel
f.module) |
259 if not all_headers_inputs: | 337 if not all_headers_inputs: |
260 return | 338 return |
261 module_obj = self.bld.name_to_obj("ns3-" + self.module, self.env) | |
262 assert module_obj is not None | |
263 all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self
.module)] | 339 all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self
.module)] |
264 task = self.create_task('gen_ns3_module_header', env=self.env) | 340 task = self.create_task('gen_ns3_module_header', env=self.env) |
265 task.set_inputs(all_headers_inputs) | |
266 task.set_outputs(all_headers_outputs) | |
267 task.module = self.module | 341 task.module = self.module |
268 task.module_deps = module_obj.module_deps | 342 task.mode = self.mode |
| 343 if self.mode == 'install': |
| 344 task.set_inputs(all_headers_inputs) |
| 345 task.set_outputs(all_headers_outputs) |
| 346 module_obj = self.bld.name_to_obj("ns3-" + self.module, self.env) |
| 347 assert module_obj is not None, self.module |
| 348 task.module_deps = module_obj.module_deps |
| 349 else: |
| 350 task.header_to_remove = all_headers_outputs[0] |
269 | 351 |
270 def install(self): | 352 def install(self): |
271 pass | 353 pass |
LEFT | RIGHT |