|
|
| 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 re |
| 4 |
import shutil |
5 |
import shutil |
| 5 |
import types |
6 |
import types |
| 6 |
import warnings |
7 |
import warnings |
|
|
| 73 |
module.target = module.name |
74 |
module.target = module.name |
| 74 |
module.add_objects = ['ns3-' + dep for dep in dependencies] |
75 |
module.add_objects = ['ns3-' + dep for dep in dependencies] |
| 75 |
module.module_deps = list(dependencies) |
76 |
module.module_deps = list(dependencies) |
| 76 |
module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS']) |
77 |
if not module.env['ENABLE_STATIC_NS3']: |
|
|
78 |
module.env.append_value('CXXFLAGS', module.env['shlib_CXXFLAGS']) |
| 77 |
module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION") |
79 |
module.env.append_value('CXXDEFINES', "NS3_MODULE_COMPILATION") |
| 78 |
return module |
80 |
return module |
| 79 |
|
81 |
|
|
|
| 83 |
return bld.new_task_gen(*args) |
85 |
return bld.new_task_gen(*args) |
| 84 |
|
86 |
|
| 85 |
def build(bld): |
87 |
def build(bld): |
| 86 |
#Object.register('ns3header', Ns3Header) |
|
|
| 87 |
#Action.Action('ns3header', func=_ns3_headers_inst, color='BLUE') |
| 88 |
#Object.register('ns3-module-header', Ns3ModuleHeader) |
| 89 |
#Action.Action('gen-ns3-module-header', func=gen_ns3_module_header, color='BLUE') |
| 90 |
bld.create_ns3_module = types.MethodType(create_ns3_module, bld) |
88 |
bld.create_ns3_module = types.MethodType(create_ns3_module, bld) |
| 91 |
bld.create_obj = types.MethodType(create_obj, bld) |
89 |
bld.create_obj = types.MethodType(create_obj, bld) |
| 92 |
|
90 |
|
|
|
| 95 |
for module in all_modules: |
93 |
for module in all_modules: |
| 96 |
modheader = bld.new_task_gen('ns3moduleheader') |
94 |
modheader = bld.new_task_gen('ns3moduleheader') |
| 97 |
modheader.module = module.split('/')[-1] |
95 |
modheader.module = module.split('/')[-1] |
|
|
96 |
|
| 97 |
bld.new_task_gen('all_ns3_headers') |
| 98 |
bld.new_task_gen('gen_typeid_list') |
| 98 |
|
99 |
|
| 99 |
|
100 |
|
| 100 |
class ns3header_taskgen(TaskGen.task_gen): |
101 |
class ns3header_taskgen(TaskGen.task_gen): |
|
|
| 160 |
#ifndef NS3_MODULE_%s |
161 |
#ifndef NS3_MODULE_%s |
| 161 |
""" % (self.module.upper().replace('-', '_'),) |
162 |
""" % (self.module.upper().replace('-', '_'),) |
| 162 |
|
163 |
|
| 163 |
# if self.module_deps: |
|
|
| 164 |
# print >> outfile, "// Module dependencies:" |
| 165 |
# for dep in self.module_deps: |
| 166 |
# print >> outfile, "#include \"%s-module.h\"" % dep |
| 167 |
|
| 168 |
print >> outfile |
164 |
print >> outfile |
| 169 |
print >> outfile, "// Module headers:" |
165 |
print >> outfile, "// Module headers:" |
| 170 |
for header in header_files: |
166 |
for header in header_files: |
|
|
| 227 |
|
223 |
|
| 228 |
def install(self): |
224 |
def install(self): |
| 229 |
pass |
225 |
pass |
|
|
226 |
|
| 227 |
|
| 228 |
|
| 229 |
class gen_typeid_list_task(Task.Task): |
| 230 |
before = 'cc cxx' |
| 231 |
after = 'ns3header_task gen_everything_h_task' |
| 232 |
color = 'BLUE' |
| 233 |
|
| 234 |
def run(self): |
| 235 |
assert len(self.outputs) == 1 |
| 236 |
|
| 237 |
rx = re.compile(r"class\s+(\w+)\s*:\s*public\s+(\w+)(?:\s*// namespace ([a-zA-Z:]+))?") |
| 238 |
inheritance_tree = {} # class_name => parent_class_name |
| 239 |
for header in [node.abspath(self.env) for node in self.inputs]: |
| 240 |
for line in open(header, "rt"): |
| 241 |
match = rx.match(line) |
| 242 |
if match is not None: |
| 243 |
if match.group(3): |
| 244 |
name = '::'.join([match.group(3), match.group(1)]) |
| 245 |
else: |
| 246 |
name = match.group(1) |
| 247 |
inheritance_tree[name] = match.group(2) |
| 248 |
|
| 249 |
outfile = file(self.outputs[0].bldpath(self.env), "wt") |
| 250 |
outfile.write(""" |
| 251 |
static struct GlobalTypeIdRegistrationClass |
| 252 |
{ |
| 253 |
GlobalTypeIdRegistrationClass () |
| 254 |
{ |
| 255 |
""") |
| 256 |
|
| 257 |
#print inheritance_tree |
| 258 |
def get_root_class(cls): |
| 259 |
parent = cls |
| 260 |
while 1: |
| 261 |
try: |
| 262 |
parent = inheritance_tree[parent] |
| 263 |
except KeyError: |
| 264 |
break |
| 265 |
return parent |
| 266 |
num = 0 |
| 267 |
for cls in inheritance_tree.iterkeys(): |
| 268 |
root = get_root_class(cls) |
| 269 |
if root in ['ObjectBase']: |
| 270 |
num += 1 |
| 271 |
outfile.write(""" |
| 272 |
TypeId tid%i = %s::GetTypeId (); tid%i.GetParent (); |
| 273 |
""" % (num, cls, num)) |
| 274 |
|
| 275 |
outfile.write(""" |
| 276 |
} |
| 277 |
} g_globalTypeIdRegistrationVariable; |
| 278 |
|
| 279 |
""") |
| 280 |
outfile.close() |
| 281 |
return 0 |
| 282 |
|
| 283 |
|
| 284 |
|
| 285 |
class gen_typeid_list_taskgen(TaskGen.task_gen): |
| 286 |
"""Generates a 'typeid-list.cc' header file that registers all known typeids. |
| 287 |
""" |
| 288 |
def __init__(self, *args, **kwargs): |
| 289 |
super(gen_typeid_list_taskgen, self).__init__(*args, **kwargs) |
| 290 |
self.install_path = None |
| 291 |
#self.inst_dir = 'ns3' |
| 292 |
|
| 293 |
def apply(self): |
| 294 |
## get all of the ns3 headers |
| 295 |
ns3_dir_node = Build.bld.path.find_dir("ns3") |
| 296 |
all_headers_inputs = [] |
| 297 |
|
| 298 |
for filename in self.to_list(self.source): |
| 299 |
src_node = ns3_dir_node.find_or_declare(filename) |
| 300 |
if src_node is None: |
| 301 |
raise Utils.WafError("source ns3 header file %s not found" % (filename,)) |
| 302 |
all_headers_inputs.append(src_node) |
| 303 |
|
| 304 |
## if self.source was empty, include all ns3 headers in enabled modules |
| 305 |
if not all_headers_inputs: |
| 306 |
for ns3headers in Build.bld.all_task_gen: |
| 307 |
if type(ns3headers).__name__ == 'ns3header_taskgen': # XXX: find less hackish way to compare |
| 308 |
## skip headers not part of enabled modules |
| 309 |
if self.env['NS3_ENABLED_MODULES']: |
| 310 |
if ("ns3-%s" % ns3headers.module) not in self.env['NS3_ENABLED_MODULES']: |
| 311 |
continue |
| 312 |
|
| 313 |
for source in ns3headers.to_list(ns3headers.source): |
| 314 |
#source = os.path.basename(source) |
| 315 |
node = ns3_dir_node.find_or_declare(source) |
| 316 |
if node is None: |
| 317 |
raise Utils.WafError("missing header file %s" % (source,)) |
| 318 |
all_headers_inputs.append(node) |
| 319 |
assert all_headers_inputs |
| 320 |
outputs = [self.path.find_dir("core").find_or_declare("typeid-list.cc")] |
| 321 |
task = self.create_task('gen_typeid_list', self.env) |
| 322 |
task.set_inputs(all_headers_inputs) |
| 323 |
task.set_outputs(outputs) |
| 324 |
|
| 325 |
def install(self): |
| 326 |
pass |
| 327 |
|
| 328 |
|
| 329 |
prio_headers = { |
| 330 |
-2: ( |
| 331 |
"string.h", # work around http://www.gccxml.org/Bug/view.php?id=6682 |
| 332 |
), |
| 333 |
-1: ( |
| 334 |
"propagation-delay-model.h", |
| 335 |
"propagation-loss-model.h", |
| 336 |
"net-device.h", |
| 337 |
) |
| 338 |
} |
| 339 |
|
| 340 |
def get_header_prio(header): |
| 341 |
for prio, headers in prio_headers.iteritems(): |
| 342 |
if header in headers: |
| 343 |
return prio |
| 344 |
return 1 |
| 345 |
|
| 346 |
|
| 347 |
def calc_header_include(path): |
| 348 |
(head, tail) = os.path.split (path) |
| 349 |
if tail == 'ns3': |
| 350 |
return '' |
| 351 |
else: |
| 352 |
return os.path.join (calc_header_include (head), tail) |
| 353 |
|
| 354 |
|
| 355 |
class gen_everything_h_task(Task.Task): |
| 356 |
before = 'cc cxx' |
| 357 |
after = 'ns3header_task' |
| 358 |
color = 'BLUE' |
| 359 |
|
| 360 |
def run(self): |
| 361 |
assert len(self.outputs) == 1 |
| 362 |
|
| 363 |
header_files = [calc_header_include(node.abspath(self.env)) for node in self.inputs] |
| 364 |
outfile = file(self.outputs[0].bldpath(self.env), "w") |
| 365 |
|
| 366 |
def sort_func(h1, h2): |
| 367 |
return cmp((get_header_prio(h1), h1), (get_header_prio(h1), h2)) |
| 368 |
|
| 369 |
header_files.sort(sort_func) |
| 370 |
|
| 371 |
print >> outfile, """ |
| 372 |
|
| 373 |
/* http://www.nsnam.org/bugzilla/show_bug.cgi?id=413 */ |
| 374 |
#ifdef ECHO |
| 375 |
# undef ECHO |
| 376 |
#endif |
| 377 |
|
| 378 |
""" |
| 379 |
for header in header_files: |
| 380 |
print >> outfile, "#include \"ns3/%s\"" % (header,) |
| 381 |
|
| 382 |
print >> outfile, """ |
| 383 |
namespace ns3 { |
| 384 |
static inline Ptr<Object> |
| 385 |
__dummy_function_to_force_template_instantiation (Ptr<Object> obj, TypeId typeId) |
| 386 |
{ |
| 387 |
return obj->GetObject<Object> (typeId); |
| 388 |
} |
| 389 |
|
| 390 |
|
| 391 |
static inline void |
| 392 |
__dummy_function_to_force_template_instantiation_v2 () |
| 393 |
{ |
| 394 |
Time t1, t2, t3; |
| 395 |
t1 = t2 + t3; |
| 396 |
t1 = t2 - t3; |
| 397 |
TimeSquare tsq = t2*t3; |
| 398 |
Time tsqdiv = tsq/Seconds(1); |
| 399 |
Scalar scal = t2/t3; |
| 400 |
TimeInvert inv = scal/t3; |
| 401 |
t1 = scal*t1; |
| 402 |
t1 = t1/scal; |
| 403 |
t1 < t2; |
| 404 |
t1 <= t2; |
| 405 |
t1 == t2; |
| 406 |
t1 != t2; |
| 407 |
t1 >= t2; |
| 408 |
t1 > t2; |
| 409 |
} |
| 410 |
|
| 411 |
|
| 412 |
} |
| 413 |
""" |
| 414 |
outfile.close() |
| 415 |
return 0 |
| 416 |
|
| 417 |
|
| 418 |
|
| 419 |
class all_ns3_headers_taskgen(TaskGen.task_gen): |
| 420 |
"""Generates a 'everything.h' header file that includes some/all public ns3 headers. |
| 421 |
""" |
| 422 |
def __init__(self, *args, **kwargs): |
| 423 |
super(all_ns3_headers_taskgen, self).__init__(*args, **kwargs) |
| 424 |
self.install_path = None |
| 425 |
#self.inst_dir = 'ns3' |
| 426 |
|
| 427 |
def apply(self): |
| 428 |
## get all of the ns3 headers |
| 429 |
ns3_dir_node = Build.bld.path.find_dir("ns3") |
| 430 |
all_headers_inputs = [] |
| 431 |
|
| 432 |
for filename in self.to_list(self.source): |
| 433 |
src_node = ns3_dir_node.find_or_declare(filename) |
| 434 |
if src_node is None: |
| 435 |
raise Utils.WafError("source ns3 header file %s not found" % (filename,)) |
| 436 |
all_headers_inputs.append(src_node) |
| 437 |
|
| 438 |
## if self.source was empty, include all ns3 headers in enabled modules |
| 439 |
if not all_headers_inputs: |
| 440 |
for ns3headers in Build.bld.all_task_gen: |
| 441 |
if type(ns3headers).__name__ == 'ns3header_taskgen': # XXX: find less hackish way to compare |
| 442 |
## skip headers not part of enabled modules |
| 443 |
if self.env['NS3_ENABLED_MODULES']: |
| 444 |
if ("ns3-%s" % ns3headers.module) not in self.env['NS3_ENABLED_MODULES']: |
| 445 |
continue |
| 446 |
|
| 447 |
for source in ns3headers.to_list(ns3headers.source): |
| 448 |
#source = os.path.basename(source) |
| 449 |
node = ns3_dir_node.find_or_declare(source) |
| 450 |
if node is None: |
| 451 |
raise Utils.WafError("missing header file %s" % (source,)) |
| 452 |
all_headers_inputs.append(node) |
| 453 |
assert all_headers_inputs |
| 454 |
all_headers_outputs = [Build.bld.path.find_dir('ns3').find_or_declare("everything.h")] |
| 455 |
task = self.create_task('gen_everything_h', self.env) |
| 456 |
task.set_inputs(all_headers_inputs) |
| 457 |
task.set_outputs(all_headers_outputs) |
| 458 |
|
| 459 |
def install(self): |
| 460 |
pass |
| 461 |
|