From 2ff175f0fc8e3fa2e62ef2cc729803f3d6067ccd Mon Sep 17 00:00:00 2001 From: Peter Badida Date: Tue, 4 Dec 2018 22:31:28 +0100 Subject: [PATCH] Add instructions for packaging with PyInstaller --- docs/source/index.rst | 1 + docs/source/packaging.rst | 139 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 docs/source/packaging.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index dcbdff5..68bbbd8 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -16,6 +16,7 @@ documentation. quickstart android api + packaging Indices and tables ================== diff --git a/docs/source/packaging.rst b/docs/source/packaging.rst new file mode 100644 index 0000000..2f0dbe3 --- /dev/null +++ b/docs/source/packaging.rst @@ -0,0 +1,139 @@ +.. _packaging: + +Packaging +========= + +For Packaging we use `PyInstaller `_ and with +these simple steps we will create a simple executable containing PyJNIus +that prints the path of currently used Java. These steps assume you have +a supported version of Python for PyJNIus and PyInstaller available together +with Java installed (necessary for running the application). + +main.py +------- + +.. code:: python + + from jnius import autoclass + + if __name__ == '__main__': + print(autoclass('java.lang.System').getProperty('java.home')) + +This will be our ``main.py`` file. You can now call PyInstaller to create +a basic ``.spec`` file which contains basic instructions for PyInstaller with:: + + pyinstaller main.py + +main.spec +--------- + +The created ``.spec`` file might look like this:: + + # -*- mode: python -*- + + block_cipher = None + + + a = Analysis( + ['main.py'], + pathex=[''], + binaries=None, + datas=None, + hiddenimports=[], + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher + ) + + pyz = PYZ( + a.pure, + a.zipped_data, + cipher=block_cipher + ) + + exe = EXE( + pyz, + a.scripts, + exclude_binaries=True, + name='main', + debug=False, + strip=False, + upx=True, + console=True + ) + + coll = COLLECT( + exe, + a.binaries, + a.zipfiles, + a.datas, + strip=False, + upx=True, + name='main' + ) + +Notice the ``Analysis`` section, it contains details for what Python related +files to collect e.g. the ``main.py`` file. For PyJNIus to work you need to +include the ``jnius_config`` module to the ``hiddenimports`` list, otherwise +you will get a ``ImportError: No module named jnius_config``:: + + ... + + a = Analysis( + ['main.py'], + pathex=[''], + binaries=None, + datas=None, + hiddenimports=['jnius_config'], + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher + ) + + ... + +After the ``.spec`` file is ready, in our case it's by default called by the +name of the ``.py`` file, we need to direct PyInstaller to use that file:: + + pyinstaller main.spec + +This will create a folder with all required ``.dll`` and ``.pyd`` or ``.so`` +shared libraries and other necessary files for our application and for Python +itself. + +Running +------- + +We have the application ready, but the "problem" is PyJNIus doesn't detect +any installed Java on your computer (yet). Therefore if you try to run the +application, it'll crash with a ``ImportError: DLL load failed: ...``. +For this simple example if you can see ``jnius.jnius.pyd`` or +``jnius.jnius.so`` in the final folder with ``main.exe`` (or just ``main``), +the error indicates that the application could not find Java Virtual Machine. + +The Java Virtual Machine is in simple terms said another necessary shared +library your application needs to load (``jvm.dll`` or ``libjvm.so``). + +On Windows this file might be in a folder similar to this:: + + C:\Program Files\Java\jdk1.7.0_79\jre\bin\server + +and you need to include the folder to the system ``PATH`` environment variable +with this command:: + + set PATH=%PATH%;C:\\Program Files\\Java\\jdk1.7.0_79\\jre\\bin\\server + +After the ``jvm.dll`` or ``libjvm.so`` becomes available, you can safely +try to run your application:: + + main.exe + +and you should get an output similar to this:: + + C:\Program Files\Java\jdk1.7.0_79\jre