merge
This commit is contained in:
1
bindings/python/ns/__init__.py
Normal file
1
bindings/python/ns/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
54
bindings/python/ns3modulegen-modular.py
Normal file
54
bindings/python/ns3modulegen-modular.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import warnings
|
||||
import sys
|
||||
import os
|
||||
import pybindgen.settings
|
||||
from pybindgen import Module, FileCodeSink, param, retval, cppclass, typehandlers
|
||||
import ns3modulegen_core_customizations
|
||||
|
||||
class ErrorHandler(pybindgen.settings.ErrorHandler):
|
||||
def handle_error(self, wrapper, exception, traceback_):
|
||||
warnings.warn("exception %r in wrapper %s" % (exception, wrapper))
|
||||
return True
|
||||
pybindgen.settings.error_handler = ErrorHandler()
|
||||
|
||||
|
||||
|
||||
|
||||
def main(argv):
|
||||
assert len(argv) == 3
|
||||
module_abs_src_path, target = argv[1], argv[2]
|
||||
module_name = os.path.basename(module_abs_src_path)
|
||||
|
||||
sys.path.insert(0, os.path.join(module_abs_src_path, "bindings"))
|
||||
try:
|
||||
module_apidefs = __import__("modulegen__%s" % target)
|
||||
del sys.modules["modulegen__%s" % target]
|
||||
try:
|
||||
module_customization = __import__("modulegen_local")
|
||||
del sys.modules["modulegen_local"]
|
||||
except ImportError:
|
||||
module_customization = None
|
||||
finally:
|
||||
sys.path.pop(0)
|
||||
|
||||
out = FileCodeSink(sys.stdout)
|
||||
root_module = module_apidefs.module_init()
|
||||
root_module.add_include('"ns3/%s-module.h"' % module_name)
|
||||
module_apidefs.register_types(root_module)
|
||||
|
||||
module_apidefs.register_methods(root_module)
|
||||
module_apidefs.register_functions(root_module)
|
||||
|
||||
ns3modulegen_core_customizations.Object_customizations(root_module)
|
||||
ns3modulegen_core_customizations.Attribute_customizations(root_module)
|
||||
|
||||
if module_customization is not None:
|
||||
module_customization.customize(root_module)
|
||||
|
||||
root_module.generate(out)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
main(sys.argv)
|
||||
|
||||
|
||||
301
bindings/python/ns3modulescan-modular.py
Normal file
301
bindings/python/ns3modulescan-modular.py
Normal file
@@ -0,0 +1,301 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
import pybindgen.settings
|
||||
from pybindgen.gccxmlparser import ModuleParser, PygenClassifier, PygenSection, WrapperWarning
|
||||
from pybindgen.typehandlers.codesink import FileCodeSink
|
||||
from pygccxml.declarations import templates
|
||||
from pygccxml.declarations.enumeration import enumeration_t
|
||||
from pygccxml.declarations.class_declaration import class_t
|
||||
from pygccxml.declarations.calldef import free_function_t, member_function_t, constructor_t, calldef_t
|
||||
|
||||
|
||||
## we need the smart pointer type transformation to be active even
|
||||
## during gccxml scanning.
|
||||
import ns3modulegen_core_customizations
|
||||
|
||||
|
||||
## silence gccxmlparser errors; we only want error handling in the
|
||||
## generated python script, not while scanning.
|
||||
class ErrorHandler(pybindgen.settings.ErrorHandler):
|
||||
def handle_error(self, dummy_wrapper, dummy_exception, dummy_traceback_):
|
||||
return True
|
||||
pybindgen.settings.error_handler = ErrorHandler()
|
||||
import warnings
|
||||
warnings.filterwarnings(category=WrapperWarning, action='ignore')
|
||||
|
||||
type_annotations = {
|
||||
'::ns3::AttributeChecker': {
|
||||
'automatic_type_narrowing': 'true',
|
||||
'allow_subclassing': 'false',
|
||||
},
|
||||
'::ns3::AttributeValue': {
|
||||
'automatic_type_narrowing': 'true',
|
||||
'allow_subclassing': 'false',
|
||||
},
|
||||
|
||||
'::ns3::CommandLine': {
|
||||
'allow_subclassing': 'true', # needed so that AddValue is able to set attributes on the object
|
||||
},
|
||||
|
||||
'::ns3::NscTcpL4Protocol': {
|
||||
'ignore': 'true', # this class is implementation detail
|
||||
},
|
||||
|
||||
|
||||
'ns3::RandomVariable::RandomVariable(ns3::RandomVariableBase const & variable) [constructor]': {
|
||||
'ignore': None,
|
||||
},
|
||||
'ns3::RandomVariableBase * ns3::RandomVariable::Peek() const [member function]': {
|
||||
'ignore': None,
|
||||
},
|
||||
'void ns3::RandomVariable::GetSeed(uint32_t * seed) const [member function]': {
|
||||
'params': {'seed':{'direction':'out',
|
||||
'array_length':'6'}}
|
||||
},
|
||||
'bool ns3::TypeId::LookupAttributeByName(std::string name, ns3::TypeId::AttributeInfo * info) const [member function]': {
|
||||
'params': {'info':{'transfer_ownership': 'false'}}
|
||||
},
|
||||
'static bool ns3::TypeId::LookupByNameFailSafe(std::string name, ns3::TypeId * tid) [member function]': {
|
||||
'ignore': None, # manually wrapped in
|
||||
},
|
||||
'bool ns3::TraceSourceAccessor::ConnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': {
|
||||
'params': {'obj': {'transfer_ownership':'false'}}
|
||||
},
|
||||
'bool ns3::TraceSourceAccessor::Connect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function]': {
|
||||
'params': {'obj': {'transfer_ownership':'false'}}
|
||||
},
|
||||
'bool ns3::TraceSourceAccessor::DisconnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': {
|
||||
'params': {'obj': {'transfer_ownership':'false'}}
|
||||
},
|
||||
'bool ns3::TraceSourceAccessor::Disconnect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function]': {
|
||||
'params': {'obj': {'transfer_ownership':'false'}}
|
||||
},
|
||||
'bool ns3::AttributeAccessor::Set(ns3::ObjectBase * object, ns3::AttributeValue const & value) const [member function]': {
|
||||
'params': {'object': {'transfer_ownership':'false'}}
|
||||
},
|
||||
'ns3::EmpiricalVariable::EmpiricalVariable(ns3::RandomVariableBase const & variable) [constructor]': {
|
||||
'ignore': None
|
||||
},
|
||||
'static ns3::AttributeList * ns3::AttributeList::GetGlobal() [member function]': {
|
||||
'caller_owns_return': 'false'
|
||||
},
|
||||
'void ns3::CommandLine::Parse(int argc, char * * argv) const [member function]': {
|
||||
'ignore': None # manually wrapped
|
||||
},
|
||||
'extern void ns3::PythonCompleteConstruct(ns3::Ptr<ns3::Object> object, ns3::TypeId typeId, ns3::AttributeList const & attributes) [free function]': {
|
||||
'ignore': None # used transparently by, should not be wrapped
|
||||
},
|
||||
|
||||
'ns3::Ptr<ns3::Ipv4RoutingProtocol> ns3::Ipv4ListRouting::GetRoutingProtocol(uint32_t index, int16_t & priority) const [member function]': {
|
||||
'params': {'priority':{'direction':'out'}}
|
||||
},
|
||||
'ns3::Ipv4RoutingTableEntry * ns3::GlobalRouter::GetInjectedRoute(uint32_t i) [member function]': {
|
||||
'params': {'return': { 'caller_owns_return': 'false',}},
|
||||
},
|
||||
'ns3::Ipv4RoutingTableEntry * ns3::Ipv4GlobalRouting::GetRoute(uint32_t i) [member function]': {
|
||||
'params': {'return': { 'caller_owns_return': 'false',}},
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
def get_ns3_relative_path(path):
|
||||
l = []
|
||||
head = path
|
||||
while head:
|
||||
head, tail = os.path.split(head)
|
||||
if tail == 'ns3':
|
||||
return os.path.join(*l)
|
||||
l.insert(0, tail)
|
||||
raise AssertionError("is the path %r inside ns3?!" % path)
|
||||
|
||||
class PreScanHook:
|
||||
|
||||
def __init__(self, headers_map, module):
|
||||
self.headers_map = headers_map
|
||||
self.module = module
|
||||
|
||||
def __call__(self, dummy_module_parser,
|
||||
pygccxml_definition,
|
||||
global_annotations,
|
||||
parameter_annotations):
|
||||
ns3_header = get_ns3_relative_path(pygccxml_definition.location.file_name)
|
||||
definition_module = self.headers_map[ns3_header]
|
||||
|
||||
## Note: we don't include line numbers in the comments because
|
||||
## those numbers are very likely to change frequently, which would
|
||||
## cause needless changes, since the generated python files are
|
||||
## kept under version control.
|
||||
|
||||
#global_annotations['pygen_comment'] = "%s:%i: %s" % \
|
||||
# (ns3_header, pygccxml_definition.location.line, pygccxml_definition)
|
||||
global_annotations['pygen_comment'] = "%s (module %r): %s" % \
|
||||
(ns3_header, definition_module, pygccxml_definition)
|
||||
|
||||
|
||||
## handle ns3::Object::GetObject (left to its own devices,
|
||||
## pybindgen will generate a mangled name containing the template
|
||||
## argument type name).
|
||||
if isinstance(pygccxml_definition, member_function_t) \
|
||||
and pygccxml_definition.parent.name == 'Object' \
|
||||
and pygccxml_definition.name == 'GetObject':
|
||||
template_args = templates.args(pygccxml_definition.demangled_name)
|
||||
if template_args == ['ns3::Object']:
|
||||
global_annotations['template_instance_names'] = 'ns3::Object=>GetObject'
|
||||
|
||||
## Don't wrap Simulator::Schedule* (manually wrapped)
|
||||
if isinstance(pygccxml_definition, member_function_t) \
|
||||
and pygccxml_definition.parent.name == 'Simulator' \
|
||||
and pygccxml_definition.name.startswith('Schedule'):
|
||||
global_annotations['ignore'] = None
|
||||
|
||||
# manually wrapped
|
||||
if isinstance(pygccxml_definition, member_function_t) \
|
||||
and pygccxml_definition.parent.name == 'Simulator' \
|
||||
and pygccxml_definition.name == 'Run':
|
||||
global_annotations['ignore'] = True
|
||||
|
||||
## http://www.gccxml.org/Bug/view.php?id=9915
|
||||
if isinstance(pygccxml_definition, calldef_t):
|
||||
for arg in pygccxml_definition.arguments:
|
||||
if arg.default_value is None:
|
||||
continue
|
||||
if "ns3::MilliSeconds( )" == arg.default_value:
|
||||
arg.default_value = "ns3::MilliSeconds(0)"
|
||||
|
||||
## classes
|
||||
if isinstance(pygccxml_definition, class_t):
|
||||
# no need for helper classes to allow subclassing in Python, I think...
|
||||
#if pygccxml_definition.name.endswith('Helper'):
|
||||
# global_annotations['allow_subclassing'] = 'false'
|
||||
|
||||
if definition_module != self.module:
|
||||
global_annotations['import_from_module'] = 'ns.%s' % definition_module
|
||||
|
||||
if pygccxml_definition.decl_string.startswith('::ns3::SimpleRefCount<'):
|
||||
global_annotations['incref_method'] = 'Ref'
|
||||
global_annotations['decref_method'] = 'Unref'
|
||||
global_annotations['peekref_method'] = 'GetReferenceCount'
|
||||
global_annotations['automatic_type_narrowing'] = 'true'
|
||||
return
|
||||
|
||||
if pygccxml_definition.decl_string.startswith('::ns3::Callback<'):
|
||||
# manually handled in ns3modulegen_core_customizations.py
|
||||
global_annotations['ignore'] = None
|
||||
return
|
||||
|
||||
if pygccxml_definition.decl_string.startswith('::ns3::TracedCallback<'):
|
||||
global_annotations['ignore'] = None
|
||||
return
|
||||
|
||||
if pygccxml_definition.decl_string.startswith('::ns3::Ptr<'):
|
||||
# handled by pybindgen "type transformation"
|
||||
global_annotations['ignore'] = None
|
||||
return
|
||||
|
||||
# table driven class customization
|
||||
try:
|
||||
annotations = type_annotations[pygccxml_definition.decl_string]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
global_annotations.update(annotations)
|
||||
|
||||
## enums
|
||||
if isinstance(pygccxml_definition, enumeration_t):
|
||||
if definition_module != self.module:
|
||||
global_annotations['import_from_module'] = 'ns.%s' % definition_module
|
||||
|
||||
## free functions
|
||||
if isinstance(pygccxml_definition, free_function_t):
|
||||
|
||||
if definition_module != self.module:
|
||||
global_annotations['ignore'] = None
|
||||
return
|
||||
|
||||
if pygccxml_definition.name == 'PeekPointer':
|
||||
global_annotations['ignore'] = None
|
||||
return
|
||||
|
||||
## table driven methods/constructors/functions customization
|
||||
if isinstance(pygccxml_definition, (free_function_t, member_function_t, constructor_t)):
|
||||
try:
|
||||
annotations = type_annotations[str(pygccxml_definition)]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
for key,value in annotations.items():
|
||||
if key == 'params':
|
||||
parameter_annotations.update (value)
|
||||
del annotations['params']
|
||||
global_annotations.update(annotations)
|
||||
|
||||
|
||||
# def post_scan_hook(dummy_module_parser, dummy_pygccxml_definition, pybindgen_wrapper):
|
||||
# ## classes
|
||||
# if isinstance(pybindgen_wrapper, CppClass):
|
||||
# if pybindgen_wrapper.name.endswith('Checker'):
|
||||
# print >> sys.stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", pybindgen_wrapper
|
||||
# #pybindgen_wrapper.set_instance_creation_function(AttributeChecker_instance_creation_function)
|
||||
|
||||
|
||||
def scan_callback_classes(module_parser, callback_classes_file):
|
||||
callback_classes_file.write("callback_classes = [\n")
|
||||
for cls in module_parser.module_namespace.classes(function=module_parser.location_filter,
|
||||
recursive=False):
|
||||
if not cls.name.startswith("Callback<"):
|
||||
continue
|
||||
assert templates.is_instantiation(cls.decl_string), "%s is not a template instantiation" % cls
|
||||
dummy_cls_name, template_parameters = templates.split(cls.decl_string)
|
||||
callback_classes_file.write(" %r,\n" % template_parameters)
|
||||
callback_classes_file.write("]\n")
|
||||
|
||||
|
||||
def ns3_module_scan(top_builddir, module_name, headers_map, output_file_name, cflags):
|
||||
module_parser = ModuleParser('ns.%s' % module_name, 'ns3')
|
||||
module_parser.add_pre_scan_hook(PreScanHook(headers_map, module_name))
|
||||
#module_parser.add_post_scan_hook(post_scan_hook)
|
||||
|
||||
gccxml_options = dict(
|
||||
include_paths=[top_builddir],
|
||||
define_symbols={
|
||||
#'NS3_ASSERT_ENABLE': None,
|
||||
#'NS3_LOG_ENABLE': None,
|
||||
},
|
||||
cflags=('--gccxml-cxxflags %r' % (cflags,))
|
||||
)
|
||||
|
||||
try:
|
||||
os.unlink(output_file_name)
|
||||
except OSError:
|
||||
pass
|
||||
output_file = open(output_file_name, "wt")
|
||||
output_sink = FileCodeSink(output_file)
|
||||
module_parser.parse_init([os.path.join(top_builddir, "ns3", "%s-module.h" % module_name)],
|
||||
None, whitelist_paths=[top_builddir],
|
||||
#includes=['"ns3/everything.h"'],
|
||||
pygen_sink=output_sink,
|
||||
gccxml_options=gccxml_options)
|
||||
module_parser.scan_types()
|
||||
|
||||
#callback_classes_file = open(os.path.join(os.path.dirname(pygen_file_name), "callbacks_list.py"), "wt")
|
||||
#scan_callback_classes(module_parser, callback_classes_file)
|
||||
#callback_classes_file.close()
|
||||
|
||||
|
||||
module_parser.scan_methods()
|
||||
module_parser.scan_functions()
|
||||
module_parser.parse_finalize()
|
||||
|
||||
output_file.close()
|
||||
os.chmod(output_file_name, 0400)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 6:
|
||||
print "ns3modulescan2.py top_builddir module_path module_headers output_file_name cflags"
|
||||
sys.exit(1)
|
||||
ns3_module_scan(sys.argv[1], sys.argv[2], eval(sys.argv[3]), sys.argv[4], sys.argv[5])
|
||||
sys.exit(0)
|
||||
@@ -1,5 +1,5 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
import types
|
||||
import re
|
||||
import os
|
||||
import pproc as subprocess
|
||||
@@ -15,7 +15,7 @@ import Build
|
||||
import Utils
|
||||
|
||||
## https://launchpad.net/pybindgen/
|
||||
REQUIRED_PYBINDGEN_VERSION = (0, 15, 0)
|
||||
REQUIRED_PYBINDGEN_VERSION = (0, 15, 0, 775)
|
||||
REQUIRED_PYGCCXML_VERSION = (0, 9, 5)
|
||||
|
||||
|
||||
@@ -52,6 +52,11 @@ def set_pybindgen_pythonpath(env):
|
||||
|
||||
def set_options(opt):
|
||||
opt.tool_options('python')
|
||||
opt.add_option('--bindings-type', type="choice",
|
||||
choices=("monolithic", "modular", "both"),
|
||||
help=("Type of Python bindings to build"),
|
||||
default="monolithic",
|
||||
dest='bindings_type')
|
||||
opt.add_option('--disable-python',
|
||||
help=("Don't build Python bindings."),
|
||||
action="store_true", default=False,
|
||||
@@ -60,6 +65,9 @@ def set_options(opt):
|
||||
help=("Rescan Python bindings. Needs working GCCXML / pygccxml environment."),
|
||||
action="store_true", default=False,
|
||||
dest='python_scan')
|
||||
opt.add_option('--apiscan',
|
||||
help=("EXPERIMENTAL: Rescan module API, for Python bindings. Needs working GCCXML / pygccxml environment."),
|
||||
default=None, dest='apiscan', metavar="MODULE[,MODULE...]")
|
||||
opt.add_option('--with-pybindgen',
|
||||
help=('Path to an existing pybindgen source tree to use.'),
|
||||
default=None,
|
||||
@@ -198,7 +206,12 @@ int main ()
|
||||
conf.env['ENABLE_PYTHON_BINDINGS'] = True
|
||||
conf.report_optional_feature("python", "Python Bindings", True, None)
|
||||
|
||||
|
||||
conf.env['BINDINGS_TYPE'] = Options.options.bindings_type
|
||||
if conf.env['BINDINGS_TYPE'] == 'both':
|
||||
msg = "monolithic and modular"
|
||||
else:
|
||||
msg = conf.env['BINDINGS_TYPE']
|
||||
conf.check_message_custom('type of bindings to build', '', msg)
|
||||
|
||||
## Check for pygccxml
|
||||
try:
|
||||
@@ -244,12 +257,73 @@ int main ()
|
||||
conf.report_optional_feature("pygccxml", "Python API Scanning Support", False,
|
||||
"gccxml too old")
|
||||
return
|
||||
|
||||
|
||||
## If we reached
|
||||
conf.env['ENABLE_PYTHON_SCANNING'] = True
|
||||
conf.report_optional_feature("pygccxml", "Python API Scanning Support", True, None)
|
||||
|
||||
|
||||
|
||||
|
||||
# ---------------------
|
||||
|
||||
def get_headers_map(bld):
|
||||
headers_map = {} # header => module
|
||||
for ns3headers in bld.all_task_gen:
|
||||
if type(ns3headers).__name__ == 'ns3header_taskgen': # XXX: find less hackish way to compare
|
||||
for h in ns3headers.to_list(ns3headers.source):
|
||||
headers_map[os.path.basename(h)] = ns3headers.module
|
||||
return headers_map
|
||||
|
||||
def get_module_path(bld, module):
|
||||
for ns3headers in bld.all_task_gen:
|
||||
if type(ns3headers).__name__ == 'ns3header_taskgen': # XXX: find less hackish way to compare
|
||||
if ns3headers.module == module:
|
||||
break
|
||||
|
||||
else:
|
||||
raise ValueError("Module %r not found" % module)
|
||||
return ns3headers.path.abspath()
|
||||
|
||||
class apiscan_task(Task.TaskBase):
|
||||
"""Uses gccxml to scan the file 'everything.h' and extract API definitions.
|
||||
"""
|
||||
after = 'gen_everything_h_task'
|
||||
before = 'cc cxx gchx'
|
||||
color = "BLUE"
|
||||
def __init__(self, curdirnode, env, bld, target, cflags, module):
|
||||
self.bld = bld
|
||||
super(apiscan_task, self).__init__(generator=self)
|
||||
self.curdirnode = curdirnode
|
||||
self.env = env
|
||||
self.target = target
|
||||
self.cflags = cflags
|
||||
self.module = module
|
||||
|
||||
def display(self):
|
||||
return 'api-scan-%s\n' % (self.target,)
|
||||
|
||||
def run(self):
|
||||
top_builddir = self.curdirnode.find_dir('../..').abspath(self.env)
|
||||
module_path = get_module_path(self.bld, self.module)
|
||||
print module_path
|
||||
headers_map = get_headers_map(self.bld)
|
||||
argv = [
|
||||
self.env['PYTHON'],
|
||||
os.path.join(self.curdirnode.abspath(), 'ns3modulescan-modular.py'), # scanning script
|
||||
top_builddir,
|
||||
self.module,
|
||||
repr(get_headers_map(self.bld)),
|
||||
os.path.join(module_path, "bindings", 'modulegen__%s.py' % (self.target)), # output file
|
||||
self.cflags,
|
||||
]
|
||||
scan = subprocess.Popen(argv, stdin=subprocess.PIPE)
|
||||
retval = scan.wait()
|
||||
return retval
|
||||
|
||||
|
||||
|
||||
# --------------
|
||||
prio_headers = {
|
||||
-2: (
|
||||
"string.h", # work around http://www.gccxml.org/Bug/view.php?id=6682
|
||||
@@ -452,7 +526,7 @@ class python_scan_task(Task.TaskBase):
|
||||
class python_scan_task_collector(Task.TaskBase):
|
||||
"""Tasks that waits for the python-scan-* tasks to complete and then signals WAF to exit
|
||||
"""
|
||||
after = 'python_scan_task'
|
||||
after = 'python_scan_task apiscan_task'
|
||||
before = 'cc cxx'
|
||||
color = "BLUE"
|
||||
def __init__(self, curdirnode, env, bld):
|
||||
@@ -481,7 +555,28 @@ def build(bld):
|
||||
|
||||
set_pybindgen_pythonpath(env)
|
||||
|
||||
if env['ENABLE_PYTHON_BINDINGS']:
|
||||
|
||||
|
||||
# copy the __init__.py file to the build dir. waf can't handle
|
||||
# this, it's against waf's principles to have build dir files
|
||||
# with the same name as source dir files, apparently.
|
||||
dirnode = bld.path.find_dir('ns')
|
||||
src = os.path.join(dirnode.abspath(), '__init__.py')
|
||||
dst = os.path.join(dirnode.abspath(env), '__init__.py')
|
||||
try:
|
||||
need_copy = os.stat(src).st_mtime > os.stat(dst).st_mtime
|
||||
except OSError:
|
||||
need_copy = True
|
||||
if need_copy:
|
||||
try:
|
||||
os.mkdir(os.path.dirname(dst))
|
||||
except OSError:
|
||||
pass
|
||||
print "%r -> %r" % (src, dst)
|
||||
shutil.copy2(src, dst)
|
||||
|
||||
|
||||
if env['ENABLE_PYTHON_BINDINGS'] and env['BINDINGS_TYPE'] in ('monolithic', 'both'):
|
||||
obj = bld.new_task_gen('all_ns3_headers')
|
||||
|
||||
if Options.options.python_scan:
|
||||
@@ -503,7 +598,28 @@ def build(bld):
|
||||
python_scan_task_collector(bld.path, env, bld)
|
||||
return
|
||||
|
||||
if env['ENABLE_PYTHON_BINDINGS']:
|
||||
if Options.options.apiscan:
|
||||
if not env['ENABLE_PYTHON_SCANNING']:
|
||||
raise Utils.WafError("Cannot re-scan python bindings: (py)gccxml not available")
|
||||
scan_targets = []
|
||||
if sys.platform == 'cygwin':
|
||||
scan_targets.append(('gcc_cygwin', ''))
|
||||
else:
|
||||
import struct
|
||||
if struct.calcsize('I') == 4 and struct.calcsize('L') == 8 and struct.calcsize('P') == 8:
|
||||
scan_targets.extend([('gcc_ILP32', '-m32'), ('gcc_LP64', '-m64')])
|
||||
elif struct.calcsize('I') == 4 and struct.calcsize('L') == 4 and struct.calcsize('P') == 4:
|
||||
scan_targets.append(('gcc_ILP32', ''))
|
||||
else:
|
||||
raise Utils.WafError("Cannot scan python bindings for unsupported data model")
|
||||
for target, cflags in scan_targets:
|
||||
for module in Options.options.apiscan.split(','):
|
||||
apiscan_task(bld.path, env, bld, target, cflags, module)
|
||||
python_scan_task_collector(bld.path, env, bld)
|
||||
return
|
||||
|
||||
|
||||
if env['ENABLE_PYTHON_BINDINGS'] and env['BINDINGS_TYPE'] in ('monolithic', 'both'):
|
||||
apidefs = env['PYTHON_BINDINGS_APIDEFS']
|
||||
|
||||
## Get a list of scanned modules; the set of scanned modules
|
||||
@@ -518,7 +634,7 @@ def build(bld):
|
||||
if name.endswith("__local"):
|
||||
continue
|
||||
scanned_modules.append(name)
|
||||
|
||||
print "scanned_modules:", scanned_modules
|
||||
debug = ('PYBINDGEN_DEBUG' in os.environ)
|
||||
source = [
|
||||
'ns3modulegen.py',
|
||||
@@ -610,3 +726,5 @@ def build(bld):
|
||||
pass
|
||||
print "%r -> %r" % (src, dst)
|
||||
shutil.copy2(src, dst)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user