Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can .so files be run using Chaquopy? #302

Closed
sayan-sen opened this issue Jun 1, 2020 · 8 comments
Closed

Can .so files be run using Chaquopy? #302

sayan-sen opened this issue Jun 1, 2020 · 8 comments

Comments

@sayan-sen
Copy link

sayan-sen commented Jun 1, 2020

i am trying to call a .so file but it fails.

MainActivity.java:

Python py = Python.getInstance();
PyObject pyf = py.getModule("temp");

temp.py:

from test1 import showimg
showimg(1,2)

I am trying to call test1.so file instead of test1.py but it fails:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.styleapp, PID: 8801
    com.chaquo.python.PyException: ELFError: Magic number does not match
        at <python>.java._vendor.elftools.common.utils._assert_with_exception(utils.py:101)
        at <python>.java._vendor.elftools.common.utils.elf_assert(utils.py:69)
        at <python>.java._vendor.elftools.elf.elffile._identify_file(elffile.py:229)
        at <python>.java._vendor.elftools.elf.elffile.__init__(elffile.py:61)
        at <python>.java.chaquopy.import_override(import.pxi:26)
        at <python>.temp.<module>(temp.py:1)
        at <python>.importlib._bootstrap._call_with_frames_removed(<frozen importlib._bootstrap>:219)
        at <python>.importlib._bootstrap_external.exec_module(<frozen importlib._bootstrap_external>:783)
        at <python>.java.android.importer.exec_module(importer.py:503)
        at <python>.java.android.importer.exec_module(importer.py:546)
        at <python>.importlib._bootstrap._load_unlocked(<frozen importlib._bootstrap>:671)
        at <python>.importlib._bootstrap._find_and_load_unlocked(<frozen importlib._bootstrap>:975)
        at <python>.importlib._bootstrap._find_and_load(<frozen importlib._bootstrap>:991)
        at <python>.importlib._bootstrap._gcd_import(<frozen importlib._bootstrap>:1014)
        at <python>.importlib.import_module(__init__.py:127)
        at <python>.chaquopy_java.Java_com_chaquo_python_Python_getModule(chaquopy_java.pyx:152)
        at com.chaquo.python.Python.getModule(Native Method)
        at com.example.styleapp.MainActivity.runthemodel(MainActivity.java:126)
        at com.example.styleapp.MainActivity.access$000(MainActivity.java:45)
        at com.example.styleapp.MainActivity$2.onMenuItemClick(MainActivity.java:102)
        at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:154)
        at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:991)
        at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:981)
        at androidx.appcompat.widget.ActionMenuView.invokeItem(ActionMenuView.java:625)
        at androidx.appcompat.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:151)
        at android.view.View.performClick(View.java:7140)
        at android.view.View.performClickInternal(View.java:7117)
        at android.view.View.access$3500(View.java:801)
        at android.view.View$PerformClick.run(View.java:27355)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7410)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)

But if i call test1.py, it runs succesfully. Here is my test1.py:

def showimg(i,j):
    print(i+j)

Why does it fail? Previously i have been told that Chaquopy doesnt import-and-run .pyc files. Does it not support .so files?

@mhsmith
Copy link
Member

mhsmith commented Jun 1, 2020

You can load .so files if they're built for Android (not Linux or Mac). However, if you're receiving that error then it probably isn't a valid .so file at all. Where did it come from?

@sayan-sen
Copy link
Author

sayan-sen commented Jun 1, 2020

i built it using cython:

from setuptools import setup
from Cython.Build import cythonize

setup(
    ext_modules=cythonize('test1.py')
)

I tested the .so file in my mac, it works fine.
If it has to be built for android then how to build .so file for android? you have any suggestions?

@mhsmith
Copy link
Member

mhsmith commented Jun 1, 2020

Are you doing this because you want to hide your code? If you're not satisfied with merely compiling to pyc format, as we discussed in #295, then you should look into Python obfuscation tools, which will be be much easier than trying to compile for Android using Cython.

