Guest User

pypy on android test1

a guest
Jan 14th, 2011
615
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.79 KB | None | 0 0
  1. #!/usr/bin/python
  2. '''
  3. Possible Solution ?
  4.   recompile gcc 4.4.3 for 64bit and copy to android-ndk-r5/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
  5.  
  6. /home/brett/android-ndk-r5/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -MMD -MP -MF /tmp/usession-default-6/obj/local/armeabi/objs/testing_1/testing_1.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__  -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -I/tmp/usession-default-6/jni -DANDROID -I/home/brett/RPythonic/pypy/pypy/translator/c -DPYPY_STANDALONE -Wa,--noexecstack -O2 -DNDEBUG -g -I/home/brett/android-ndk-r5/platforms/android-3/arch-arm/usr/include -c  /tmp/usession-default-6/jni/testing_1.c -o /tmp/usession-default-6/obj/local/armeabi/objs/testing_1/testing_1.o
  7. In file included from /home/brett/RPythonic/pypy/pypy/translator/c/src/g_prerequisite.h:7,
  8.                 from /tmp/usession-default-6/jni/common_header.h:44,
  9.                 from /tmp/usession-default-6/jni/testing_1.c:1:
  10. /home/brett/RPythonic/pypy/pypy/translator/c/src/commondefs.h:58:6: error: #error "error in LONG_MAX (64-bit sources but a 32-bit compiler?)"
  11. /home/brett/RPythonic/pypy/pypy/translator/c/src/commondefs.h:61:6: error: #error "unsupported value for LONG_MIN"
  12. /tmp/usession-default-6/jni/testing_1.c:85: error: expected specifier-qualifier-list before 'PyObject'
  13. /tmp/usession-default-6/jni/testing_1.c:404: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
  14. /tmp/usession-default-6/jni/testing_1.c:409: error: expected ')' before '*' token
  15. In file included from /home/brett/RPythonic/pypy/pypy/translator/c/src/g_include.h:58,
  16.                 from /tmp/usession-default-6/jni/testing_1.c:564:
  17.  
  18. '''
  19. print('rpython translator compiler for android')
  20. import os, sys
  21.  
  22. ## requires Android NDK
  23. NDK_PLATFORM_VERSION = 'android-9'  # change this to match your NDK version
  24. NDK_ROOT = '../android-ndk-r5/' # change this to point to your NDK installation
  25. assert os.path.isdir( NDK_ROOT )
  26. NDK_ROOT = os.path.abspath( NDK_ROOT )
  27. NDK_PLATFORM = os.path.join( NDK_ROOT, 'platforms/%s/arch-arm/' %NDK_PLATFORM_VERSION )
  28. assert os.path.isdir( NDK_PLATFORM )
  29.  
  30. NDK_LIBS = os.path.join( NDK_PLATFORM, 'usr/lib/' )
  31. assert os.path.isdir( NDK_LIBS )
  32.  
  33. ## requires pypy
  34. PYPY_ROOT = 'pypy/'
  35. if PYPY_ROOT not in sys.path: sys.path.append(PYPY_ROOT)
  36. assert os.path.isdir( PYPY_ROOT )
  37. PYPY_ROOT = os.path.abspath( PYPY_ROOT )
  38. PYPY_INCLUDE = os.path.join( PYPY_ROOT, 'pypy/translator/c' )
  39.  
  40. import pypy.translator.interactive
  41. import pypy.translator.platform.linux
  42. from pypy.tool.udir import udir
  43. from pypy.translator.tool.cbuild import ExternalCompilationInfo
  44. from pypy.tool.runsubprocess import run_subprocess as _run_subprocess
  45.  
  46. class Android(pypy.translator.platform.linux.BaseLinux):
  47.     name = "android"
  48.  
  49.     def __init__(self):
  50.         self.cc = NDK_GCC = os.path.join( NDK_ROOT, 'toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc' )
  51.         assert os.path.isfile( NDK_GCC )
  52.         NDK_GPP = os.path.join( NDK_ROOT, 'toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-g++' )
  53.         assert os.path.isfile( NDK_GPP )
  54.         NDK_AR = os.path.join( NDK_ROOT, 'toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ar' )
  55.         assert os.path.isfile( NDK_AR )
  56.         NDK_STRIP = os.path.join( NDK_ROOT, 'toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-strip' )
  57.         assert os.path.isfile( NDK_STRIP )
  58.  
  59.     @staticmethod
  60.     def android_eci(
  61.         pre_include_bits        = [],
  62.         includes                = [],
  63.         include_dirs            = [],
  64.         post_include_bits       = [],
  65.         libraries               = [],
  66.         library_dirs            = [],
  67.         separate_module_sources = [],
  68.         separate_module_files   = [],
  69.         export_symbols          = [],
  70.         compile_extra           = [],
  71.         link_extra              = [],
  72.         frameworks              = [],
  73.         link_files              = [],
  74.         testonly_libraries      = [],
  75.         use_cpp_linker          = False,
  76.         platform                = None ):
  77.         """
  78.         pre_include_bits: list of pieces of text that should be put at the top
  79.         of the generated .c files, before any #include.  They shouldn't
  80.         contain an #include themselves.  (Duplicate pieces are removed.)
  81.  
  82.         includes: list of .h file names to be #include'd from the
  83.         generated .c files.
  84.  
  85.         include_dirs: list of dir names that is passed to the C compiler
  86.  
  87.         post_include_bits: list of pieces of text that should be put at the top
  88.         of the generated .c files, after the #includes.  (Duplicate pieces are
  89.         removed.)
  90.  
  91.         libraries: list of library names that is passed to the linker
  92.  
  93.         library_dirs: list of dir names that is passed to the linker
  94.  
  95.         separate_module_sources: list of multiline strings that are
  96.         each written to a .c file and compiled separately and linked
  97.         later on.  (If function prototypes are needed for other .c files
  98.         to access this, they can be put in post_include_bits.)
  99.  
  100.         separate_module_files: list of .c file names that are compiled
  101.         separately and linked later on.  (If an .h file is needed for
  102.         other .c files to access this, it can be put in includes.)
  103.  
  104.         export_symbols: list of names that should be exported by the final
  105.         binary.
  106.  
  107.         compile_extra: list of parameters which will be directly passed to
  108.         the compiler
  109.  
  110.         link_extra: list of parameters which will be directly passed to
  111.         the linker
  112.  
  113.         frameworks: list of Mac OS X frameworks which should passed to the
  114.         linker. Use this instead of the 'libraries' parameter if you want to
  115.         link to a framework bundle. Not suitable for unix-like .dylib
  116.         installations.
  117.  
  118.         link_files: list of file names which will be directly passed to the
  119.         linker
  120.  
  121.         testonly_libraries: list of libraries that are searched for during
  122.         testing only, by ll2ctypes.  Useful to search for a name in a dynamic
  123.         library during testing but use the static library for compilation.
  124.  
  125.         use_cpp_linker: a flag to tell if g++ should be used instead of gcc
  126.         when linking (a bit custom so far)
  127.  
  128.         platform: an object that can identify the platform
  129.         """
  130.         #include_dirs.insert( 0, PYPY_INCLUDE )
  131.         include_dirs.insert( 0, os.path.join(NDK_PLATFORM,'usr/include/') )
  132.         library_dirs.append( NDK_LIBS )
  133.         #link_files.append( os.path.join(NDK_LIBS, 'crtbegin_dynamic.o') )
  134.         for o in os.listdir( NDK_LIBS ):
  135.             if o.endswith('.o'):
  136.                 link_files.append( os.path.join(NDK_LIBS,o) ); print('linking->', o)
  137.                 libraries.append( os.path.join(NDK_LIBS,o) )
  138.         os.environ['LD_LIBRARY_PATH'] = NDK_LIBS
  139.  
  140.         eci = ExternalCompilationInfo(
  141.             include_dirs = include_dirs,
  142.             link_files = link_files,
  143.             libraries = libraries,
  144.             library_dirs = library_dirs,
  145.             platform=platform,
  146.         )
  147.         return eci
  148.     #def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False):
  149.     #   eci.include_dirs = list( eci.include_dirs )
  150.     #   eci.include_dirs.append( '%s/usr/include' %NDK_BASE )
  151.     #   m = pypy.translator.platform.linux.BaseLinux.gen_makefile( self, cfiles, eci, exe_name=exe_name, path=path, shared=shared )
  152.     #   return m
  153.  
  154.     def _execute_c_compiler(self, cc, args, outname, cwd=None): # TODO fix: crtbegin_dynamic.o: No such file, error by ld
  155.         print('android compiler: %s' %outname)
  156.         for a in args: print('\t.%s' %a)
  157.         #for a in os.environ: print( a, os.environ[a] )
  158.         # 'cc' can also contain some options for the C compiler;
  159.         # e.g. it can be "gcc -m32".  We handle it by splitting on ' '.
  160.         cclist = cc.split()
  161.         cc = cclist[0]
  162.         args = cclist[1:] + args
  163.         returncode, stdout, stderr = _run_subprocess(self.cc, args, self.c_environ, cwd)
  164.         self._handle_error(returncode, stderr, stdout, outname)
  165.  
  166.     def gen_android_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False):
  167.         mk = path.join( 'Android.mk' )
  168.         #g = 'LOCAL_PATH := %s \n' %path.strpath
  169.         g = 'LOCAL_PATH := $(call my-dir)\n'    # note no whitespace after $(call my-dir) ## make: *** No rule to make target
  170.         g += 'include $(CLEAR_VARS) \n'
  171.         g += 'LOCAL_CFLAGS := -I%s -DPYPY_STANDALONE\n' %PYPY_INCLUDE
  172.         for c in cfiles:
  173.             g += 'LOCAL_MODULE := %s \n' %c.purebasename
  174.             g += 'LOCAL_SRC_FILES := %s \n' %c.basename
  175.         g += 'include $(BUILD_SHARED_LIBRARY) \n'
  176.         mk.write( g )
  177.         print('-'*80); print( g ); print('_'*80)
  178.         return mk
  179.  
  180. platform = AndroidPlatform = Android()
  181.  
  182.  
  183. #####################
  184.  
  185. def xx():
  186.     jnidir = udir.join('jni').ensure(dir=1)
  187.     #os.environ['NDK_PROJECT_PATH'] = tmpdir.strpath
  188.  
  189.     cfile = jnidir.join('simple.c')
  190.     cfile.write('''
  191.     #include <stdio.h>
  192.     int main()
  193.     {
  194.         printf("42\\n");
  195.         return 0;
  196.     }
  197.     ''')
  198.  
  199.  
  200.     #mk = AndroidPlatform.gen_makefile([cfile], eci, path=tmpdir)
  201.     #mk.write()
  202.     #AndroidPlatform.execute_makefile(mk)
  203.     #res = AndroidPlatform.execute(tmpdir.join('test_simple_enough'))
  204.     #assert res.out == '42\n'
  205.     #exe =platform.compile([cfile], eci)
  206.     #print(exe)
  207.     print('android test complete')
  208.  
  209.  
  210.  
  211. from pypy.translator.interactive import Translation
  212. import inspect
  213.  
  214. def translate_c( func ):
  215.     spec = inspect.getargspec( func )
  216.     t = Translation( func ); print('-'*80); print('#### PYPY FLOWGRAPH STEP1 COMPLETE ####'); print('-'*80)
  217.     t.annotate(); print('-'*80); print('#### PYPY ANNONTATION STEP2 COMPLETE ####'); print('-'*80)
  218.     args = []
  219.     if spec.defaults:
  220.         for k in spec.defaults: args.append( type(k) )  # TODO fixme
  221.     t.rtype( args ); print('-'*80); print('#### PYPY RTYPER STEP3 COMPLETE ####'); print('-'*80)
  222.     t.source_c(); print('-'*80); print('#### PYPY SOURCE GENERATION STEP4 COMPLETE ####'); print('-'*80)
  223.     headers = []
  224.     sources = []
  225.     ## copy generated source to our jni directory ##
  226.     for f in t.driver.cbuilder.targetdir.listdir():     # after source_c is called this is available
  227.         if f.ext == '.h': headers.append( f )
  228.         elif f.ext == '.c': sources.append( f )
  229.     return headers, sources
  230.  
  231.  
  232. MANIFEST = '''
  233. <?xml version="1.0" encoding="utf-8"?>
  234. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  235.      package="com.example.hellojni"
  236.      android:versionCode="1"
  237.      android:versionName="1.0">
  238.    <uses-sdk android:minSdkVersion="3" />
  239.    <application android:label="@string/app_name"
  240.                 android:debuggable="true">
  241.        <activity android:name=".HelloJni"
  242.                  android:label="@string/app_name">
  243.            <intent-filter>
  244.                <action android:name="android.intent.action.MAIN" />
  245.                <category android:name="android.intent.category.LAUNCHER" />
  246.            </intent-filter>
  247.        </activity>
  248.    </application>
  249. </manifest>
  250. '''
  251.  
  252. _C_TEST1 = '''
  253. #include <stdio.h>
  254. int main()
  255. {
  256.    printf("42\\n");
  257.    return 0;
  258. }
  259. '''
  260.  
  261. def new_android_project( headers=[], sources=[] ):
  262.     print('-'*80); print('#### CREATING NEW ANDROID PROJECT ####'); print('-'*80)
  263.     ## android NDK expects a 'jni' folder under project directory ##
  264.     jnidir = udir.join('jni').ensure(dir=1)
  265.     projectdir = os.path.split( jnidir.strpath )[0]
  266.     #mani = open( os.path.join( projectdir, 'AndroidManifest.xml' ), 'wb' )
  267.     #mani.write( MANIFEST ); mani.close()
  268.  
  269.     for f in headers + sources: f.copy( jnidir )
  270.     if not headers and not sources: # run test
  271.         cfile = jnidir.join('simple.c')
  272.         cfile.write(_C_TEST1)
  273.         sources.append( cfile )
  274.  
  275.     eci = Android.android_eci()
  276.     mk = platform.gen_android_makefile(sources, eci, path=jnidir)
  277.  
  278.     ndkbuild = os.path.join(NDK_ROOT,'ndk-build')
  279.     assert os.path.isfile( ndkbuild )
  280.     print('-'*80); print('#### %s ####'%ndkbuild); print('-'*80)
  281.     os.system( 'cd %s; %s -B V=1' %(projectdir, ndkbuild))
  282.     print('-'*80)
  283.  
  284.     return projectdir
  285.  
  286.  
  287. if __name__ == '__main__':
  288.     # change to import pass target
  289.     #def test( argc=0, argv='' ): print('helloworld')
  290.     def test(): print( 'helloworld' )
  291.     headers,sources = translate_c( test )
  292.     new_android_project(headers, sources)
Advertisement
Add Comment
Please, Sign In to add comment