#!/usr/bin/env python3 """ Helper script to wrap C++ to Python with Pybind. This script is installed via CMake to the user's binary directory and invoked during the wrapping by CMake. """ # pylint: disable=import-error import argparse import gtwrap.interface_parser as parser import gtwrap.template_instantiator as instantiator from gtwrap.pybind_wrapper import PybindWrapper def main(): """Main runner.""" arg_parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) arg_parser.add_argument( "--src", type=str, required=True, help="Input interface .i/.h file") arg_parser.add_argument( "--module_name", type=str, required=True, help="Name of the Python module to be generated and " "used in the Python `import` statement.", ) arg_parser.add_argument( "--out", type=str, required=True, help="Name of the output pybind .cc file", ) arg_parser.add_argument( "--use-boost", action="store_true", help="using boost's shared_ptr instead of std's", ) arg_parser.add_argument( "--top_module_namespaces", type=str, default="", help="C++ namespace for the top module, e.g. `ns1::ns2::ns3`. " "Only the content within this namespace and its sub-namespaces " "will be wrapped. The content of this namespace will be available at " "the top module level, and its sub-namespaces' in the submodules.\n" "For example, `import ` gives you access to a Python " "`.Class` of the corresponding C++ `ns1::ns2::ns3::Class`" "and `from import ns4` gives you access to a Python " "`ns4.Class` of the C++ `ns1::ns2::ns3::ns4::Class`. ", ) arg_parser.add_argument( "--ignore", nargs='*', type=str, help="A space-separated list of classes to ignore. " "Class names must include their full namespaces.", ) arg_parser.add_argument("--template", type=str, help="The module template file") args = arg_parser.parse_args() top_module_namespaces = args.top_module_namespaces.split("::") if top_module_namespaces[0]: top_module_namespaces = [''] + top_module_namespaces # Read in the complete interface (.i) file with open(args.src, "r") as f: content = f.read() module = parser.Module.parseString(content) instantiator.instantiate_namespace_inplace(module) with open(args.template, "r") as f: template_content = f.read() wrapper = PybindWrapper( module=module, module_name=args.module_name, use_boost=args.use_boost, top_module_namespaces=top_module_namespaces, ignore_classes=args.ignore, module_template=template_content, ) # Wrap the code and get back the cpp/cc code. cc_content = wrapper.wrap() # Generate the C++ code which Pybind11 will use. with open(args.out, "w") as f: f.write(cc_content) if __name__ == "__main__": main()