Darth_Malgus

Untitled

Sep 21st, 2023
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.30 KB | None | 0 0
  1. ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
  2. from __future__ import print_function
  3. import os, os.path
  4. import sys
  5. import shutil
  6. import types
  7. import warnings
  8.  
  9. from waflib import TaskGen, Task, Options, Build, Utils
  10. from waflib.Errors import WafError
  11. import wutils
  12.  
  13. try:
  14. set
  15. except NameError:
  16. from sets import Set as set # Python 2.3 fallback
  17.  
  18.  
  19.  
  20. all_modules = []
  21. for dirname in os.listdir('src'):
  22. if dirname.startswith('.') or dirname == 'CVS':
  23. continue
  24. path = os.path.join('src', dirname)
  25. if not os.path.isdir(path):
  26. continue
  27. if os.path.exists(os.path.join(path, 'wscript')):
  28. all_modules.append(dirname)
  29. all_modules.sort()
  30.  
  31. def get_required_boost_libs(conf):
  32. for module in all_modules:
  33. conf.recurse (module, name="required_boost_libs", mandatory=False)
  34.  
  35. def options(opt):
  36. opt.add_option('--enable-rpath',
  37. help=("Link programs with rpath"
  38. " (normally not needed, see "
  39. " --run and --shell; moreover, only works in some"
  40. " specific platforms, such as Linux and Solaris)"),
  41. action="store_true", dest='enable_rpath', default=False)
  42.  
  43. opt.add_option('--enable-modules',
  44. help=("Build only these modules (and dependencies)"),
  45. dest='enable_modules')
  46.  
  47. opt.load('boost', tooldir=['waf-tools'])
  48.  
  49. for module in all_modules:
  50. opt.recurse(module, mandatory=False)
  51.  
  52. def configure(conf):
  53.  
  54. # Add Crypto++ module
  55. # New Code
  56. bld = conf.bld
  57. # New Code
  58.  
  59. # New Code
  60. bld.recurse('contrib/cryptopp')
  61. bld.env.prepend_value('INCLUDES', ['contrib/cryptopp'])
  62. # New Code
  63.  
  64. # Append blddir to the module path before recursing into modules
  65. blddir = os.path.abspath(os.path.join(conf.bldnode.abspath(), conf.variant))
  66. conf.env.append_value('NS3_MODULE_PATH', blddir + "/lib")
  67.  
  68. for module in all_modules:
  69. conf.recurse(module, mandatory=False)
  70.  
  71. # Remove duplicate path items
  72. conf.env['NS3_MODULE_PATH'] = wutils.uniquify_list(conf.env['NS3_MODULE_PATH'])
  73.  
  74. if Options.options.enable_rpath:
  75. conf.env.append_value('RPATH', '-Wl,-rpath,%s' % (os.path.join(blddir),))
  76.  
  77. ## Used to link the 'test-runner' program with all of ns-3 code
  78. conf.env['NS3_MODULES'] = ['ns3-' + module.split('/')[-1] for module in all_modules]
  79.  
  80.  
  81.  
  82. # we need the 'ns3module' waf "feature" to be created because code
  83. # elsewhere looks for it to find the ns3 module objects.
  84. @TaskGen.feature('ns3module')
  85. def _add_test_code(module):
  86. pass
  87.  
  88. def create_ns3_module(bld, name, dependencies=(), test=False):
  89. static = bool(bld.env.ENABLE_STATIC_NS3)
  90. # Create a separate library for this module.
  91. if static:
  92. module = bld(features='cxx cxxstlib ns3module')
  93. else:
  94. module = bld(features='cxx cxxshlib ns3module')
  95. module.target = '%s/lib/ns%s-%s%s' % (bld.srcnode.path_from(module.path), wutils.VERSION,
  96. name, bld.env.BUILD_SUFFIX)
  97. linkflags = []
  98. cxxflags = []
  99. ccflags = []
  100. if not static:
  101. cxxflags = module.env['shlib_CXXFLAGS']
  102. ccflags = module.env['shlib_CXXFLAGS']
  103. # Turn on the link flags for shared libraries if we have the
  104. # proper compiler and platform.
  105. if module.env['CXX_NAME'] in ['gcc', 'icc'] and module.env['WL_SONAME_SUPPORTED']:
  106. # Get the module library name without any relative paths
  107. # at its beginning because all of the libraries will end
  108. # up in the same directory.
  109. module_library_name = module.env.cshlib_PATTERN % (os.path.basename(module.target),)
  110. linkflags = '-Wl,--soname=' + module_library_name
  111. cxxdefines = ["NS3_MODULE_COMPILATION"]
  112. ccdefines = ["NS3_MODULE_COMPILATION"]
  113.  
  114. module.env.append_value('CXXFLAGS', cxxflags)
  115. module.env.append_value('CCFLAGS', ccflags)
  116. module.env.append_value('LINKFLAGS', linkflags)
  117. module.env.append_value('CXXDEFINES', cxxdefines)
  118. module.env.append_value('CCDEFINES', ccdefines)
  119.  
  120. module.is_static = static
  121. module.vnum = wutils.VNUM
  122. # Add the proper path to the module's name.
  123. # Set the libraries this module depends on.
  124. module.module_deps = list(dependencies)
  125.  
  126. module.install_path = "${LIBDIR}"
  127.  
  128. module.name = "ns3-" + name
  129. module.dependencies = dependencies
  130. # Initially create an empty value for this because the pcfile
  131. # writing task assumes every module has a uselib attribute.
  132. module.uselib = ''
  133. module.use = ['ns3-' + dep for dep in dependencies]
  134. module.test = test
  135. module.is_ns3_module = True
  136. module.ns3_dir_location = bld.path.path_from(bld.srcnode)
  137.  
  138. module.env.append_value("INCLUDES", '#')
  139.  
  140. module.pcfilegen = bld(features='ns3pcfile')
  141. module.pcfilegen.module = module.name
  142.  
  143. return module
  144.  
  145. @TaskGen.feature("ns3testlib")
  146. @TaskGen.before_method("apply_incpaths")
  147. def apply_incpaths_ns3testlib(self):
  148. if not self.source:
  149. return
  150. testdir = self.to_nodes(self.source[-1])[0].parent.path_from(self.bld.srcnode)
  151. self.env.append_value("DEFINES", 'NS_TEST_SOURCEDIR="%s"' % (testdir,))
  152.  
  153.  
  154. def create_ns3_module_test_library(bld, name):
  155. # Create an ns3 module for the test library that depends only on
  156. # the module being tested.
  157. library_name = name + "-test"
  158. library = bld.create_ns3_module(library_name, [name], test=True)
  159. library.features += " ns3testlib"
  160.  
  161. # Modify attributes for the test library that are different from a
  162. # normal module.
  163. del library.is_ns3_module
  164. library.is_ns3_module_test_library = True
  165. library.module_name = 'ns3-' + name
  166.  
  167. # Add this module and test library to the list.
  168. bld.env.append_value('NS3_MODULES_WITH_TEST_LIBRARIES', [(library.module_name, library.name)])
  169.  
  170. # Set the include path from the build directory to modules.
  171. relative_path_from_build_to_here = bld.path.path_from(bld.bldnode)
  172. include_flag = '-I' + relative_path_from_build_to_here
  173. library.env.append_value('CXXFLAGS', include_flag)
  174. library.env.append_value('CCFLAGS', include_flag)
  175.  
  176. return library
  177.  
  178. def create_obj(bld, *args):
  179. warnings.warn("(in %s) Use bld(...) call now, instead of bld.create_obj(...)" % str(bld.path),
  180. DeprecationWarning, stacklevel=2)
  181. return bld(*args)
  182.  
  183.  
  184. def ns3_python_bindings(bld):
  185.  
  186. # this method is called from a module wscript, so remember bld.path is not bindings/python!
  187. module_abs_src_path = bld.path.abspath()
  188. module = os.path.basename(module_abs_src_path)
  189. env = bld.env
  190. env.append_value("MODULAR_BINDINGS_MODULES", "ns3-"+module)
  191.  
  192. if Options.options.apiscan:
  193. return
  194.  
  195. if not env['ENABLE_PYTHON_BINDINGS']:
  196. return
  197.  
  198. bindings_dir = bld.path.find_dir("bindings")
  199. if bindings_dir is None or not os.path.exists(bindings_dir.abspath()):
  200. warnings.warn("(in %s) Requested to build modular python bindings, but apidefs dir not found "
  201. "=> skipped the bindings." % str(bld.path),
  202. Warning, stacklevel=2)
  203. return
  204.  
  205. env.append_value('PYTHON_MODULES_BUILT', module)
  206. try:
  207. apidefs = env['PYTHON_BINDINGS_APIDEFS'].replace("-", "_")
  208. except AttributeError:
  209. # we likely got an empty list for env['PYTHON_BINDINGS_APIDEFS']
  210. return
  211.  
  212. #debug = ('PYBINDGEN_DEBUG' in os.environ)
  213. debug = True # XXX
  214. source = [bld.srcnode.find_resource('bindings/python/ns3modulegen-modular.py'),
  215. bld.path.find_resource("bindings/modulegen__%s.py" % apidefs)]
  216.  
  217. modulegen_customizations = bindings_dir.find_resource("modulegen_customizations.py")
  218. if modulegen_customizations is not None:
  219. source.append(modulegen_customizations)
  220.  
  221. modulegen_local = bld.path.find_resource("bindings/modulegen_local.py")
  222. # the local customization file may or not exist
  223. if modulegen_local is not None:
  224. source.append("bindings/modulegen_local.py")
  225.  
  226. module_py_name = module.replace('-', '_')
  227. module_target_dir = bld.srcnode.find_dir("bindings/python/ns").path_from(bld.path)
  228.  
  229. # if bindings/<module>.py exists, it becomes the module frontend, and the C extension befomes _<module>
  230. if bld.path.find_resource("bindings/%s.py" % (module_py_name,)) is not None:
  231. bld(features='copy',
  232. source=("bindings/%s.py" % (module_py_name,)),
  233. target=('%s/%s.py' % (module_target_dir, module_py_name)))
  234. extension_name = '_%s' % (module_py_name,)
  235. bld.install_files('${PYTHONARCHDIR}/ns', ["bindings/%s.py" % (module_py_name,)])
  236. else:
  237. extension_name = module_py_name
  238.  
  239. target = ['bindings/ns3module.cc', 'bindings/ns3module.h', 'bindings/ns3modulegen.log']
  240. #if not debug:
  241. # target.append('ns3modulegen.log')
  242.  
  243. argv = ['NS3_ENABLED_FEATURES=${FEATURES}',
  244. 'GCC_RTTI_ABI_COMPLETE=${GCC_RTTI_ABI_COMPLETE}',
  245. '${PYTHON}']
  246. #if debug:
  247. # argv.extend(["-m", "pdb"])
  248.  
  249. argv.extend(['${SRC[0]}', module_abs_src_path, apidefs, extension_name, '${TGT[0]}'])
  250.  
  251. argv.extend(['2>', '${TGT[2]}']) # 2> ns3modulegen.log
  252.  
  253. features = []
  254. for (name, caption, was_enabled, reason_not_enabled) in env['NS3_OPTIONAL_FEATURES']:
  255. if was_enabled:
  256. features.append(name)
  257.  
  258. bindgen = bld(features='command', source=source, target=target, command=argv)
  259. bindgen.env['FEATURES'] = ','.join(features)
  260. bindgen.dep_vars = ['FEATURES', "GCC_RTTI_ABI_COMPLETE"]
  261. bindgen.name = "pybindgen(ns3 module %s)" % module
  262. bindgen.module = module
  263. bindgen.install_path = None
  264.  
  265. # Retrieve the module dependencies
  266. module_obj = bld.get_tgen_by_name('ns3-' + module)
  267. module_deps = module_obj.use.copy()
  268. module_deps.append('ns3-' + module)
  269.  
  270. # generate the extension module
  271. pymod = bld(features='cxx cxxshlib pyext')
  272. pymod.source = ['bindings/ns3module.cc']
  273. pymod.target = '%s/%s' % (module_target_dir, extension_name)
  274. pymod.name = 'ns3module_%s' % module
  275. pymod.module= module
  276. pymod.use = module_deps # Should be '"ns3-"+module', but see bug 1117
  277. if pymod.env['ENABLE_STATIC_NS3']:
  278. if sys.platform == 'darwin':
  279. pymod.env.append_value('LINKFLAGS', '-Wl,-all_load')
  280. for mod in pymod.usel:
  281. #mod = mod.split("--lib")[0]
  282. pymod.env.append_value('LINKFLAGS', '-l' + mod)
  283. else:
  284. pymod.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic')
  285. for mod in pymod.use:
  286. #mod = mod.split("--lib")[0]
  287. pymod.env.append_value('LINKFLAGS', '-l' + mod)
  288. pymod.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive')
  289. defines = list(pymod.env['DEFINES'])
  290. defines.extend(['NS_DEPRECATED=', 'NS3_DEPRECATED_H'])
  291. defines.extend(['NS_DEPRECATED_3_31=', 'NS3_DEPRECATED_H'])
  292. defines.extend(['NS_DEPRECATED_3_30=', 'NS3_DEPRECATED_H'])
  293. defines.extend(['NS_DEPRECATED_3_27=', 'NS3_DEPRECATED_H'])
  294. defines.extend(['NS_DEPRECATED_3_26=', 'NS3_DEPRECATED_H'])
  295. if Utils.unversioned_sys_platform()== 'win32':
  296. try:
  297. defines.remove('_DEBUG') # causes undefined symbols on win32
  298. except ValueError:
  299. pass
  300. pymod.env['DEFINES'] = defines
  301. pymod.includes = '# bindings'
  302. pymod.install_path = '${PYTHONARCHDIR}/ns'
  303.  
  304. # Workaround to a WAF bug, remove this when ns-3 upgrades to WAF > 1.6.10
  305. # https://www.nsnam.org/bugzilla/show_bug.cgi?id=1335
  306. # http://code.google.com/p/waf/issues/detail?id=1098
  307. if Utils.unversioned_sys_platform() == 'darwin':
  308. pymod.mac_bundle = True
  309.  
  310. return pymod
  311.  
  312.  
  313. def build(bld):
  314. bld.create_ns3_module = types.MethodType(create_ns3_module, bld)
  315. bld.create_ns3_module_test_library = types.MethodType(create_ns3_module_test_library, bld)
  316. bld.create_obj = types.MethodType(create_obj, bld)
  317. bld.ns3_python_bindings = types.MethodType(ns3_python_bindings, bld)
  318.  
  319. # Remove these modules from the list of all modules.
  320. for not_built in bld.env['MODULES_NOT_BUILT']:
  321.  
  322. # XXX Because these modules are located in subdirectories of
  323. # test, their names in the all_modules list include the extra
  324. # relative path "test/". If these modules are moved into the
  325. # src directory, then this if block should be removed.
  326. if not_built == 'ns3tcp' or not_built == 'ns3wifi':
  327. not_built = 'test/' + not_built
  328.  
  329. if not_built in all_modules:
  330. all_modules.remove(not_built)
  331.  
  332. bld.recurse(list(all_modules))
  333.  
  334. for module in all_modules:
  335. modheader = bld(features='ns3moduleheader')
  336. modheader.module = module.split('/')[-1]
  337.  
  338. class ns3pcfile(Task.Task):
  339. after = ['cxxprogram', 'cxxshlib', 'cxxstlib']
  340.  
  341. def __str__(self):
  342. "string to display to the user"
  343. tgt_str = ' '.join([a.bldpath() for a in self.outputs])
  344. return 'pcfile: %s' % (tgt_str)
  345.  
  346. def runnable_status(self):
  347. return super(ns3pcfile, self).runnable_status()
  348.  
  349. def _self_libs(self, env, name, libdir):
  350. if env['ENABLE_STATIC_NS3']:
  351. path_st = 'STLIBPATH_ST'
  352. lib_st = 'STLIB_ST'
  353. lib_marker = 'STLIB_MARKER'
  354. else:
  355. path_st = 'LIBPATH_ST'
  356. lib_st = 'LIB_ST'
  357. lib_marker = 'SHLIB_MARKER'
  358. retval = [env[path_st] % libdir]
  359. if env[lib_marker]:
  360. retval.append(env[lib_marker])
  361. retval.append(env[lib_st] % name)
  362. return retval
  363.  
  364. def _lib(self, env, dep):
  365. libpath = env['LIBPATH_%s' % dep]
  366. linkflags = env['LINKFLAGS_%s' % dep]
  367. libs = env['LIB_%s' % dep]
  368. retval = []
  369. for path in libpath:
  370. retval.append(env['LIBPATH_ST'] % path)
  371. retval = retval + linkflags
  372. for lib in libs:
  373. retval.append(env['LIB_ST'] % lib)
  374. return retval
  375.  
  376. def _listify(self, v):
  377. if isinstance(v, list):
  378. return v
  379. else:
  380. return [v]
  381.  
  382. def _cflags(self, dep):
  383. flags = self.env['CFLAGS_%s' % dep]
  384. return self._listify(flags)
  385.  
  386. def _cxxflags(self, dep):
  387. return self._listify(self.env['CXXFLAGS_%s' % dep])
  388.  
  389. def _defines(self, dep):
  390. return [self.env['DEFINES_ST'] % define for define in self.env['DEFINES_%s' % dep]]
  391.  
  392. def _includes(self, dep):
  393. includes = self.env['INCLUDES_%s' % dep]
  394. return [self.env['CPPPATH_ST'] % include for include in Utils.to_list(includes)]
  395.  
  396. def _generate_pcfile(self, name, use, env, outfilename, module):
  397. outfile = open(outfilename, 'wt')
  398. prefix = env.PREFIX
  399. includedir = Utils.subst_vars('${INCLUDEDIR}/%s%s' % (wutils.APPNAME, wutils.VERSION), env)
  400. libdir = env.LIBDIR
  401. libs = self._self_libs(env, "%s%s-%s%s" % (wutils.APPNAME, wutils.VERSION, name[4:], env.BUILD_SUFFIX), '${libdir}')
  402. for dep in use:
  403. libs += self._lib(env, dep)
  404. for dep in env.LIBS:
  405. libs += self.env['LIB_ST'] % dep
  406. cflags = [self.env['CPPPATH_ST'] % '${includedir}']
  407.  
  408. if getattr(module, 'export_includes', None):
  409. for include in module.to_incnodes(module.export_includes):
  410. cflags += [self.env['CPPPATH_ST'] % include.abspath()]
  411. requires = []
  412. for dep in use:
  413. cflags = cflags + self._cflags(dep) + self._cxxflags(dep) + \
  414. self._defines(dep) + self._includes(dep)
  415. if dep.startswith('ns3-'):
  416. dep_name = dep[4:]
  417. requires.append("libns%s-%s%s" % (wutils.VERSION, dep_name, env.BUILD_SUFFIX))
  418. print("""\
  419. prefix=%s
  420. libdir=%s
  421. includedir=%s
  422.  
  423. Name: lib%s
  424. Description: ns-3 module %s
  425. Version: %s
  426. Libs: %s
  427. Cflags: %s
  428. Requires: %s\
  429. """ % (prefix, libdir, includedir,
  430. name, name, wutils.VERSION, ' '.join(libs), ' '.join(cflags), ' '.join(requires)), file=outfile)
  431. outfile.close()
  432.  
  433. def run(self):
  434. output_filename = self.outputs[0].abspath()
  435. self._generate_pcfile(self.module.name,
  436. self.module.to_list(self.module.use),
  437. self.env, output_filename, self.module)
  438.  
  439.  
  440. @TaskGen.feature('ns3pcfile')
  441. @TaskGen.after_method('process_rule')
  442. def apply(self):
  443. module = self.bld.find_ns3_module(self.module)
  444. output_filename = 'lib%s.pc' % os.path.basename(module.target)
  445. output_node = self.path.find_or_declare(output_filename)
  446. assert output_node is not None, str(self)
  447. task = self.create_task('ns3pcfile')
  448. self.bld.install_files('${LIBDIR}/pkgconfig', output_node)
  449. task.set_outputs([output_node])
  450. task.module = module
  451.  
  452.  
  453.  
  454. @TaskGen.feature('ns3header')
  455. @TaskGen.after_method('process_rule')
  456. def apply_ns3header(self):
  457. if self.module is None:
  458. raise WafError("'module' missing on ns3headers object %s" % self)
  459. ns3_dir_node = self.bld.path.find_or_declare("ns3")
  460. for filename in set(self.to_list(self.source)):
  461. src_node = self.path.find_resource(filename)
  462. if src_node is None:
  463. raise WafError("source ns3 header file %s not found" % (filename,))
  464. dst_node = ns3_dir_node.find_or_declare(src_node.name)
  465. assert dst_node is not None
  466. task = self.create_task('ns3header')
  467. task.mode = getattr(self, 'mode', 'install')
  468. if task.mode == 'install':
  469. self.bld.install_files('${INCLUDEDIR}/%s%s/ns3' % (wutils.APPNAME, wutils.VERSION), [src_node])
  470. task.set_inputs([src_node])
  471. task.set_outputs([dst_node])
  472. else:
  473. task.header_to_remove = dst_node
  474. self.headers = set(self.to_list(self.source))
  475. self.source = '' # tell WAF not to process these files further
  476.  
  477.  
  478. class ns3header(Task.Task):
  479. before = ['cxxprogram', 'cxxshlib', 'cxxstlib', 'gen_ns3_module_header']
  480. color = 'BLUE'
  481.  
  482. def __str__(self):
  483. "string to display to the user"
  484. env = self.env
  485. src_str = ' '.join([a.bldpath() for a in self.inputs])
  486. tgt_str = ' '.join([a.bldpath() for a in self.outputs])
  487. if self.outputs: sep = ' -> '
  488. else: sep = ''
  489. if self.mode == 'remove':
  490. return 'rm-ns3-header %s' % (self.header_to_remove.abspath(),)
  491. return 'install-ns3-header: %s' % (tgt_str)
  492.  
  493. def __repr__(self):
  494. return str(self)
  495.  
  496. def uid(self):
  497. try:
  498. return self.uid_
  499. except AttributeError:
  500. m = Utils.md5()
  501. up = m.update
  502. up(self.__class__.__name__.encode())
  503. for x in self.inputs + self.outputs:
  504. up(x.abspath().encode())
  505. up(self.mode.encode())
  506. if self.mode == 'remove':
  507. up(self.header_to_remove.abspath().encode())
  508. self.uid_ = m.digest()
  509. return self.uid_
  510.  
  511. def runnable_status(self):
  512. if self.mode == 'remove':
  513. if os.path.exists(self.header_to_remove.abspath()):
  514. return Task.RUN_ME
  515. else:
  516. return Task.SKIP_ME
  517. else:
  518. return super(ns3header, self).runnable_status()
  519.  
  520. def run(self):
  521. if self.mode == 'install':
  522. assert len(self.inputs) == len(self.outputs)
  523. inputs = [node.abspath() for node in self.inputs]
  524. outputs = [node.abspath() for node in self.outputs]
  525. for src, dst in zip(inputs, outputs):
  526. try:
  527. os.chmod(dst, 0o600)
  528. except OSError:
  529. pass
  530. shutil.copy2(src, dst)
  531. ## make the headers in builddir read-only, to prevent
  532. ## accidental modification
  533. os.chmod(dst, 0o400)
  534. return 0
  535. else:
  536. assert len(self.inputs) == 0
  537. assert len(self.outputs) == 0
  538. out_file_name = self.header_to_remove.abspath()
  539. try:
  540. os.unlink(out_file_name)
  541. except OSError as ex:
  542. if ex.errno != 2:
  543. raise
  544. return 0
  545.  
  546.  
  547. @TaskGen.feature('ns3privateheader')
  548. @TaskGen.after_method('process_rule')
  549. def apply_ns3privateheader(self):
  550. if self.module is None:
  551. raise WafError("'module' missing on ns3headers object %s" % self)
  552. ns3_dir_node = self.bld.path.find_or_declare("ns3/private")
  553. for filename in set(self.to_list(self.source)):
  554. src_node = self.path.find_resource(filename)
  555. if src_node is None:
  556. raise WafError("source ns3 header file %s not found" % (filename,))
  557. dst_node = ns3_dir_node.find_or_declare(src_node.name)
  558. assert dst_node is not None
  559. task = self.create_task('ns3privateheader')
  560. task.mode = getattr(self, 'mode', 'install')
  561. if task.mode == 'install':
  562. task.set_inputs([src_node])
  563. task.set_outputs([dst_node])
  564. else:
  565. task.header_to_remove = dst_node
  566. self.headers = set(self.to_list(self.source))
  567. self.source = '' # tell WAF not to process these files further
  568.  
  569. class ns3privateheader(Task.Task):
  570. before = ['cxxprogram', 'cxxshlib', 'cxxstlib', 'gen_ns3_module_header']
  571. after = 'ns3header'
  572. color = 'BLUE'
  573.  
  574. def __str__(self):
  575. "string to display to the user"
  576. env = self.env
  577. src_str = ' '.join([a.bldpath() for a in self.inputs])
  578. tgt_str = ' '.join([a.bldpath() for a in self.outputs])
  579. if self.outputs: sep = ' -> '
  580. else: sep = ''
  581. if self.mode == 'remove':
  582. return 'rm-ns3-header %s' % (self.header_to_remove.abspath(),)
  583. return 'install-ns3-header: %s' % (tgt_str)
  584.  
  585. def __repr__(self):
  586. return str(self)
  587.  
  588. def uid(self):
  589. try:
  590. return self.uid_
  591. except AttributeError:
  592. m = Utils.md5()
  593. up = m.update
  594. up(self.__class__.__name__.encode())
  595. for x in self.inputs + self.outputs:
  596. up(x.abspath().encode())
  597. up(self.mode.encode())
  598. if self.mode == 'remove':
  599. up(self.header_to_remove.abspath().encode())
  600. self.uid_ = m.digest()
  601. return self.uid_
  602.  
  603. def runnable_status(self):
  604. if self.mode == 'remove':
  605. if os.path.exists(self.header_to_remove.abspath()):
  606. return Task.RUN_ME
  607. else:
  608. return Task.SKIP_ME
  609. else:
  610. return super(ns3privateheader, self).runnable_status()
  611.  
  612. def run(self):
  613. if self.mode == 'install':
  614. assert len(self.inputs) == len(self.outputs)
  615. inputs = [node.abspath() for node in self.inputs]
  616. outputs = [node.abspath() for node in self.outputs]
  617. for src, dst in zip(inputs, outputs):
  618. try:
  619. os.chmod(dst, 0o600)
  620. except OSError:
  621. pass
  622. shutil.copy2(src, dst)
  623. ## make the headers in builddir read-only, to prevent
  624. ## accidental modification
  625. os.chmod(dst, 0o400)
  626. return 0
  627. else:
  628. assert len(self.inputs) == 0
  629. assert len(self.outputs) == 0
  630. out_file_name = self.header_to_remove.abspath()
  631. try:
  632. os.unlink(out_file_name)
  633. except OSError as ex:
  634. if ex.errno != 2:
  635. raise
  636. return 0
  637.  
  638.  
  639. class gen_ns3_module_header(Task.Task):
  640. before = ['cxxprogram', 'cxxshlib', 'cxxstlib']
  641. after = 'ns3header'
  642. color = 'BLUE'
  643.  
  644. def runnable_status(self):
  645. if self.mode == 'remove':
  646. if os.path.exists(self.header_to_remove.abspath()):
  647. return Task.RUN_ME
  648. else:
  649. return Task.SKIP_ME
  650. else:
  651. return super(gen_ns3_module_header, self).runnable_status()
  652.  
  653. def __str__(self):
  654. "string to display to the user"
  655. env = self.env
  656. src_str = ' '.join([a.bldpath() for a in self.inputs])
  657. tgt_str = ' '.join([a.bldpath() for a in self.outputs])
  658. if self.outputs: sep = ' -> '
  659. else: sep = ''
  660. if self.mode == 'remove':
  661. return 'rm-module-header %s' % (self.header_to_remove.abspath(),)
  662. return 'gen-module-header: %s' % (tgt_str)
  663.  
  664. def run(self):
  665. if self.mode == 'remove':
  666. assert len(self.inputs) == 0
  667. assert len(self.outputs) == 0
  668. out_file_name = self.header_to_remove.abspath()
  669. try:
  670. os.unlink(out_file_name)
  671. except OSError as ex:
  672. if ex.errno != 2:
  673. raise
  674. return 0
  675. assert len(self.outputs) == 1
  676. out_file_name = self.outputs[0].get_bld().abspath()#self.env)
  677. header_files = [os.path.basename(node.abspath()) for node in self.inputs]
  678. outfile = open(out_file_name, "w")
  679. header_files.sort()
  680.  
  681. print("""
  682. #ifdef NS3_MODULE_COMPILATION
  683. # error "Do not include ns3 module aggregator headers from other modules; these are meant only for end user scripts."
  684. #endif
  685.  
  686. #ifndef NS3_MODULE_%s
  687. """ % (self.module.upper().replace('-', '_'),), file=outfile)
  688.  
  689. # if self.module_deps:
  690. # print >> outfile, "// Module dependencies:"
  691. # for dep in self.module_deps:
  692. # print >> outfile, "#include \"%s-module.h\"" % dep
  693.  
  694. print(file=outfile)
  695. print("// Module headers:", file=outfile)
  696. for header in header_files:
  697. print("#include \"%s\"" % (header,), file=outfile)
  698.  
  699. print("#endif", file=outfile)
  700.  
  701. outfile.close()
  702. return 0
  703.  
  704. def sig_explicit_deps(self):
  705. self.m.update('\n'.join(sorted([node.abspath() for node in self.inputs])).encode('utf-8'))
  706. return self.m.digest()
  707.  
  708. def unique_id(self):
  709. try:
  710. return self.uid
  711. except AttributeError:
  712. "this is not a real hot zone, but we want to avoid surprizes here"
  713. m = Utils.md5()
  714. m.update("ns-3-module-header-%s" % self.module)
  715. self.uid = m.digest()
  716. return self.uid
  717.  
  718.  
  719. # Generates a 'ns3/foo-module.h' header file that includes all public
  720. # ns3 headers of a certain module.
  721. @TaskGen.feature('ns3moduleheader')
  722. @TaskGen.after_method('process_rule')
  723. def apply_ns3moduleheader(self):
  724. ## get all of the ns3 headers
  725. ns3_dir_node = self.bld.path.find_or_declare("ns3")
  726. all_headers_inputs = []
  727. found_the_module = False
  728. for ns3headers in self.bld.all_task_gen:
  729. if 'ns3header' in getattr(ns3headers, "features", []):
  730. if ns3headers.module != self.module:
  731. continue
  732. found_the_module = True
  733. for source in sorted(ns3headers.headers):
  734. source = os.path.basename(source)
  735. node = ns3_dir_node.find_or_declare(os.path.basename(source))
  736. if node is None:
  737. fatal("missing header file %s" % (source,))
  738. all_headers_inputs.append(node)
  739. if not found_the_module:
  740. raise WafError("error finding headers for module %s" % self.module)
  741. if not all_headers_inputs:
  742. return
  743.  
  744. try:
  745. module_obj = self.bld.get_tgen_by_name("ns3-" + self.module)
  746. except WafError: # maybe the module was disabled, and therefore removed
  747. return
  748.  
  749. all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self.module)]
  750. task = self.create_task('gen_ns3_module_header')
  751. task.module = self.module
  752. task.mode = getattr(self, "mode", "install")
  753. if task.mode == 'install':
  754. assert module_obj is not None, self.module
  755. self.bld.install_files('${INCLUDEDIR}/%s%s/ns3' % (wutils.APPNAME, wutils.VERSION),
  756. ns3_dir_node.find_or_declare("%s-module.h" % self.module))
  757. task.set_inputs(all_headers_inputs)
  758. task.set_outputs(all_headers_outputs)
  759. task.module_deps = module_obj.module_deps
  760. else:
  761. task.header_to_remove = all_headers_outputs[0]
Tags: wscript NS3
Advertisement
Add Comment
Please, Sign In to add comment