def generate(defined_symbols, extraIncludes): messages.disable( messages.W1005 # using a non public variable type for arguments or returns , messages.W1006 # `Py++` need your # help to expose function that takes > as argument/returns C++ arrays. # Take a look on "Function Transformation" > functionality and define # the transformation. , messages.W1007 # more than 10 args -> BOOST_PYTHON_MAX_ARITY is set , messages.W1009 # execution error W1009: The function takes as argument (name=pFunIdx, pos=1) > # non-const reference to Python immutable type - function could not be called > from Python , messages.W1014 # "operator*" is not supported. See , messages.W1016 # `Py++` does not exports non-const casting operators # Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X , messages.W1023 # Py++` will generate class wrapper - there are few functions that should be # redefined in class wrapper , messages.W1025 # `Py++` will generate class wrapper - class contains "c_" - T* > member variable , messages.W1026 # `Py++` will generate class wrapper - class contains "arr_" - T& > member variable , messages.W1027 # `Py++` will generate class wrapper - class contains "mat_" - > array member variable , messages.W1035 # error. `Py++` can not expose static pointer member variables. , messages.W1036 # error. `Py++` can not expose pointer to Python immutable > member variables. This # could be changed in future. , messages.W1040 # error. The declaration is unexposed, but there are other > declarations, which # refer to it. This could cause "no to_python converter > found" run # time error # This is serious and lead to RuntimeError: `Py++` is going to write different content to the same file , messages.W1047 # There are two or more classes that use same > alias("MatElement"). Duplicated aliases causes # few problems, but the main one > is that some of the classes will not # be exposed to Python.Other classes : > , messages.W1049 # This method could not be overriden in Python - method returns > # reference to local variable! , messages.W1052 # `Py++` will not expose free operator ) logger.debug("Install SRC: ", os.path.abspath(__file__)) logger.debug("Execute from: ", os.getcwd()) sourcedir = os.path.dirname(os.path.abspath(__file__)) sourceHeader = os.path.abspath(sourcedir + "/" + r"pygimli.h") gimliInclude = os.path.dirname( os.path.abspath(sourcedir + "/../src/" + r"gimli.h")) settings.includesPaths.append(gimliInclude) xml_cached_fc = parser.create_cached_source_fc( sourceHeader, settings.module_name + '.cache') import platform defines = ['PYGIMLI_CAST', 'HAVE_BOOST_THREAD_HPP'] caster = 'gccxml' compiler_path = options.clang if platform.system() == 'Windows': if platform.architecture()[0] == '64bit': #compiler_path = 'C:/msys64/mingw64/bin/clang++' if sys.platform == 'darwin': pass else: defines.append('_WIN64') defines.append('MS_WIN64') logger.info('Marking win64 for gccxml') else: pass #compiler_path = 'C:/msys32/mingw32/bin/clang++' if len(compiler_path) == 0: compiler_path = None for define in [settings.gimli_defines, defined_symbols]: if len(define) > 0: defines.append(define) try: if sys.platform == 'win32': # os.name == 'nt' (default on my mingw)results in wrong commandline # for gccxml os.name = 'mingw' casterpath = settings.caster_path.replace('\\', '\\\\') casterpath = settings.caster_path.replace('/', '\\') if 'gccxml' not in casterpath: caster = 'castxml' if '.exe' not in casterpath: casterpath += '\\' + caster + '.exe' else: casterpath = settings.caster_path if 'gccxml' not in casterpath: caster = 'castxml' except Exception as e: logger.info("caster_path=%s" % casterpath) logger.info(str(e)) raise Exception("Problems determine castxml binary") settings.includesPaths.insert(0, os.path.abspath(extraIncludes)) logger.info("caster_path=%s" % casterpath) logger.info("working_directory=%s" % settings.gimli_path) logger.info("include_paths=%s" % settings.includesPaths) logger.info("define_symbols=%s" % defines) logger.info("compiler_path=%s" % compiler_path) logger.info("indexing_suite_version=2") xml_generator_config = parser.xml_generator_configuration_t( xml_generator=caster, xml_generator_path=casterpath, working_directory=settings.gimli_path, include_paths=settings.includesPaths, define_symbols=defines, ignore_gccxml_output=False, cflags="", compiler_path=compiler_path) mb = module_builder.module_builder_t( [xml_cached_fc], indexing_suite_version=2, xml_generator_config=xml_generator_config ) logger.info("Reading of c++ sources done.") mb.classes().always_expose_using_scope = True mb.calldefs().create_with_signature = True global_ns = mb.global_ns global_ns.exclude() main_ns = global_ns.namespace(MAIN_NAMESPACE) main_ns.include() # for c in main_ns.free_functions(): # print(c) # if 'pow' in c.name: # print(c) # print(c.name) # if c.decl_string.startswith('::GIMLI::pow'): # print(c) # print(c.name) # sys.exit() logger.info("Apply handmade wrappers.") try: hand_made_wrappers.apply(mb) except BaseException as e: print(e) logger.info("Apply custom rvalues.") # START manual r-value converters rvalue_converters = [ 'register_pytuple_to_rvector3_conversion', 'register_pysequence_to_rvector_conversion', # 'register_pysequence_to_bvector_conversion', 'register_pysequence_to_indexvector_conversion', 'register_pysequence_to_r3vector_conversion', 'register_pysequence_to_StdVectorRVector3_conversion', # 'register_rvector_to_ndarray_conversion', ] for converter in rvalue_converters: mb.add_declaration_code('void %s();' % converter) mb.add_registration_code('%s();' % converter) # END manual r-value converters custom_rvalue_path = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp') logger.info("Starting to exclude stuff that we don't need " "or that is known to be spurious.") exclude(main_ns.variables, name=[ 'Triangle6_S1', 'Triangle6_S2', 'Triangle6_S3', 'HexahedronFacesID', 'Hexahedron20FacesID', 'TetrahedronFacesID', 'HexahedronSplit5TetID', 'HexahedronSplit6TetID', 'TriPrismFacesID', 'TriPrimSplit3TetID', 'NodeCoordinates', 'EdgeCoordinates', 'TriCoordinates', 'QuadCoordinates', 'TetCoordinates', 'HexCoordinates', 'PrismCoordinates', 'PyramidCoordinates', 'PyramidFacesID', 'Tet10NodeSplit', 'Tet10NodeSplitZienk', 'Hex20NodeSplit', 'Prism15NodeSplit', 'Pyramid13NodeSplit' ] ) exclude(main_ns.free_functions, return_type=[ 'float *', 'float &', "::GIMLI::__VectorExpr< double, " + "GIMLI::__VectorUnaryExprOp< double, " + "GIMLI::VectorIterator< double >, GIMLI::ABS_ > >"], name=[ 'strReplaceBlankWithUnderscore', 'toStr', 'toInt', 'toFloat', 'toDouble', 'str', 'getRowSubstrings', 'getNonEmptyRow', 'getSubstrings', 'abs', 'type'] ) exclude(main_ns.free_operators, name=[''], return_type=['::std::ostream &', '::std::istream &'] ) exclude(main_ns.classes, name=['ABS_', 'ACOT', 'ATAN', 'COS', 'COT', 'EXP', 'ABS_', 'LOG', 'LOG10', 'SIGN', 'SIN', 'SQRT', 'SQR', 'TAN', 'TANH', 'PLUS', 'MINUS', 'MULT', 'DIVID', 'BINASSIGN', 'cerrPtr', 'cerrPtrObject', 'coutPtr', 'coutPtrObject', 'deletePtr', 'edge_', 'distancePair_', 'IPCMessage', 'PythonGILSave', ] ) exclude(main_ns.member_functions, name=['begin', 'end', 'val'], return_type=[''] ) exclude(main_ns.member_operators, symbol=['']) for f in main_ns.declarations: if isinstance(f, decl_wrappers.calldef_wrapper.free_function_t): if (str(f.return_type).find('GIMLI::VectorExpr') != -1): f.exclude() ex = ['::GIMLI::MatrixElement', '::GIMLI::__VectorUnaryExprOp', '::GIMLI::__VectorBinaryExprOp', '::GIMLI::__ValVectorExprOp', '::GIMLI::__VectorValExprOp', '::GIMLI::__VectorExpr', '::GIMLI::Expr', '::GIMLI::InversionBase', 'GIMLI::MatrixElement', 'GIMLI::__VectorUnaryExprOp', 'GIMLI::__VectorBinaryExprOp', 'GIMLI::__ValVectorExprOp', 'GIMLI::__VectorValExprOp', 'GIMLI::__VectorExpr', 'GIMLI::Expr', 'GIMLI::InversionBase', 'std::vector<unsigned long', 'std::vector<bool', 'std::vector<double', ] for c in main_ns.free_functions(): for e in ex: if c.decl_string.find(e) > -1: try: c.exclude() logger.debug("Exclude: " + str(c)) except BaseException as _: logger.debug("Fail to exclude: " + str(c)) for c in main_ns.classes(): for e in ex: if c.decl_string.startswith(e): try: c.exclude() logger.debug("Exclude: " + c.name) except BaseException as _: logger.debug("Fail to exclude: " + c.name) try: for mem in c.variables(): try: mem.exclude() # logger.info("Exclude: " + str(mem)) except BaseException as _: logger.debug("Fail to exclude: " + str(mem)) except BaseException as _: # print(c, "has no member functions") pass try: for mem in c.constructors(): for e in ex: if mem.decl_string.find(e) > -1: try: mem.exclude() # logger.info("Exclude: " + str(mem)) except BaseException as _: logger.debug("Fail to exclude: " + str(mem)) for mem in c.member_functions(): for e in ex: if mem.decl_string.find(e) > -1: try: mem.exclude() # logger.info("Exclude: " + str(mem)) except BaseException as _: logger.debug("Fail to exclude: " + str(mem)) except BaseException as _: # print(c, "has no member functions") pass # print('#'*100) # print(c, c.name) if c.name.startswith('Vector<unsigned long>'): # print(' ', c.name) for mem in c.constructors(): # print("mem", mem, mem.decl_string) if mem.decl_string.find('( ::GIMLI::Index )') > -1: logger.debug("Exclude: " + str(mem)) mem.exclude() # print("mem", mem) try: mb.calldefs(access_type_matcher_t('protected')).exclude() mb.calldefs(access_type_matcher_t('private')).exclude() except BaseException as _: pass # setMemberFunctionCallPolicieByReturn(mb, [ '::GIMLI::Node &' # , '::GIMLI::Cell &' # , '::GIMLI::Boundary &' # , '::GIMLI::Shape &' # , '::GIMLI::Node *' # , '::GIMLI::Cell *' # , '::GIMLI::Boundary *' # , '::GIMLI::Shape *' # ] # , call_policies.reference_existing_object) setMemberFunctionCallPolicieByReturn( mb, ['::std::string *', 'float *', 'double *', 'int *', 'long *', 'long int *', 'long long int *', 'unsigned int *', 'long unsigned int *', 'unsigned long long int *', 'long long unsigned int *', '::GIMLI::Index *', '::GIMLI::SIndex *', 'bool *'], call_policies.return_pointee_value) setMemberFunctionCallPolicieByReturn(mb, ['::std::string &', 'float &', 'double &', 'int &', 'long &', 'long int &', 'long long int &', 'unsigned int &', 'long unsigned int &', 'long long unsigned int &', 'unsigned long long int &', '::GIMLI::Index &', '::GIMLI::SIndex &', 'bool &' ], call_policies.return_by_value) # setMemberFunctionCallPolicieByReturn(mb, # ['::GIMLI::VectorIterator<double> &'] # , call_policies.copy_const_reference) # setMemberFunctionCallPolicieByReturn(mb, [ # , 'double &' ] # , call_policies.reference_existing_object) # call_policies.return_value_policy(call_policies.reference_existing_object) # call_policies.return_value_policy(call_policies.copy_non_const_reference) # call_policies.return_value_policy(call_policies.copy_const_reference) # addAutoConversions(mb) # excludeMemberByReturn(main_ns, ['::DCFEMLib::SparseMatrix<double> &']) # fun = mb.global_ns.member_functions('begin', allow_empty=True) # for f in fun: # f.exclude() # excludeFreeFunctionsByName(main_ns, ['strReplaceBlankWithUnderscore' # 'toStr', 'toInt', 'toFloat', 'toDouble', # 'getRowSubstrings', 'getNonEmptyRow', 'getSubstrings' ]) # excludeFreeFunctionsByReturn(main_ns, [ 'float *', 'float &' ]) # fun = ns.free_operators(return_type=funct, allow_empty=True) # excludeMemberOperators(main_ns, ['++', '--', '*']) # exclude all that does not match any predefined callpolicie excludeRest = True if excludeRest: mem_funs = mb.calldefs() for mem_fun in mem_funs: if mem_fun.call_policies: continue if not mem_fun.call_policies and \ (declarations.is_reference(mem_fun.return_type) or declarations.is_pointer(mem_fun.return_type)): # print mem_fun # mem_fun.exclude() mem_fun.call_policies = call_policies.return_value_policy( call_policies.reference_existing_object) # mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.return_pointee_value) # mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.return_opaque_pointer) # mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.copy_non_const_reference) logger.info("Create api documentation from Doxgen comments.") # Now it is the time to give a name to our module from doxygen import doxygen_doc_extractor extractor = doxygen_doc_extractor() logger.info("Create code creator.") mb.build_code_creator(settings.module_name, doc_extractor=extractor) # It is common requirement in software world-each file should have license # mb.code_creator.license = '//Boost Software # License(http://boost.org/more/license_info.html)' # I don't want absolute includes within code mb.code_creator.user_defined_directories.append(os.path.abspath('.')) # And finally we can write code to the disk def ignore(val): pass logger.info("Create bindings code.") mb.split_module('./generated', on_unused_file_found=ignore) additional_files = [ os.path.join( os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp'), os.path.join( os.path.abspath(os.path.dirname(__file__)), 'generators.h'), os.path.join( os.path.abspath(os.path.dirname(__file__)), 'tuples.hpp')] logger.info("Add additional files.") for sourcefile in additional_files: p, filename = os.path.split(sourcefile) destfile = os.path.join('./generated', filename) if not samefile(sourcefile, destfile): shutil.copy(sourcefile, './generated') logger.info("Updated " + filename + "as it was missing or out of date")
def generate(defined_symbols, extraIncludes): messages.disable( messages.W1005 # using a non public variable type for arguments or returns , messages.W1006 # `Py++` need your # help to expose function that takes > as argument/returns C++ arrays. # Take a look on "Function Transformation" > functionality and define # the transformation. , messages.W1007 # more than 10 args -> BOOST_PYTHON_MAX_ARITY is set , messages.W1009 # execution error W1009: The function takes as argument (name=pFunIdx, pos=1) > # non-const reference to Python immutable type - function could not be called > from Python , messages.W1014 # "operator*" is not supported. See , messages.W1016 # `Py++` does not exports non-const casting operators # Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X , messages.W1023 # Py++` will generate class wrapper - there are few functions that should be # redefined in class wrapper , messages.W1025 # `Py++` will generate class wrapper - class contains "c_" - T* > member variable , messages.W1026 # `Py++` will generate class wrapper - class contains "arr_" - T& > member variable , messages.W1027 # `Py++` will generate class wrapper - class contains "mat_" - > array member variable , messages.W1035 # error. `Py++` can not expose static pointer member variables. , messages.W1036 # error. `Py++` can not expose pointer to Python immutable > member variables. This # could be changed in future. , messages.W1040 # error. The declaration is unexposed, but there are other > declarations, which # refer to it. This could cause "no to_python converter > found" run # time error # This is serious and lead to RuntimeError: `Py++` is going to write different content to the same file , messages.W1047 # There are two or more classes that use same > alias("MatElement"). Duplicated aliases causes # few problems, but the main one > is that some of the classes will not # be exposed to Python.Other classes : > , messages.W1049 # This method could not be overriden in Python - method returns > # reference to local variable! , messages.W1052 # `Py++` will not expose free operator ) logger.debug("Install SRC: ", os.path.abspath(__file__)) logger.debug("Execute from: ", os.getcwd()) sourcedir = os.path.dirname(os.path.abspath(__file__)) sourceHeader = os.path.abspath(sourcedir + "/" + r"pygimli.h") gimliInclude = os.path.dirname( os.path.abspath(sourcedir + "/../src/" + r"gimli.h")) settings.includesPaths.append(gimliInclude) xml_cached_fc = parser.create_cached_source_fc( sourceHeader, settings.module_name + '.cache') #xml_cached_fc = parser.create_cached_source_fc(os.path.join(r"pygimli.h"), settings.module_name + '.cache') import platform defines = ['PYGIMLI_CAST', 'HAVE_BOOST_THREAD_HPP'] caster = 'gccxml' if platform.architecture()[ 0] == '64bit' and platform.system() == 'Windows': if sys.platform == 'darwin': pass else: defines.append('_WIN64') logger.info('Marking win64 for gccxml') for define in [settings.gimli_defines, defined_symbols]: if len(define) > 0: defines.append(define) try: if sys.platform == 'win32': # os.name == 'nt' (default on my mingw) results in wrong commandline # for gccxml os.name = 'mingw' casterpath = settings.caster_path.replace('\\', '\\\\') casterpath = settings.caster_path.replace('/', '\\') if not 'gccxml' in casterpath: caster = 'castxml' if not '.exe' in casterpath: casterpath += '\\' + caster + '.exe' else: casterpath = settings.caster_path if not 'gccxml' in casterpath: caster = 'castxml' except Exception as e: logger.info("caster_path=%s" % casterpath) logger.info(str(e)) raise Exception("Problems determine castxml binary") settings.includesPaths.insert(0, os.path.abspath(extraIncludes)) logger.info("caster_path=%s" % casterpath) logger.info("working_directory=%s" % settings.gimli_path) logger.info("include_paths=%s" % settings.includesPaths) logger.info("define_symbols=%s" % defines) logger.info("indexing_suite_version=2") mb = module_builder.module_builder_t([xml_cached_fc], gccxml_path=casterpath, working_directory=settings.gimli_path, include_paths=settings.includesPaths, define_symbols=defines, indexing_suite_version=2, caster=caster ) logger.info("Reading of c++ sources done.") mb.classes().always_expose_using_scope = True mb.calldefs().create_with_signature = True global_ns = mb.global_ns global_ns.exclude() main_ns = global_ns.namespace(MAIN_NAMESPACE) main_ns.include() #for c in main_ns.free_functions(): ##print(c) #if 'pow' in c.name: #print(c) #print(c.name) ##if c.decl_string.startswith('::GIMLI::pow'): ##print(c) ##print(c.name) #sys.exit() logger.info("Apply handmade wrappers.") hand_made_wrappers.apply(mb) logger.info("Apply custom rvalues.") # START manual r-value converters rvalue_converters = [ 'register_pytuple_to_rvector3_conversion', 'register_pysequence_to_rvector_conversion', #'register_pysequence_to_bvector_conversion', 'register_pysequence_to_indexvector_conversion', 'register_pysequence_to_r3vector_conversion', 'register_pysequence_to_StdVectorRVector3_conversion', #'register_rvector_to_ndarray_conversion', ] for converter in rvalue_converters: mb.add_declaration_code('void %s();' % converter) mb.add_registration_code('%s();' % converter) # END manual r-value converters custom_rvalue_path = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp') logger.info("Starting to exclude stuff that we don't need or that is known to be spurious.") exclude(main_ns.variables, name=[ 'Triangle6_S1', 'Triangle6_S2', 'Triangle6_S3', 'HexahedronFacesID', 'Hexahedron20FacesID', 'TetrahedronFacesID', 'HexahedronSplit5TetID', 'HexahedronSplit6TetID', 'TriPrismFacesID', 'TriPrimSplit3TetID', 'NodeCoordinates', 'EdgeCoordinates', 'TriCoordinates', 'QuadCoordinates', 'TetCoordinates', 'HexCoordinates', 'PrismCoordinates', 'PyramidCoordinates', 'PyramidFacesID', 'Tet10NodeSplit', 'Tet10NodeSplitZienk', 'Hex20NodeSplit', 'Prism15NodeSplit', 'Pyramid13NodeSplit' ] ) exclude(main_ns.free_functions, return_type=[ 'float *', 'float &', "::GIMLI::__VectorExpr< double, GIMLI::__VectorUnaryExprOp< double, GIMLI::VectorIterator< double >, GIMLI::ABS_ > >"], name=[ 'strReplaceBlankWithUnderscore', 'toStr', 'toInt', 'toFloat', 'toDouble', 'str', 'getRowSubstrings', 'getNonEmptyRow', 'getSubstrings', 'abs', 'type'] ) exclude(main_ns.free_operators, name=[''], return_type=['::std::ostream &', '::std::istream &'] ) exclude(main_ns.classes, name=['ABS_', 'ACOT', 'ATAN', 'COS', 'COT', 'EXP', 'ABS_', 'LOG', 'LOG10', 'SIGN', 'SIN', 'SQRT', 'SQR', 'TAN', 'TANH', 'PLUS', 'MINUS', 'MULT', 'DIVID', 'BINASSIGN', 'cerrPtr', 'cerrPtrObject', 'coutPtr', 'coutPtrObject', 'deletePtr', 'edge_', 'distancePair_', 'IPCMessage', 'PythonGILSave', ] ) exclude(main_ns.member_functions, name=['begin', 'end', 'val'], return_type=[''] ) exclude(main_ns.member_operators, symbol=['']) for f in main_ns.declarations: if isinstance(f, decl_wrappers.calldef_wrapper.free_function_t): if (str(f.return_type).find('GIMLI::VectorExpr') != -1): f.exclude() ex = ['::GIMLI::MatrixElement', '::GIMLI::__VectorUnaryExprOp', '::GIMLI::__VectorBinaryExprOp', '::GIMLI::__ValVectorExprOp', '::GIMLI::__VectorValExprOp', '::GIMLI::__VectorExpr', '::GIMLI::Expr', '::GIMLI::InversionBase', 'GIMLI::MatrixElement', 'GIMLI::__VectorUnaryExprOp', 'GIMLI::__VectorBinaryExprOp', 'GIMLI::__ValVectorExprOp', 'GIMLI::__VectorValExprOp', 'GIMLI::__VectorExpr', 'GIMLI::Expr', 'GIMLI::InversionBase', 'std::vector<unsigned long', ] for c in main_ns.free_functions(): for e in ex: if c.decl_string.find(e) > -1: try: c.exclude() logger.debug("Exclude: " + str(c)) except: logger.debug("Fail to exclude: " + str(c)) for c in main_ns.classes(): for e in ex: if c.decl_string.startswith(e): try: c.exclude() logger.debug("Exclude: " + c.name) except: logger.debug("Fail to exclude: " + c.name) try: for mem in c.constructors(): for e in ex: if mem.decl_string.find(e) > -1: try: mem.exclude() #logger.info("Exclude: " + str(mem)) except: logger.debug("Fail to exclude: " + str(mem)) for mem in c.member_functions(): for e in ex: if mem.decl_string.find(e) > -1: try: mem.exclude() #logger.info("Exclude: " + str(mem)) except: logger.debug("Fail to exclude: " + str(mem)) except: #print(c, "has no member functions") pass #print('#'*100) #print(c, c.name) if c.name.startswith('Vector<unsigned long>'): #print(' ', c.name) for mem in c.constructors(): #print("mem", mem, mem.decl_string) if mem.decl_string.find('( ::GIMLI::Index )') > -1: logger.debug("Exclude: " + str(mem)) mem.exclude() #print("mem", mem) mb.calldefs(access_type_matcher_t('protected')).exclude() mb.calldefs(access_type_matcher_t('private')).exclude() # setMemberFunctionCallPolicieByReturn(mb, [ '::GIMLI::Node &' #, '::GIMLI::Cell &' #, '::GIMLI::Boundary &' #, '::GIMLI::Shape &' #, '::GIMLI::Node *' #, '::GIMLI::Cell *' #, '::GIMLI::Boundary *' #, '::GIMLI::Shape *' #] #, call_policies.reference_existing_object) setMemberFunctionCallPolicieByReturn( mb, ['::std::string *', 'float *', 'double *', 'int *', 'long *', 'long int *', 'long long int *', 'unsigned int *', 'long unsigned int *', 'unsigned long long int *', '::GIMLI::Index *', '::GIMLI::SIndex *', 'bool *'], call_policies.return_pointee_value) setMemberFunctionCallPolicieByReturn(mb, ['::std::string &', 'float &', 'double &', 'int &', 'long &', 'long int &', 'long long int &', 'unsigned int &', 'long unsigned int &', 'unsigned long long int &', '::GIMLI::Index &', '::GIMLI::SIndex &', 'bool &' ], call_policies.return_by_value) # setMemberFunctionCallPolicieByReturn(mb, ['::GIMLI::VectorIterator<double> &'] #, call_policies.copy_const_reference) # setMemberFunctionCallPolicieByReturn(mb, [ #, 'double &' ] #, call_policies.reference_existing_object) # call_policies.return_value_policy(call_policies.reference_existing_object) # call_policies.return_value_policy(call_policies.copy_non_const_reference) # call_policies.return_value_policy(call_policies.copy_const_reference) # addAutoConversions(mb) # excludeMemberByReturn(main_ns, ['::DCFEMLib::SparseMatrix<double> &']) #main_ns.classes(decl_starts_with(['STLMatrix']), allow_empty=True).exclude() #fun = mb.global_ns.member_functions('begin', allow_empty=True) # for f in fun: # f.exclude() # excludeFreeFunctionsByName(main_ns, ['strReplaceBlankWithUnderscore' #'toStr', 'toInt', 'toFloat', 'toDouble', #'getRowSubstrings', 'getNonEmptyRow', 'getSubstrings' ]) #excludeFreeFunctionsByReturn(main_ns, [ 'float *', 'float &' ]) #fun = ns.free_operators(return_type=funct, allow_empty=True) #excludeMemberOperators(main_ns, ['++', '--', '*']) # exclude all that does not match any predefined callpolicie excludeRest = True if excludeRest: mem_funs = mb.calldefs() for mem_fun in mem_funs: if mem_fun.call_policies: continue if not mem_fun.call_policies and \ (declarations.is_reference(mem_fun.return_type) or declarations.is_pointer(mem_fun.return_type)): # print mem_fun # mem_fun.exclude() mem_fun.call_policies = call_policies.return_value_policy( call_policies.reference_existing_object) # mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.return_pointee_value) # mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.return_opaque_pointer) # mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.copy_non_const_reference) logger.info("Create api documentation from Doxgen comments.") # Now it is the time to give a name to our module from doxygen import doxygen_doc_extractor extractor = doxygen_doc_extractor() logger.info("Create code creator.") mb.build_code_creator(settings.module_name, doc_extractor=extractor) # It is common requirement in software world - each file should have license #mb.code_creator.license = '//Boost Software License(http://boost.org/more/license_info.html)' # I don't want absolute includes within code mb.code_creator.user_defined_directories.append(os.path.abspath('.')) # And finally we can write code to the disk def ignore(val): pass logger.info("Create bindings code.") mb.split_module('./generated', on_unused_file_found=ignore) additional_files = [ os.path.join( os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp'), os.path.join( os.path.abspath(os.path.dirname(__file__)), 'generators.h'), os.path.join( os.path.abspath(os.path.dirname(__file__)), 'tuples.hpp')] logger.info("Add additional files.") for sourcefile in additional_files: p, filename = os.path.split(sourcefile) destfile = os.path.join('./generated', filename) if not samefile(sourcefile, destfile): shutil.copy(sourcefile, './generated') logger.info("Updated " + filename + "as it was missing or out of date")
#from environment import gccxml from pygccxml import declarations from pygccxml.declarations.matchers import access_type_matcher_t from pyplusplus import code_creators from pyplusplus import module_builder from pyplusplus import function_transformers as FT from doxygen import doxygen_doc_extractor from pyplusplus.module_builder import call_policies """ """ myextractor=doxygen_doc_extractor() if __name__ == '__main__': module_name = '_libsimpa' #1. creating module builder mb = module_builder.module_builder_t( files=[ os.path.abspath('../dummy.hpp') ] , gccxml_path=os.environ["GCCXML"] , encoding='iso-8859-1') #mb.namespace("core_mathlib").exclude() mb.calldefs( access_type_matcher_t( 'protected' ) ).exclude() mb.calldefs( access_type_matcher_t( 'private' ) ).exclude() # #################################################### # SCRIPT POUR ../input_output/bin.h
def generate(defined_symbols, extraIncludes): # messages.disable( # messages.W1005 # using a non public variable type for argucments or returns ## Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X # , messages.W1009 # check this # , messages.W1014 # check this # , messages.W1020 # , messages.W1021 # , messages.W1022 # , messages.W1023 # , messages.W1024 # , messages.W1025 # , messages.W1026 # , messages.W1027 # , messages.W1028 # , messages.W1029 # , messages.W1030 # , messages.W1031 # , messages.W1036 # check this #) print("Install SRC: ", os.path.abspath(__file__)) print("Execute from: ", os.getcwd()) sourcedir = os.path.dirname(os.path.abspath(__file__)) sourceHeader = os.path.abspath(sourcedir + "/" + r"pygimli.h") gimliInclude = os.path.dirname(os.path.abspath(sourcedir + "/../src/" + r"gimli.h")) settings.includesPaths.append(gimliInclude) xml_cached_fc = parser.create_cached_source_fc(sourceHeader, settings.module_name + '.cache') #xml_cached_fc = parser.create_cached_source_fc(os.path.join(r"pygimli.h"), settings.module_name + '.cache') import platform defines = ['PYGIMLI_GCCXML', 'HAVE_BOOST_THREAD_HPP'] if platform.architecture()[0] == '64bit' and platform.architecture()[1] != 'ELF': if sys.platform == 'darwin': pass else: defines.append('_WIN64') print('Marking win64 for gccxml') for define in [settings.gimli_defines, defined_symbols]: if len(define) > 0: defines.append(define) try: if sys.platform == 'win32': #os.name == 'nt' (default on my mingw) results in wrong commandline for gccxml os.name = 'mingw' gccxmlpath = settings.gccxml_path.replace('\\', '\\\\') + '\\\\gccxml.exe' else: gccxmlpath = settings.gccxml_path except Exception as e: print (str(e)) raise Exception("Problems determine gccxml binary") settings.includesPaths.insert(0,os.path.abspath(extraIncludes)) print("gccxml-binary: ", gccxmlpath) print("extra-include: ", os.path.abspath(extraIncludes)) print("gccxml includes: ", settings.includesPaths) print("gccxml defines: ", defines) mb = module_builder.module_builder_t([xml_cached_fc], gccxml_path=gccxmlpath, working_directory=settings.gimli_path, include_paths=settings.includesPaths, define_symbols=defines, indexing_suite_version=2) mb.classes().always_expose_using_scope = True mb.calldefs().create_with_signature = True hand_made_wrappers.apply(mb) global_ns = mb.global_ns global_ns.exclude() main_ns = global_ns.namespace(MAIN_NAMESPACE) main_ns.include() ### START manual r-value converters rvalue_converters = [ 'register_pysequence_to_StdVectorUL_conversion', 'register_pytuple_to_rvector3_conversion', 'register_pysequence_to_rvector_conversion', 'register_pysequence_to_StdVectorRVector3_conversion' ] for converter in rvalue_converters: mb.add_declaration_code('void %s();' % converter) mb.add_registration_code('%s();' % converter) ### END manual r-value converters custom_rvalue_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp') exclude(main_ns.variables, name = [ 'Triangle6_S1', 'Triangle6_S2', 'Triangle6_S3' , 'HexahedronFacesID', 'Hexahedron20FacesID' , 'TetrahedronFacesID' , 'HexahedronSplit5TetID', 'HexahedronSplit6TetID' , 'TriPrismFacesID', 'TriPrimSplit3TetID' , 'NodeCoordinates','EdgeCoordinates' , 'TriCoordinates', 'QuadCoordinates' , 'TetCoordinates', 'HexCoordinates' , 'PrismCoordinates', 'PyramidCoordinates', 'PyramidFacesID' , 'Tet10NodeSplit', 'Tet10NodeSplitZienk' , 'Hex20NodeSplit', 'Prism15NodeSplit', 'Pyramid13NodeSplit' ]) for f in main_ns.declarations: if type(f) == decl_wrappers.calldef_wrapper.free_function_t: if (str(f.return_type).find('GIMLI::VectorExpr') != -1): f.exclude() exclude(main_ns.free_functions, return_type = [ 'float *', 'float &' ,"::GIMLI::__VectorExpr< double, GIMLI::__VectorUnaryExprOp< double, GIMLI::VectorIterator< double >, GIMLI::ABS_ > >" ], name = [ 'strReplaceBlankWithUnderscore' , 'toStr', 'toInt', 'toFloat', 'toDouble', 'str' , 'getRowSubstrings', 'getNonEmptyRow', 'getSubstrings' , 'abs' , 'type' ]) exclude(main_ns.free_operators, name = [''], return_type = ['::std::ostream &', '::std::istream &']) exclude(main_ns.classes, name = [ 'ABS_', 'ACOT', 'ATAN', 'COS', 'COT', 'EXP', 'ABS_', 'LOG', 'LOG10', 'SIGN' ,'SIN', 'SQRT', 'SQR', 'TAN', 'TANH', 'PLUS', 'MINUS', 'MULT', 'DIVID', 'BINASSIGN' ,'cerrPtr', 'cerrPtrObject', 'coutPtr', 'coutPtrObject', 'deletePtr' ,'edge_', 'distancePair_' ,'IPCMessage' ,'PythonGILSave' ,'__VectorExpr' ,'__VectorUnaryExprOp' ,'__VectorBinaryExprOp' ,'__VectorValExprOp' ,'__ValVectorExprOp' ,'::GIMLI::__VectorValExprOp< double, GIMLI::__VectorIterator< double >, GIMLI::MULT >' ,'::GIMLI::__VectorBinaryExprOp< double, GIMLI::__VectorIterator< double >, GIMLI::__VectorIterator< double >, GIMLI::MULT>' ,'::GIMLI::__VectorExpr< double, GIMLI::__VectorBinaryExprOp< double, GIMLI::__VectorIterator< double >, GIMLI::__VectorIterator< double >, GIMLI::MULT > >' ,'::GIMLI::__VectorExpr< double, GIMLI::__VectorValExprOp< double, GIMLI::__VectorIterator< double >, GIMLI::MULT > >' ,'::GIMLI::__VectorExpr< double, GIMLI::__VectorUnaryExprOp< double, GIMLI::__VectorIterator< double >, GIMLI::LOG10 > >' ,'::GIMLI::__VectorExpr< double, GIMLI::__VectorUnaryExprOp< double, GIMLI::__VectorIterator< double >, GIMLI::LOG > >' ,'::GIMLI::__VectorUnaryExprOp< double, GIMLI::__VectorIterator< double >, GIMLI::LOG10 >' ,'::GIMLI::__VectorUnaryExprOp< double, GIMLI::__VectorIterator< double >, GIMLI::LOG >' ,'::GIMLI::__VectorExpr<double, GIMLI::__VectorValExprOp<double, GIMLI::__VectorExpr<double, GIMLI::__ValVectorExprOp<double, GIMLI::__VectorIterator<double >, GIMLI::MULT > >, GIMLI::MULT > >' ,'::GIMLI::__VectorValExprOp<double, GIMLI::__VectorExpr<double, GIMLI::__ValVectorExprOp<double, GIMLI::__VectorIterator<double >, GIMLI::MULT > >, GIMLI::MULT >.pypp.hpp', 'GIMLI::Expr<GIMLI::ExprIdentity>' ]) exclude(main_ns.member_functions, name = ['begin', 'end', 'val'], return_type = ['']) exclude(main_ns.member_operators, symbol = ['']) mb.calldefs(access_type_matcher_t('protected')).exclude() mb.calldefs(access_type_matcher_t('private')).exclude() #setMemberFunctionCallPolicieByReturn(mb, [ '::GIMLI::Node &' #, '::GIMLI::Cell &' #, '::GIMLI::Boundary &' #, '::GIMLI::Shape &' #, '::GIMLI::Node *' #, '::GIMLI::Cell *' #, '::GIMLI::Boundary *' #, '::GIMLI::Shape *' #] #, call_policies.reference_existing_object) setMemberFunctionCallPolicieByReturn(mb, [ '::std::string *', 'float *', 'double *', 'int *', 'long *' , 'long long int *', 'unsigned long long int *' , '::GIMLI::Index *'] , call_policies.return_pointee_value) #setMemberFunctionCallPolicieByReturn(mb, ['::GIMLI::VectorIterator<double> &'] #, call_policies.copy_const_reference) setMemberFunctionCallPolicieByReturn(mb, ['::std::string &' , 'double &' ] , call_policies.return_by_value) #setMemberFunctionCallPolicieByReturn(mb, [ #, 'double &' ] #, call_policies.reference_existing_object) #call_policies.return_value_policy(call_policies.reference_existing_object) #call_policies.return_value_policy(call_policies.copy_non_const_reference) #call_policies.return_value_policy(call_policies.copy_const_reference) #addAutoConversions(mb) # excludeMemberByReturn(main_ns, ['::DCFEMLib::SparseMatrix<double> &']) #main_ns.classes(decl_starts_with(['STLMatrix']), allow_empty=True).exclude() #fun = mb.global_ns.member_functions('begin', allow_empty=True) #for f in fun: #f.exclude() #excludeFreeFunctionsByName(main_ns, ['strReplaceBlankWithUnderscore' #'toStr', 'toInt', 'toFloat', 'toDouble', #'getRowSubstrings', 'getNonEmptyRow', 'getSubstrings' ]) #excludeFreeFunctionsByReturn(main_ns, [ 'float *', 'float &' ]) #fun = ns.free_operators(return_type=funct, allow_empty=True) #excludeMemberOperators(main_ns, ['++', '--', '*']) # exclude all that does not match any predefined callpolicie excludeRest = True if excludeRest: mem_funs = mb.calldefs () for mem_fun in mem_funs: if mem_fun.call_policies: continue if not mem_fun.call_policies and \ (declarations.is_reference(mem_fun.return_type) or declarations.is_pointer (mem_fun.return_type)): #print mem_fun #mem_fun.exclude() mem_fun.call_policies = \ call_policies.return_value_policy(call_policies.reference_existing_object) #mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.return_pointee_value) #mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.return_opaque_pointer) #mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.copy_non_const_reference) # Now it is the time to give a name to our module from doxygen import doxygen_doc_extractor extractor = doxygen_doc_extractor() mb.build_code_creator(settings.module_name, doc_extractor=extractor) #It is common requirement in software world - each file should have license #mb.code_creator.license = '//Boost Software License(http://boost.org/more/license_info.html)' #I don't want absolute includes within code mb.code_creator.user_defined_directories.append(os.path.abspath('.')) #And finally we can write code to the disk def ignore(val): pass mb.split_module('./generated', on_unused_file_found=ignore) additional_files = [ os.path.join(os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp'), os.path.join(os.path.abspath(os.path.dirname(__file__)), 'generators.h'), os.path.join(os.path.abspath(os.path.dirname(__file__)), 'tuples.hpp') ] for sourcefile in additional_files: p,filename = os.path.split(sourcefile) destfile = os.path.join('./generated', filename) if not samefile(sourcefile, destfile): shutil.copy(sourcefile, './generated') print("Updated ", filename, "as it was missing or out of date")
bp::implicitly_convertible< std::string, CLAM::EAudioFileCodec >(); bp::implicitly_convertible< int, CLAM::EAudioFileEncoding >(); bp::implicitly_convertible< std::string, CLAM::EAudioFileEncoding >(); bp::implicitly_convertible< int, CLAM::EAudioFileEndianess >(); bp::implicitly_convertible< std::string, CLAM::EAudioFileEndianess >(); bp::implicitly_convertible< int, CLAM::EAudioFileFormat >(); bp::implicitly_convertible< std::string, CLAM::EAudioFileFormat >();""" ) # Classes that need to be registered before others mb.add_registration_code("register_Enum_class();", tail=False) mb.add_registration_code("register_Component_class();", tail=False) #TODO: avoid duplicated classes registering # Creating code creator. After this step you should not modify/customize declarations. mb.build_code_creator( module_name='clam', doc_extractor=doxygen_doc_extractor() ) #// This file has been generated by Py++ from CLAM Library include files mb.code_creator.license = """/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License
bp::implicitly_convertible< int, CLAM::EAudioFileEncoding >(); bp::implicitly_convertible< std::string, CLAM::EAudioFileEncoding >(); bp::implicitly_convertible< int, CLAM::EAudioFileEndianess >(); bp::implicitly_convertible< std::string, CLAM::EAudioFileEndianess >(); bp::implicitly_convertible< int, CLAM::EAudioFileFormat >(); bp::implicitly_convertible< std::string, CLAM::EAudioFileFormat >();""") # Classes that need to be registered before others mb.add_registration_code("register_Enum_class();", tail=False) mb.add_registration_code("register_Component_class();", tail=False) #TODO: avoid duplicated classes registering # Creating code creator. After this step you should not modify/customize declarations. mb.build_code_creator(module_name='clam', doc_extractor=doxygen_doc_extractor()) #// This file has been generated by Py++ from CLAM Library include files mb.code_creator.license = """/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software