Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- '''
- Possible Solution ?
- recompile gcc 4.4.3 for 64bit and copy to android-ndk-r5/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
- /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
- In file included from /home/brett/RPythonic/pypy/pypy/translator/c/src/g_prerequisite.h:7,
- from /tmp/usession-default-6/jni/common_header.h:44,
- from /tmp/usession-default-6/jni/testing_1.c:1:
- /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?)"
- /home/brett/RPythonic/pypy/pypy/translator/c/src/commondefs.h:61:6: error: #error "unsupported value for LONG_MIN"
- /tmp/usession-default-6/jni/testing_1.c:85: error: expected specifier-qualifier-list before 'PyObject'
- /tmp/usession-default-6/jni/testing_1.c:404: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
- /tmp/usession-default-6/jni/testing_1.c:409: error: expected ')' before '*' token
- In file included from /home/brett/RPythonic/pypy/pypy/translator/c/src/g_include.h:58,
- from /tmp/usession-default-6/jni/testing_1.c:564:
- '''
- print('rpython translator compiler for android')
- import os, sys
- ## requires Android NDK
- NDK_PLATFORM_VERSION = 'android-9' # change this to match your NDK version
- NDK_ROOT = '../android-ndk-r5/' # change this to point to your NDK installation
- assert os.path.isdir( NDK_ROOT )
- NDK_ROOT = os.path.abspath( NDK_ROOT )
- NDK_PLATFORM = os.path.join( NDK_ROOT, 'platforms/%s/arch-arm/' %NDK_PLATFORM_VERSION )
- assert os.path.isdir( NDK_PLATFORM )
- NDK_LIBS = os.path.join( NDK_PLATFORM, 'usr/lib/' )
- assert os.path.isdir( NDK_LIBS )
- ## requires pypy
- PYPY_ROOT = 'pypy/'
- if PYPY_ROOT not in sys.path: sys.path.append(PYPY_ROOT)
- assert os.path.isdir( PYPY_ROOT )
- PYPY_ROOT = os.path.abspath( PYPY_ROOT )
- PYPY_INCLUDE = os.path.join( PYPY_ROOT, 'pypy/translator/c' )
- import pypy.translator.interactive
- import pypy.translator.platform.linux
- from pypy.tool.udir import udir
- from pypy.translator.tool.cbuild import ExternalCompilationInfo
- from pypy.tool.runsubprocess import run_subprocess as _run_subprocess
- class Android(pypy.translator.platform.linux.BaseLinux):
- name = "android"
- def __init__(self):
- self.cc = NDK_GCC = os.path.join( NDK_ROOT, 'toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc' )
- assert os.path.isfile( NDK_GCC )
- NDK_GPP = os.path.join( NDK_ROOT, 'toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-g++' )
- assert os.path.isfile( NDK_GPP )
- NDK_AR = os.path.join( NDK_ROOT, 'toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ar' )
- assert os.path.isfile( NDK_AR )
- NDK_STRIP = os.path.join( NDK_ROOT, 'toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-strip' )
- assert os.path.isfile( NDK_STRIP )
- @staticmethod
- def android_eci(
- pre_include_bits = [],
- includes = [],
- include_dirs = [],
- post_include_bits = [],
- libraries = [],
- library_dirs = [],
- separate_module_sources = [],
- separate_module_files = [],
- export_symbols = [],
- compile_extra = [],
- link_extra = [],
- frameworks = [],
- link_files = [],
- testonly_libraries = [],
- use_cpp_linker = False,
- platform = None ):
- """
- pre_include_bits: list of pieces of text that should be put at the top
- of the generated .c files, before any #include. They shouldn't
- contain an #include themselves. (Duplicate pieces are removed.)
- includes: list of .h file names to be #include'd from the
- generated .c files.
- include_dirs: list of dir names that is passed to the C compiler
- post_include_bits: list of pieces of text that should be put at the top
- of the generated .c files, after the #includes. (Duplicate pieces are
- removed.)
- libraries: list of library names that is passed to the linker
- library_dirs: list of dir names that is passed to the linker
- separate_module_sources: list of multiline strings that are
- each written to a .c file and compiled separately and linked
- later on. (If function prototypes are needed for other .c files
- to access this, they can be put in post_include_bits.)
- separate_module_files: list of .c file names that are compiled
- separately and linked later on. (If an .h file is needed for
- other .c files to access this, it can be put in includes.)
- export_symbols: list of names that should be exported by the final
- binary.
- compile_extra: list of parameters which will be directly passed to
- the compiler
- link_extra: list of parameters which will be directly passed to
- the linker
- frameworks: list of Mac OS X frameworks which should passed to the
- linker. Use this instead of the 'libraries' parameter if you want to
- link to a framework bundle. Not suitable for unix-like .dylib
- installations.
- link_files: list of file names which will be directly passed to the
- linker
- testonly_libraries: list of libraries that are searched for during
- testing only, by ll2ctypes. Useful to search for a name in a dynamic
- library during testing but use the static library for compilation.
- use_cpp_linker: a flag to tell if g++ should be used instead of gcc
- when linking (a bit custom so far)
- platform: an object that can identify the platform
- """
- #include_dirs.insert( 0, PYPY_INCLUDE )
- include_dirs.insert( 0, os.path.join(NDK_PLATFORM,'usr/include/') )
- library_dirs.append( NDK_LIBS )
- #link_files.append( os.path.join(NDK_LIBS, 'crtbegin_dynamic.o') )
- for o in os.listdir( NDK_LIBS ):
- if o.endswith('.o'):
- link_files.append( os.path.join(NDK_LIBS,o) ); print('linking->', o)
- libraries.append( os.path.join(NDK_LIBS,o) )
- os.environ['LD_LIBRARY_PATH'] = NDK_LIBS
- eci = ExternalCompilationInfo(
- include_dirs = include_dirs,
- link_files = link_files,
- libraries = libraries,
- library_dirs = library_dirs,
- platform=platform,
- )
- return eci
- #def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False):
- # eci.include_dirs = list( eci.include_dirs )
- # eci.include_dirs.append( '%s/usr/include' %NDK_BASE )
- # m = pypy.translator.platform.linux.BaseLinux.gen_makefile( self, cfiles, eci, exe_name=exe_name, path=path, shared=shared )
- # return m
- def _execute_c_compiler(self, cc, args, outname, cwd=None): # TODO fix: crtbegin_dynamic.o: No such file, error by ld
- print('android compiler: %s' %outname)
- for a in args: print('\t.%s' %a)
- #for a in os.environ: print( a, os.environ[a] )
- # 'cc' can also contain some options for the C compiler;
- # e.g. it can be "gcc -m32". We handle it by splitting on ' '.
- cclist = cc.split()
- cc = cclist[0]
- args = cclist[1:] + args
- returncode, stdout, stderr = _run_subprocess(self.cc, args, self.c_environ, cwd)
- self._handle_error(returncode, stderr, stdout, outname)
- def gen_android_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False):
- mk = path.join( 'Android.mk' )
- #g = 'LOCAL_PATH := %s \n' %path.strpath
- g = 'LOCAL_PATH := $(call my-dir)\n' # note no whitespace after $(call my-dir) ## make: *** No rule to make target
- g += 'include $(CLEAR_VARS) \n'
- g += 'LOCAL_CFLAGS := -I%s -DPYPY_STANDALONE\n' %PYPY_INCLUDE
- for c in cfiles:
- g += 'LOCAL_MODULE := %s \n' %c.purebasename
- g += 'LOCAL_SRC_FILES := %s \n' %c.basename
- g += 'include $(BUILD_SHARED_LIBRARY) \n'
- mk.write( g )
- print('-'*80); print( g ); print('_'*80)
- return mk
- platform = AndroidPlatform = Android()
- #####################
- def xx():
- jnidir = udir.join('jni').ensure(dir=1)
- #os.environ['NDK_PROJECT_PATH'] = tmpdir.strpath
- cfile = jnidir.join('simple.c')
- cfile.write('''
- #include <stdio.h>
- int main()
- {
- printf("42\\n");
- return 0;
- }
- ''')
- #mk = AndroidPlatform.gen_makefile([cfile], eci, path=tmpdir)
- #mk.write()
- #AndroidPlatform.execute_makefile(mk)
- #res = AndroidPlatform.execute(tmpdir.join('test_simple_enough'))
- #assert res.out == '42\n'
- #exe =platform.compile([cfile], eci)
- #print(exe)
- print('android test complete')
- from pypy.translator.interactive import Translation
- import inspect
- def translate_c( func ):
- spec = inspect.getargspec( func )
- t = Translation( func ); print('-'*80); print('#### PYPY FLOWGRAPH STEP1 COMPLETE ####'); print('-'*80)
- t.annotate(); print('-'*80); print('#### PYPY ANNONTATION STEP2 COMPLETE ####'); print('-'*80)
- args = []
- if spec.defaults:
- for k in spec.defaults: args.append( type(k) ) # TODO fixme
- t.rtype( args ); print('-'*80); print('#### PYPY RTYPER STEP3 COMPLETE ####'); print('-'*80)
- t.source_c(); print('-'*80); print('#### PYPY SOURCE GENERATION STEP4 COMPLETE ####'); print('-'*80)
- headers = []
- sources = []
- ## copy generated source to our jni directory ##
- for f in t.driver.cbuilder.targetdir.listdir(): # after source_c is called this is available
- if f.ext == '.h': headers.append( f )
- elif f.ext == '.c': sources.append( f )
- return headers, sources
- MANIFEST = '''
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.hellojni"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="3" />
- <application android:label="@string/app_name"
- android:debuggable="true">
- <activity android:name=".HelloJni"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- </manifest>
- '''
- _C_TEST1 = '''
- #include <stdio.h>
- int main()
- {
- printf("42\\n");
- return 0;
- }
- '''
- def new_android_project( headers=[], sources=[] ):
- print('-'*80); print('#### CREATING NEW ANDROID PROJECT ####'); print('-'*80)
- ## android NDK expects a 'jni' folder under project directory ##
- jnidir = udir.join('jni').ensure(dir=1)
- projectdir = os.path.split( jnidir.strpath )[0]
- #mani = open( os.path.join( projectdir, 'AndroidManifest.xml' ), 'wb' )
- #mani.write( MANIFEST ); mani.close()
- for f in headers + sources: f.copy( jnidir )
- if not headers and not sources: # run test
- cfile = jnidir.join('simple.c')
- cfile.write(_C_TEST1)
- sources.append( cfile )
- eci = Android.android_eci()
- mk = platform.gen_android_makefile(sources, eci, path=jnidir)
- ndkbuild = os.path.join(NDK_ROOT,'ndk-build')
- assert os.path.isfile( ndkbuild )
- print('-'*80); print('#### %s ####'%ndkbuild); print('-'*80)
- os.system( 'cd %s; %s -B V=1' %(projectdir, ndkbuild))
- print('-'*80)
- return projectdir
- if __name__ == '__main__':
- # change to import pass target
- #def test( argc=0, argv='' ): print('helloworld')
- def test(): print( 'helloworld' )
- headers,sources = translate_c( test )
- new_android_project(headers, sources)
Advertisement
Add Comment
Please, Sign In to add comment