@sayan-sen sayan-sen reopened this Jun 2, 2020
@sayan-sen
Copy link
Author

sayan-sen commented Jun 2, 2020

I need to Cythonize because because .pyc bytecode is decompileable and the obfuscation is easily reverse-engineered.
So now am using:
PyObject os= py.getModule("setup");
where setup.py:

from setuptools import setup
from Cython.Build import cythonize
import os
print(os.getcwd())
os.chdir('/sdcard/Download')
print(os.getcwd())

setup(
    ext_modules=cythonize('test1.py')
)

I have put the python script test1.py in /sdcard/Download.
But now it throws the following error:

W/python.stderr: /data/user/0/com.example.styleapp/files/chaquopy/AssetFinder/requirements/Cython/Compiler/Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: /storage/emulated/0/Download/test1.py

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.styleapp, PID: 18166
    com.chaquo.python.PyException: SystemExit: usage:  [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
       or:  --help [cmd1 cmd2 ...]
       or:  --help-commands
       or:  cmd --help
    
    error: no commands supplied
        at <python>.distutils.core.setup(core.py:136)
        at <python>.setuptools.setup(__init__.py:161)
        at <python>.setup.<module>(setup.py:8)
        at <python>.importlib._bootstrap._call_with_frames_removed(<frozen importlib._bootstrap>:219)
        at <python>.importlib._bootstrap_external.exec_module(<frozen importlib._bootstrap_external>:783)
        at <python>.java.android.importer.exec_module(importer.py:503)
        at <python>.java.android.importer.exec_module(importer.py:546)
        at <python>.importlib._bootstrap._load_unlocked(<frozen importlib._bootstrap>:671)
        at <python>.importlib._bootstrap._find_and_load_unlocked(<frozen importlib._bootstrap>:975)
        at <python>.importlib._bootstrap._find_and_load(<frozen importlib._bootstrap>:991)
        at <python>.importlib._bootstrap._gcd_import(<frozen importlib._bootstrap>:1014)
        at <python>.importlib.import_module(__init__.py:127)
        at <python>.chaquopy_java.Java_com_chaquo_python_Python_getModule(chaquopy_java.pyx:152)
        at com.chaquo.python.Python.getModule(Native Method)
        at com.example.styleapp.MainActivity.runthemodel(MainActivity.java:127)
        at com.example.styleapp.MainActivity.access$000(MainActivity.java:47)
        at com.example.styleapp.MainActivity$2.onMenuItemClick(MainActivity.java:103)
        at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:154)
        at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:991)
        at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:981)
        at androidx.appcompat.widget.ActionMenuView.invokeItem(ActionMenuView.java:625)
        at androidx.appcompat.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:151)
        at android.view.View.performClick(View.java:7140)
        at android.view.View.performClickInternal(View.java:7117)
        at android.view.View.access$3500(View.java:801)
        at android.view.View$PerformClick.run(View.java:27355)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7410)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)

Is it because am not passing args to setup.py? like setup.py build_ext --inplace

@sayan-sen
Copy link
Author

Currently am trying to use os.system:

import os
os.system('python3 setup.py build_ext -b "/sdcard/Download/" -t .')

But

PyObject os = py.getModule("os");
os.callAttr("system","python3 setup.py build_ext -b /sdcard/Download/ -t .");

is not even calling the setup.py script.

@mhsmith
Copy link
Member

mhsmith commented Jun 2, 2020

You won't be able to compile a Cython module on an actual Android device, because most devices don't come with a compiler.

If you need to build your code into .so file, then you can use Cython with our package build tool, which was used to build everything in the native package repository. For more details, see #175 (comment).

@sayan-sen
Copy link
Author

So the licensed package build tool builds the .so files for Android platform?

@mhsmith
Copy link
Member

mhsmith commented Jun 2, 2020

Yes: for more details on the tool, see #175 (comment). And for instructions on building your own Cython module, see #800 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants