|
|
| 1 |
|
|
|
| 2 |
## -*- 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; -*- |
| 3 |
from __future__ import print_function |
2 |
from __future__ import print_function |
| 4 |
import os, os.path |
3 |
import os, os.path |
|
|
| 16 |
except NameError: |
15 |
except NameError: |
| 17 |
from sets import Set as set # Python 2.3 fallback |
16 |
from sets import Set as set # Python 2.3 fallback |
| 18 |
|
17 |
|
| 19 |
|
18 |
all_contrib_modules = [] |
| 20 |
|
|
|
| 21 |
all_modules = [] |
| 22 |
for dirname in os.listdir('contrib'): |
19 |
for dirname in os.listdir('contrib'): |
| 23 |
if dirname.startswith('.') or dirname == 'CVS': |
20 |
if dirname.startswith('.') or dirname == 'CVS': |
| 24 |
continue |
21 |
continue |
|
|
| 26 |
if not os.path.isdir(path): |
23 |
if not os.path.isdir(path): |
| 27 |
continue |
24 |
continue |
| 28 |
if os.path.exists(os.path.join(path, 'wscript')): |
25 |
if os.path.exists(os.path.join(path, 'wscript')): |
| 29 |
all_modules.append(dirname) |
26 |
all_contrib_modules.append(dirname) |
| 30 |
all_modules.sort() |
27 |
all_contrib_modules.sort() |
| 31 |
|
|
|
| 32 |
|
| 33 |
|
28 |
|
| 34 |
def options(opt): |
29 |
def options(opt): |
| 35 |
opt.add_option('--enable-rpath', |
30 |
for module in all_contrib_modules: |
| 36 |
help=("Link programs with rpath" |
|
|
| 37 |
" (normally not needed, see " |
| 38 |
" --run and --shell; moreover, only works in some" |
| 39 |
" specific platforms, such as Linux and Solaris)"), |
| 40 |
action="store_true", dest='enable_rpath', default=False) |
| 41 |
|
| 42 |
opt.add_option('--enable-modules', |
| 43 |
help=("Build only these modules (and dependencies)"), |
| 44 |
dest='enable_modules') |
| 45 |
|
| 46 |
opt.load('boost', tooldir=['waf-tools']) |
| 47 |
|
| 48 |
for module in all_modules: |
| 49 |
opt.recurse(module, mandatory=False) |
31 |
opt.recurse(module, mandatory=False) |
| 50 |
|
32 |
|
| 51 |
def configure(conf): |
33 |
def configure(conf): |
| 52 |
if not conf.env['REQUIRED_BOOST_LIBS']: |
34 |
for module in all_contrib_modules: |
| 53 |
conf.env['REQUIRED_BOOST_LIBS'] = [] |
|
|
| 54 |
for module in all_modules: |
| 55 |
conf.recurse (module, name="required_boost_libs", mandatory=False) |
| 56 |
|
| 57 |
if conf.env['REQUIRED_BOOST_LIBS'] is not []: |
| 58 |
conf.load('boost') |
| 59 |
conf.check_boost(lib=' '.join (conf.env['REQUIRED_BOOST_LIBS']), mandatory=False) |
| 60 |
if not conf.env['LIB_BOOST']: |
| 61 |
conf.check_boost(lib=' '.join (conf.env['REQUIRED_BOOST_LIBS']), libpath="/usr/lib64", mandatory=False) |
| 62 |
if not conf.env['LIB_BOOST']: |
| 63 |
conf.env['LIB_BOOST'] = [] |
| 64 |
|
| 65 |
# Append blddir to the module path before recursing into modules |
| 66 |
blddir = os.path.abspath(os.path.join(conf.bldnode.abspath(), conf.variant)) |
| 67 |
conf.env.append_value('NS3_MODULE_PATH', blddir) |
| 68 |
|
| 69 |
for module in all_modules: |
| 70 |
conf.recurse(module, mandatory=False) |
35 |
conf.recurse(module, mandatory=False) |
| 71 |
|
36 |
|
| 72 |
# Remove duplicate path items |
|
|
| 73 |
conf.env['NS3_MODULE_PATH'] = wutils.uniquify_list(conf.env['NS3_MODULE_PATH']) |
| 74 |
|
| 75 |
if Options.options.enable_rpath: |
| 76 |
conf.env.append_value('RPATH', '-Wl,-rpath,%s' % (os.path.join(blddir),)) |
| 77 |
|
| 78 |
## Used to link the 'test-runner' program with all of ns-3 code |
37 |
## Used to link the 'test-runner' program with all of ns-3 code |
| 79 |
conf.env['NS3_CONTRIBUTED_MODULES'] = ['ns3-' + module.split('/')[-1] for module in all_modules] |
38 |
conf.env['NS3_CONTRIBUTED_MODULES'] = ['ns3-' + module.split('/')[-1] for module in all_contrib_modules] |
| 80 |
|
|
|
| 81 |
|
39 |
|
| 82 |
|
40 |
|
| 83 |
# we need the 'ns3module' waf "feature" to be created because code |
41 |
# we need the 'ns3module' waf "feature" to be created because code |
| 84 |
# elsewhere looks for it to find the ns3 module objects. |
42 |
# elsewhere looks for it to find the ns3 module objects. |
| 85 |
@TaskGen.feature('ns3module') |
|
|
| 86 |
def _add_test_code(module): |
| 87 |
pass |
| 88 |
|
43 |
|
| 89 |
def create_ns3_module(bld, name, dependencies=(), test=False): |
44 |
def create_ns3_module(bld, name, dependencies=(), test=False): |
| 90 |
static = bool(bld.env.ENABLE_STATIC_NS3) |
45 |
static = bool(bld.env.ENABLE_STATIC_NS3) |
|
|
| 143 |
|
98 |
|
| 144 |
return module |
99 |
return module |
| 145 |
|
100 |
|
| 146 |
@TaskGen.feature("ns3testlib") |
|
|
| 147 |
@TaskGen.before_method("apply_incpaths") |
| 148 |
def apply_incpaths_ns3testlib(self): |
| 149 |
if not self.source: |
| 150 |
return |
| 151 |
testdir = self.source[-1].parent.path_from(self.bld.srcnode) |
| 152 |
self.env.append_value("DEFINES", 'NS_TEST_SOURCEDIR="%s"' % (testdir,)) |
| 153 |
|
| 154 |
|
| 155 |
def create_ns3_module_test_library(bld, name): |
101 |
def create_ns3_module_test_library(bld, name): |
| 156 |
# Create an ns3 module for the test library that depends only on |
102 |
# Create an ns3 module for the test library that depends only on |
| 157 |
# the module being tested. |
103 |
# the module being tested. |
|
|
| 183 |
|
129 |
|
| 184 |
|
130 |
|
| 185 |
def ns3_python_bindings(bld): |
131 |
def ns3_python_bindings(bld): |
| 186 |
|
|
|
| 187 |
# this method is called from a module wscript, so remember bld.path is not bindings/python! |
132 |
# this method is called from a module wscript, so remember bld.path is not bindings/python! |
| 188 |
module_abs_src_path = bld.path.abspath() |
133 |
module_abs_src_path = bld.path.abspath() |
| 189 |
module = os.path.basename(module_abs_src_path) |
134 |
module = os.path.basename(module_abs_src_path) |
|
|
| 305 |
|
250 |
|
| 306 |
return pymod |
251 |
return pymod |
| 307 |
|
252 |
|
| 308 |
|
|
|
| 309 |
def build(bld): |
253 |
def build(bld): |
| 310 |
bld.create_ns3_module = types.MethodType(create_ns3_module, bld) |
254 |
bld.create_ns3_module = types.MethodType(create_ns3_module, bld) |
| 311 |
bld.create_ns3_module_test_library = types.MethodType(create_ns3_module_test_library, bld) |
255 |
bld.create_ns3_module_test_library = types.MethodType(create_ns3_module_test_library, bld) |
|
|
| 315 |
# Remove these modules from the list of all modules. |
259 |
# Remove these modules from the list of all modules. |
| 316 |
for not_built in bld.env['MODULES_NOT_BUILT']: |
260 |
for not_built in bld.env['MODULES_NOT_BUILT']: |
| 317 |
|
261 |
|
| 318 |
# XXX Because these modules are located in subdirectories of |
262 |
if not_built in all_contrib_modules: |
| 319 |
# test, their names in the all_modules list include the extra |
263 |
all_contrib_modules.remove(not_built) |
| 320 |
# relative path "test/". If these modules are moved into the |
|
|
| 321 |
# src directory, then this if block should be removed. |
| 322 |
if not_built == 'ns3tcp' or not_built == 'ns3wifi': |
| 323 |
not_built = 'test/' + not_built |
| 324 |
|
264 |
|
| 325 |
if not_built in all_modules: |
265 |
bld.recurse(list(all_contrib_modules)) |
| 326 |
all_modules.remove(not_built) |
|
|
| 327 |
|
266 |
|
| 328 |
bld.recurse(list(all_modules)) |
267 |
for module in all_contrib_modules: |
| 329 |
|
|
|
| 330 |
for module in all_modules: |
| 331 |
modheader = bld(features='ns3moduleheader') |
268 |
modheader = bld(features='ns3moduleheader') |
| 332 |
modheader.module = module.split('/')[-1] |
269 |
modheader.module = module.split('/')[-1] |
| 333 |
|
270 |
|
| 334 |
class ns3pcfile_task(Task.Task): |
|
|
| 335 |
after = 'cxx' |
| 336 |
|
| 337 |
def __str__(self): |
| 338 |
"string to display to the user" |
| 339 |
tgt_str = ' '.join([a.bldpath() for a in self.outputs]) |
| 340 |
return 'pcfile: %s\n' % (tgt_str) |
| 341 |
|
| 342 |
def runnable_status(self): |
| 343 |
return super(ns3pcfile_task, self).runnable_status() |
| 344 |
|
| 345 |
def _self_libs(self, env, name, libdir): |
| 346 |
if env['ENABLE_STATIC_NS3']: |
| 347 |
path_st = 'STLIBPATH_ST' |
| 348 |
lib_st = 'STLIB_ST' |
| 349 |
lib_marker = 'STLIB_MARKER' |
| 350 |
else: |
| 351 |
path_st = 'LIBPATH_ST' |
| 352 |
lib_st = 'LIB_ST' |
| 353 |
lib_marker = 'SHLIB_MARKER' |
| 354 |
retval = [env[path_st] % libdir] |
| 355 |
if env[lib_marker]: |
| 356 |
retval.append(env[lib_marker]) |
| 357 |
retval.append(env[lib_st] % name) |
| 358 |
return retval |
| 359 |
|
| 360 |
def _lib(self, env, dep): |
| 361 |
libpath = env['LIBPATH_%s' % dep] |
| 362 |
linkflags = env['LINKFLAGS_%s' % dep] |
| 363 |
libs = env['LIB_%s' % dep] |
| 364 |
retval = [] |
| 365 |
for path in libpath: |
| 366 |
retval.append(env['LIBPATH_ST'] % path) |
| 367 |
retval = retval + linkflags |
| 368 |
for lib in libs: |
| 369 |
retval.append(env['LIB_ST'] % lib) |
| 370 |
return retval |
| 371 |
|
| 372 |
def _listify(self, v): |
| 373 |
if isinstance(v, list): |
| 374 |
return v |
| 375 |
else: |
| 376 |
return [v] |
| 377 |
|
| 378 |
def _cflags(self, dep): |
| 379 |
flags = self.env['CFLAGS_%s' % dep] |
| 380 |
return self._listify(flags) |
| 381 |
|
| 382 |
def _cxxflags(self, dep): |
| 383 |
return self._listify(self.env['CXXFLAGS_%s' % dep]) |
| 384 |
|
| 385 |
def _defines(self, dep): |
| 386 |
return [self.env['DEFINES_ST'] % define for define in self.env['DEFINES_%s' % dep]] |
| 387 |
|
| 388 |
def _includes(self, dep): |
| 389 |
includes = self.env['INCLUDES_%s' % dep] |
| 390 |
return [self.env['CPPPATH_ST'] % include for include in includes] |
| 391 |
|
| 392 |
def _generate_pcfile(self, name, use, env, outfilename): |
| 393 |
outfile = open(outfilename, 'wt') |
| 394 |
prefix = env.PREFIX |
| 395 |
includedir = Utils.subst_vars('${INCLUDEDIR}/%s%s' % (wutils.APPNAME, wutils.VERSION), env) |
| 396 |
libdir = env.LIBDIR |
| 397 |
libs = self._self_libs(env, "%s%s-%s%s" % (wutils.APPNAME, wutils.VERSION, name[4:], env.BUILD_SUFFIX), '${libdir}') |
| 398 |
for dep in use: |
| 399 |
libs += self._lib(env, dep) |
| 400 |
for dep in env.LIBS: |
| 401 |
libs += self.env['LIB_ST'] % dep |
| 402 |
cflags = [self.env['CPPPATH_ST'] % '${includedir}'] |
| 403 |
requires = [] |
| 404 |
for dep in use: |
| 405 |
cflags = cflags + self._cflags(dep) + self._cxxflags(dep) + \ |
| 406 |
self._defines(dep) + self._includes(dep) |
| 407 |
if dep.startswith('ns3-'): |
| 408 |
dep_name = dep[4:] |
| 409 |
requires.append("libns%s-%s%s" % (wutils.VERSION, dep_name, env.BUILD_SUFFIX)) |
| 410 |
print("""\ |
| 411 |
prefix=%s |
| 412 |
libdir=%s |
| 413 |
includedir=%s |
| 414 |
|
| 415 |
Name: lib%s |
| 416 |
Description: ns-3 module %s |
| 417 |
Version: %s |
| 418 |
Libs: %s |
| 419 |
Cflags: %s |
| 420 |
Requires: %s\ |
| 421 |
""" % (prefix, libdir, includedir, |
| 422 |
name, name, wutils.VERSION, ' '.join(libs), ' '.join(cflags), ' '.join(requires)), file=outfile) |
| 423 |
outfile.close() |
| 424 |
|
| 425 |
def run(self): |
| 426 |
output_filename = self.outputs[0].abspath() |
| 427 |
self._generate_pcfile(self.module.name, |
| 428 |
self.module.to_list(self.module.use), |
| 429 |
self.env, output_filename) |
| 430 |
|
| 431 |
|
| 432 |
@TaskGen.feature('ns3pcfile') |
| 433 |
@TaskGen.after_method('process_rule') |
| 434 |
def apply(self): |
| 435 |
module = self.bld.find_ns3_module(self.module) |
| 436 |
output_filename = 'lib%s.pc' % os.path.basename(module.target) |
| 437 |
output_node = self.path.find_or_declare(output_filename) |
| 438 |
assert output_node is not None, str(self) |
| 439 |
task = self.create_task('ns3pcfile') |
| 440 |
self.bld.install_files('${LIBDIR}/pkgconfig', output_node) |
| 441 |
task.set_outputs([output_node]) |
| 442 |
task.module = module |
| 443 |
|
| 444 |
|
| 445 |
|
| 446 |
@TaskGen.feature('ns3header') |
| 447 |
@TaskGen.after_method('process_rule') |
| 448 |
def apply_ns3header(self): |
| 449 |
if self.module is None: |
| 450 |
raise WafError("'module' missing on ns3headers object %s" % self) |
| 451 |
ns3_dir_node = self.bld.path.find_or_declare("ns3") |
| 452 |
for filename in set(self.to_list(self.source)): |
| 453 |
src_node = self.path.find_resource(filename) |
| 454 |
if src_node is None: |
| 455 |
raise WafError("source ns3 header file %s not found" % (filename,)) |
| 456 |
dst_node = ns3_dir_node.find_or_declare(src_node.name) |
| 457 |
assert dst_node is not None |
| 458 |
task = self.create_task('ns3header') |
| 459 |
task.mode = getattr(self, 'mode', 'install') |
| 460 |
if task.mode == 'install': |
| 461 |
self.bld.install_files('${INCLUDEDIR}/%s%s/ns3' % (wutils.APPNAME, wutils.VERSION), [src_node]) |
| 462 |
task.set_inputs([src_node]) |
| 463 |
task.set_outputs([dst_node]) |
| 464 |
else: |
| 465 |
task.header_to_remove = dst_node |
| 466 |
self.headers = set(self.to_list(self.source)) |
| 467 |
self.source = '' # tell WAF not to process these files further |
| 468 |
|
| 469 |
|
| 470 |
class ns3header_task(Task.Task): |
| 471 |
before = 'cxx gen_ns3_module_header' |
| 472 |
color = 'BLUE' |
| 473 |
|
| 474 |
def __str__(self): |
| 475 |
"string to display to the user" |
| 476 |
env = self.env |
| 477 |
src_str = ' '.join([a.bldpath() for a in self.inputs]) |
| 478 |
tgt_str = ' '.join([a.bldpath() for a in self.outputs]) |
| 479 |
if self.outputs: sep = ' -> ' |
| 480 |
else: sep = '' |
| 481 |
if self.mode == 'remove': |
| 482 |
return 'rm-ns3-header %s' % (self.header_to_remove.abspath(),) |
| 483 |
return 'install-ns3-header: %s' % (tgt_str) |
| 484 |
|
| 485 |
def __repr__(self): |
| 486 |
return str(self) |
| 487 |
|
| 488 |
def uid(self): |
| 489 |
try: |
| 490 |
return self.uid_ |
| 491 |
except AttributeError: |
| 492 |
m = Utils.md5() |
| 493 |
up = m.update |
| 494 |
up(self.__class__.__name__.encode()) |
| 495 |
for x in self.inputs + self.outputs: |
| 496 |
up(x.abspath().encode()) |
| 497 |
up(self.mode.encode()) |
| 498 |
if self.mode == 'remove': |
| 499 |
up(self.header_to_remove.abspath().encode()) |
| 500 |
self.uid_ = m.digest() |
| 501 |
return self.uid_ |
| 502 |
|
| 503 |
def runnable_status(self): |
| 504 |
if self.mode == 'remove': |
| 505 |
if os.path.exists(self.header_to_remove.abspath()): |
| 506 |
return Task.RUN_ME |
| 507 |
else: |
| 508 |
return Task.SKIP_ME |
| 509 |
else: |
| 510 |
return super(ns3header_task, self).runnable_status() |
| 511 |
|
| 512 |
def run(self): |
| 513 |
if self.mode == 'install': |
| 514 |
assert len(self.inputs) == len(self.outputs) |
| 515 |
inputs = [node.abspath() for node in self.inputs] |
| 516 |
outputs = [node.abspath() for node in self.outputs] |
| 517 |
for src, dst in zip(inputs, outputs): |
| 518 |
try: |
| 519 |
os.chmod(dst, 0o600) |
| 520 |
except OSError: |
| 521 |
pass |
| 522 |
shutil.copy2(src, dst) |
| 523 |
## make the headers in builddir read-only, to prevent |
| 524 |
## accidental modification |
| 525 |
os.chmod(dst, 0o400) |
| 526 |
return 0 |
| 527 |
else: |
| 528 |
assert len(self.inputs) == 0 |
| 529 |
assert len(self.outputs) == 0 |
| 530 |
out_file_name = self.header_to_remove.abspath() |
| 531 |
try: |
| 532 |
os.unlink(out_file_name) |
| 533 |
except OSError as ex: |
| 534 |
if ex.errno != 2: |
| 535 |
raise |
| 536 |
return 0 |
| 537 |
|
| 538 |
|
| 539 |
@TaskGen.feature('ns3privateheader') |
| 540 |
@TaskGen.after_method('process_rule') |
| 541 |
def apply_ns3privateheader(self): |
| 542 |
if self.module is None: |
| 543 |
raise WafError("'module' missing on ns3headers object %s" % self) |
| 544 |
ns3_dir_node = self.bld.path.find_or_declare("ns3/private") |
| 545 |
for filename in set(self.to_list(self.source)): |
| 546 |
src_node = self.path.find_resource(filename) |
| 547 |
if src_node is None: |
| 548 |
raise WafError("source ns3 header file %s not found" % (filename,)) |
| 549 |
dst_node = ns3_dir_node.find_or_declare(src_node.name) |
| 550 |
assert dst_node is not None |
| 551 |
task = self.create_task('ns3privateheader') |
| 552 |
task.mode = getattr(self, 'mode', 'install') |
| 553 |
if task.mode == 'install': |
| 554 |
task.set_inputs([src_node]) |
| 555 |
task.set_outputs([dst_node]) |
| 556 |
else: |
| 557 |
task.header_to_remove = dst_node |
| 558 |
self.headers = set(self.to_list(self.source)) |
| 559 |
self.source = '' # tell WAF not to process these files further |
| 560 |
|
| 561 |
class ns3privateheader_task(Task.Task): |
| 562 |
before = 'cxx gen_ns3_module_header' |
| 563 |
after = 'ns3header' |
| 564 |
color = 'BLUE' |
| 565 |
|
| 566 |
def __str__(self): |
| 567 |
"string to display to the user" |
| 568 |
env = self.env |
| 569 |
src_str = ' '.join([a.bldpath() for a in self.inputs]) |
| 570 |
tgt_str = ' '.join([a.bldpath() for a in self.outputs]) |
| 571 |
if self.outputs: sep = ' -> ' |
| 572 |
else: sep = '' |
| 573 |
if self.mode == 'remove': |
| 574 |
return 'rm-ns3-header %s' % (self.header_to_remove.abspath(),) |
| 575 |
return 'install-ns3-header: %s' % (tgt_str) |
| 576 |
|
| 577 |
def __repr__(self): |
| 578 |
return str(self) |
| 579 |
|
| 580 |
def uid(self): |
| 581 |
try: |
| 582 |
return self.uid_ |
| 583 |
except AttributeError: |
| 584 |
m = Utils.md5() |
| 585 |
up = m.update |
| 586 |
up(self.__class__.__name__.encode()) |
| 587 |
for x in self.inputs + self.outputs: |
| 588 |
up(x.abspath().encode()) |
| 589 |
up(self.mode.encode()) |
| 590 |
if self.mode == 'remove': |
| 591 |
up(self.header_to_remove.abspath().encode()) |
| 592 |
self.uid_ = m.digest() |
| 593 |
return self.uid_ |
| 594 |
|
| 595 |
def runnable_status(self): |
| 596 |
if self.mode == 'remove': |
| 597 |
if os.path.exists(self.header_to_remove.abspath()): |
| 598 |
return Task.RUN_ME |
| 599 |
else: |
| 600 |
return Task.SKIP_ME |
| 601 |
else: |
| 602 |
return super(ns3privateheader_task, self).runnable_status() |
| 603 |
|
| 604 |
def run(self): |
| 605 |
if self.mode == 'install': |
| 606 |
assert len(self.inputs) == len(self.outputs) |
| 607 |
inputs = [node.abspath() for node in self.inputs] |
| 608 |
outputs = [node.abspath() for node in self.outputs] |
| 609 |
for src, dst in zip(inputs, outputs): |
| 610 |
try: |
| 611 |
os.chmod(dst, 0o600) |
| 612 |
except OSError: |
| 613 |
pass |
| 614 |
shutil.copy2(src, dst) |
| 615 |
## make the headers in builddir read-only, to prevent |
| 616 |
## accidental modification |
| 617 |
os.chmod(dst, 0o400) |
| 618 |
return 0 |
| 619 |
else: |
| 620 |
assert len(self.inputs) == 0 |
| 621 |
assert len(self.outputs) == 0 |
| 622 |
out_file_name = self.header_to_remove.abspath() |
| 623 |
try: |
| 624 |
os.unlink(out_file_name) |
| 625 |
except OSError as ex: |
| 626 |
if ex.errno != 2: |
| 627 |
raise |
| 628 |
return 0 |
| 629 |
|
| 630 |
|
| 631 |
class gen_ns3_module_header_task(Task.Task): |
| 632 |
before = 'cxx' |
| 633 |
after = 'ns3header' |
| 634 |
color = 'BLUE' |
| 635 |
|
| 636 |
def runnable_status(self): |
| 637 |
if self.mode == 'remove': |
| 638 |
if os.path.exists(self.header_to_remove.abspath()): |
| 639 |
return Task.RUN_ME |
| 640 |
else: |
| 641 |
return Task.SKIP_ME |
| 642 |
else: |
| 643 |
return super(gen_ns3_module_header_task, self).runnable_status() |
| 644 |
|
| 645 |
def __str__(self): |
| 646 |
"string to display to the user" |
| 647 |
env = self.env |
| 648 |
src_str = ' '.join([a.bldpath() for a in self.inputs]) |
| 649 |
tgt_str = ' '.join([a.bldpath() for a in self.outputs]) |
| 650 |
if self.outputs: sep = ' -> ' |
| 651 |
else: sep = '' |
| 652 |
if self.mode == 'remove': |
| 653 |
return 'rm-module-header %s' % (self.header_to_remove.abspath(),) |
| 654 |
return 'gen-module-header: %s' % (tgt_str) |
| 655 |
|
| 656 |
def run(self): |
| 657 |
if self.mode == 'remove': |
| 658 |
assert len(self.inputs) == 0 |
| 659 |
assert len(self.outputs) == 0 |
| 660 |
out_file_name = self.header_to_remove.abspath() |
| 661 |
try: |
| 662 |
os.unlink(out_file_name) |
| 663 |
except OSError as ex: |
| 664 |
if ex.errno != 2: |
| 665 |
raise |
| 666 |
return 0 |
| 667 |
assert len(self.outputs) == 1 |
| 668 |
out_file_name = self.outputs[0].get_bld().abspath()#self.env) |
| 669 |
header_files = [os.path.basename(node.abspath()) for node in self.inputs] |
| 670 |
outfile = open(out_file_name, "w") |
| 671 |
header_files.sort() |
| 672 |
|
| 673 |
print(""" |
| 674 |
#ifdef NS3_MODULE_COMPILATION |
| 675 |
# error "Do not include ns3 module aggregator headers from other modules; these are meant only for end user scripts." |
| 676 |
#endif |
| 677 |
|
| 678 |
#ifndef NS3_MODULE_%s |
| 679 |
""" % (self.module.upper().replace('-', '_'),), file=outfile) |
| 680 |
|
| 681 |
# if self.module_deps: |
| 682 |
# print >> outfile, "// Module dependencies:" |
| 683 |
# for dep in self.module_deps: |
| 684 |
# print >> outfile, "#include \"%s-module.h\"" % dep |
| 685 |
|
| 686 |
print(file=outfile) |
| 687 |
print("// Module headers:", file=outfile) |
| 688 |
for header in header_files: |
| 689 |
print("#include \"%s\"" % (header,), file=outfile) |
| 690 |
|
| 691 |
print("#endif", file=outfile) |
| 692 |
|
| 693 |
outfile.close() |
| 694 |
return 0 |
| 695 |
|
| 696 |
def sig_explicit_deps(self): |
| 697 |
self.m.update('\n'.join(sorted([node.abspath() for node in self.inputs])).encode('utf-8')) |
| 698 |
return self.m.digest() |
| 699 |
|
| 700 |
def unique_id(self): |
| 701 |
try: |
| 702 |
return self.uid |
| 703 |
except AttributeError: |
| 704 |
"this is not a real hot zone, but we want to avoid surprizes here" |
| 705 |
m = Utils.md5() |
| 706 |
m.update("ns-3-module-header-%s" % self.module) |
| 707 |
self.uid = m.digest() |
| 708 |
return self.uid |
| 709 |
|
| 710 |
|
| 711 |
# Generates a 'ns3/foo-module.h' header file that includes all public |
| 712 |
# ns3 headers of a certain module. |
| 713 |
@TaskGen.feature('ns3moduleheader') |
| 714 |
@TaskGen.after_method('process_rule') |
| 715 |
def apply_ns3moduleheader(self): |
| 716 |
## get all of the ns3 headers |
| 717 |
ns3_dir_node = self.bld.path.find_or_declare("ns3") |
| 718 |
all_headers_inputs = [] |
| 719 |
found_the_module = False |
| 720 |
for ns3headers in self.bld.all_task_gen: |
| 721 |
if 'ns3header' in getattr(ns3headers, "features", []): |
| 722 |
if ns3headers.module != self.module: |
| 723 |
continue |
| 724 |
found_the_module = True |
| 725 |
for source in sorted(ns3headers.headers): |
| 726 |
source = os.path.basename(source) |
| 727 |
node = ns3_dir_node.find_or_declare(os.path.basename(source)) |
| 728 |
if node is None: |
| 729 |
fatal("missing header file %s" % (source,)) |
| 730 |
all_headers_inputs.append(node) |
| 731 |
if not found_the_module: |
| 732 |
raise WafError("error finding headers for module %s" % self.module) |
| 733 |
if not all_headers_inputs: |
| 734 |
return |
| 735 |
|
| 736 |
try: |
| 737 |
module_obj = self.bld.get_tgen_by_name("ns3-" + self.module) |
| 738 |
except WafError: # maybe the module was disabled, and therefore removed |
| 739 |
return |
| 740 |
|
| 741 |
all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self.module)] |
| 742 |
task = self.create_task('gen_ns3_module_header') |
| 743 |
task.module = self.module |
| 744 |
task.mode = getattr(self, "mode", "install") |
| 745 |
if task.mode == 'install': |
| 746 |
assert module_obj is not None, self.module |
| 747 |
self.bld.install_files('${INCLUDEDIR}/%s%s/ns3' % (wutils.APPNAME, wutils.VERSION), |
| 748 |
ns3_dir_node.find_or_declare("%s-module.h" % self.module)) |
| 749 |
task.set_inputs(all_headers_inputs) |
| 750 |
task.set_outputs(all_headers_outputs) |
| 751 |
task.module_deps = module_obj.module_deps |
| 752 |
else: |
| 753 |
task.header_to_remove = all_headers_outputs[0] |