Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- '''
- libblender test1 - segfaults on WM_init()
- by Harts Antler | Sept 2010 | bhartsho@yahoo.com
- License: LGPL
- Notes:
- 1. after editing CMakeLists.txt, run: cmake -G "Unix Makefiles" ../blender
- 2. game engine must be turned off, line 76: OPTION(WITH_GAMEENGINE "Enable Game Engine" OFF)
- 3. minimal ubuntu setup: apt-get install libxi-dev libopenexr-dev libopenjpeg-dev libsamplerate-dev
- 4. blender/source/creator/CMakeLists.txt - thanks to IdeasMan!
- change: ADD_EXECUTABLE(blender ${EXETYPE} ${EXESRC})
- to: ADD_LIBRARY(blender SHARED ${EXETYPE} ${EXESRC})
- 5. build libblender
- RPython Notes:
- 6. link or copy libblender.so to /usr/lib/
- cd /usr/lib
- sudo ln -s /path/to/my/build/lib/libblender.so
- 7. download pypy source code, set PATH2PYPY below
- '''
- BLENDER_SOURCE = '../blender'
- PATH2PYPY = '../pypy-trunk'
- import os, sys, time, math
- sys.path.append(PATH2PYPY)
- if '--compile' in sys.argv: # compiles RPython
- os.system( 'python %s/pypy/translator/goal/translate.py %s' %(PATH2PYPY, sys.argv[0] ) )
- sys.exit()
- USE_CTYPES = False
- if '--ctypes' in sys.argv: USE_CTYPES = True
- import ctypes
- from ctypes import *
- _libblender = ctypes.CDLL('lib/libblender.so')
- # undefined symbol: _ZN10KX_RayCast9reportHitEP17PHY_RayCastResult
- # if you get the error above you need to compile libblender with out the game engine
- print 'ctypes can load libblender', _libblender
- # Helper function for declaring function prototypes
- def cfunc(name, result, *args):
- """Build and apply a ctypes prototype complete with parameter flags"""
- atypes = []
- aflags = []
- for arg in args:
- atypes.append(arg[1])
- aflags.append((arg[2], arg[0]) + arg[3:])
- return CFUNCTYPE(result, *atypes)((name, _libblender), tuple(aflags))
- def test_ctypes():
- main = cfunc('main', c_int, ('argc', c_int, 1), ('argv', POINTER(c_char_p), 1) )
- argv = (c_char_p * len(sys.argv))()
- for i, arg in enumerate( sys.argv ): argv[ i ] = arg
- argv[0] = 'blender'
- argc = c_int( len(sys.argv) )
- #main( ctypes.byref(argc), argv )
- main( argc, argv ) # this segfaults, why?
- # need help!!! #
- test_ctypes() # segfaults, most likely WM_init, why?
- ####### RPython below ##########
- sys.exit() # comment if you want to try building with RPython and rffi
- from pypy.rpython.lltypesystem import lltype, rffi
- from pypy.rpython.tool import rffi_platform as platform
- from pypy.translator.tool.cbuild import ExternalCompilationInfo
- from pypy.rpython.annlowlevel import llhelper # thanks Forgeot d'Arc
- _problem_headers_ = 'smoke_API.h MEM_RefCountPtr.h MEM_NonCopyable.h MEM_RefCounted.h MEM_SmartPtr.h MEM_Allocator.h MEM_CacheLimiter.h BSP_MeshPrimitives.h BSP_CSGMesh.h BOP_Interface.h CTR_TaggedIndex.h BSP_CSGMesh.h STR_String.h GHOST_Rect.h GHOST_IWindow.h GHOST_ITimerTask.h GHOST_ISystem.h GHOST_IEvent.h GHOST_IEventConsumer.h STR_HashedString.h CTR_Map.h CTR_TaggedSetOps.h CTR_List.h CTR_UHeap.h'.split()
- _problem_headers_ += 'BLI_vfontdata.h BLI_editVert.h BLI_bpath.h BLI_graph.h BLI_ghash.h BLI_blenlib.h BLI_listbase.h RNA_define.h RNA_access.h'.split()
- _rpy_conflicts_ = 'mmap_win.h'.split()
- _problem_headers_ += _rpy_conflicts_
- def find_blender_headers():
- headers = []
- paths = []
- internal = os.path.join( BLENDER_SOURCE, 'intern' ) # would be nice to have a blender.h at this level that included everything
- for name in os.listdir( internal ):
- #if name == 'guardedalloc': continue # conflicts with RPython memory allocations - not useful anyways?
- print name
- a = os.path.join( internal, name )
- if os.path.isdir( a ): # audaspace, boolop, bsp, container, decimation, elbeem, ghost, guardedalloc, iksolver, itasc, make, memutil, moto, etc...
- for name in os.listdir( a ):
- b = os.path.join( a,name )
- # there can be headers at this level, container for example: CTR_Map.h
- if os.path.isfile( b ) and b.endswith('.h') and name not in _problem_headers_:
- headers.append( b )
- if a not in paths: paths.append( a )
- elif os.path.isdir( b ) and name == 'extern': # only wrap externals?
- for name in os.listdir( b ):
- c = os.path.join( b, name )
- if os.path.isfile( c ) and c.endswith('.h') and name not in _problem_headers_:
- headers.append( c )
- if b not in paths: paths.append( b )
- h = []; p = []
- for a in headers: print a; h.append( os.path.abspath(a) )
- for a in paths: p.append( os.path.abspath(a) )
- return h, p
- headers, paths = find_blender_headers()
- #for name in 'blenlib makesrna render imbuf blenkernel'.split():
- for name in 'blenlib makesrna render imbuf'.split():
- a = os.path.join( BLENDER_SOURCE, 'source' )
- b = os.path.join( a, 'blender' )
- c = os.path.join( b, name )
- paths.append( os.path.abspath(c) )
- for f in os.listdir( c ):
- if f.endswith( '.h' ) and f not in _problem_headers_: headers.append( f ); print f
- ugly_hacks = '''
- struct bContext;
- typedef struct bContext bContext;
- '''
- eci = ExternalCompilationInfo(
- includes = headers,
- include_dirs = paths,
- #link_files = [ os.path.abspath('lib/libblender.so') ],
- link_files = [ '/usr/lib/libblender.so' ], # required
- separate_module_sources=[ugly_hacks] # can inject C code here
- )
- platform.verify_eci(eci)
- _rffi_ctypes_mapping = {
- rffi.INT : ctypes.c_int,
- rffi.UINT : ctypes.c_uint,
- }
- def external(name, args=[], result=lltype.Void): # if function takes void then args=[], not args=[lltype.Void]
- if USE_CTYPES:
- if result in _rffi_ctypes_mapping: result = _rffi_ctypes_mapping[ result ]
- else: result = ctypes.c_void_p
- a = []
- for arg in args:
- if arg in _rffi_ctypes_mapping: a.append( _rffi_ctypes_mapping[ arg ] )
- else: a.append( ctypes.c_void_p )
- proto = ctypes.CFUNCTYPE( result, *tuple(a) )
- func = proto( (name, _libblender) )
- return func
- else: # RPython - rffi
- return rffi.llexternal(name, args, result, compilation_info=eci)
- #charpp = rffi.CArrayPtr( rffi.CCHARP )
- # blender/source/blender/blenkernel/BKE_context.h
- bContext = rffi.CStructPtr('bContext')
- CTX_create = external( 'CTX_create', result=bContext)
- #CTX_free = external( 'CTX_free', [bContext], lltype.Void)
- #CTX_copy = external( 'CTX_copy', [bContext], bContext_ptr)
- # blender/source/blender/blenlib/BLI_threads.h
- BLI_threadapi_init = external('BLI_threadapi_init')
- # blender/source/blender/makesrns/RNA_types.h
- BlenderRNA_ptr = rffi.CStructPtr('BlenderRNA')
- ParameterList_ptr = rffi.CStructPtr('ParameterList')
- FunctionRNA_ptr = rffi.CStructPtr('FunctionRNA')
- PropertyRNA_ptr = rffi.CStructPtr('PropertyRNA')
- StructRNA_ptr = rffi.CStructPtr('StructRNA')
- IDProperty_ptr = rffi.CStructPtr('IDProperty')
- IDProperty_ptr = rffi.CStructPtr('IDProperty')
- ReportList_ptr = rffi.CStructPtr('ReportList')
- # blender/source/blender/makesrns/RNA_define.h
- RNA_init = external('RNA_init' )
- RNA_create = external('RNA_create', result=BlenderRNA_ptr )
- RNA_free = external('RNA_free', [ BlenderRNA_ptr ] )
- # blender/source/blender/render/RE_pipeline.h
- RE_engines_init = external('RE_engines_init' )
- # blender/source/blender/imbuf/IMB_imbuf.h
- IMB_init = external('IMB_init' )
- # blender/source/kernel/gen_system/SYS_System.h
- '''
- System specific information / access.
- For now, only used for commandline parameters.
- One of the available implementations must be linked to the application
- that uses this system routines.
- Please note that this protocol/interface is just for testing,
- it needs discussion in the development group for a more final version.
- '''
- #SYS_GetSystem = external('SYS_GetSystem' )
- # blender/source/kernel/gen_messaging/GEN_messaging.h
- GEN_init_messaging_system = external('GEN_init_messaging_system' )
- # blender/source/blender/blenlib/BLI_args.h
- bArgs = rffi.CStructPtr('bArgs')
- #struct bArgs *BLI_argsInit(int argc, char **argv);
- BLI_argsInit = external('BLI_argsInit', [rffi.INT, rffi.CCHARPP ], bArgs )
- #void BLI_argsParse(struct bArgs *ba, int pass, BA_ArgCallback default_cb, void *data);
- BLI_argsParse = external('BLI_argsParse', [ bArgs, rffi.INT, rffi.VOIDP, rffi.VOIDP ] )
- # blender/source/blender/windowmanager/WM_api.h
- '''
- void WM_setprefsize (int stax, int stay, int sizx, int sizy);
- void WM_setinitialstate_fullscreen();
- void WM_setinitialstate_normal();
- void WM_init (struct bContext *C, int argc, char **argv);
- void WM_exit (struct bContext *C);
- void WM_main (struct bContext *C);
- int WM_init_game (struct bContext *C);
- void WM_init_splash (struct bContext *C);
- void WM_check (struct bContext *C);
- '''
- WM_init = external('WM_init', [ bContext, rffi.INT, rffi.CCHARPP ] )
- WM_main = external('WM_main', [ bContext ] )
- def mainx( argc, argv ):
- C = CTX_create() # bContext pointer
- #try: # binreloc is not important?
- # br_init = cfunc('br_init', c_void_p, ('BrInitError', c_void_p,1) )
- # br_init()
- #except: print 'built without bin-reloc'
- ## setCallbacks not defined header, not important?
- ## only for: MEM_set_error_callback(mem_error_cb); BLI_setErrorCallBack(error_cb)
- #setCallbacks = cfunc('setCallbacks', c_void_p )
- #setCallbacks()
- BLI_threadapi_init()
- RNA_init()
- RE_engines_init()
- IMB_init()
- #syshandle = SYS_GetSystem() # not final, only for parsing some command lines
- GEN_init_messaging_system()
- ba = BLI_argsInit( argc, argv )
- voidp = lltype.nullptr(rffi.VOIDP.TO)
- BLI_argsParse(ba, 1, voidp, voidp )
- WM_init( C, argc, argv ) # seg faults
- #BLI_argsInit = cfunc('BLI_argsInit', c_void_p, ('argc', c_int, 1), ('argv', c_char_p, 1) )
- print 'main exit'
- def entrypoint( args ):
- print args
- #argv = []
- #for arg in args.split(' '): argv.append( arg )
- #argc = len(argv)
- argv = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
- argc = 1
- mainx( argc, argv )
- return 0
- if __name__ == '__main__' and 0:
- from pypy.translator.interactive import Translation
- t = Translation( test )
- t.annotate([str]); t.rtype()
- entrypoint = t.compile_c()
- entrypoint(1)
- def jitpolicy(driver):
- from pypy.module.pypyjit.policy import PyPyJitPolicy
- return PyPyJitPolicy()
- #pypy-trunk/pypy/translator/goal/translate.py <thisfile.py>
- def target(*args):
- return entrypoint, None
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement