-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Description
First of all: Thanks for building this, it's an amazing project!
I'm trying to use the dynamic linking capabilities of emscripten to compile the Python interpreter as a shared library and import it at runtime. My motivation for this is that I would like to be able to compile Python modules that rely on C extensions (e.g. numpy) and then import these modules dynamically at runtime (which should be possible via dlopen in my understanding).
I started off from from https://github.com/dgym/cpython-emscripten (which works fine when compiling Python statically) and modified the Makefile to build a shared library in addition to the static Python library. This works fine but I run into a problem when importing the library at runtime, as described here:
Before starting to debug this in depth I first wanted to make sure that I correctly set up the build process, hence my question. What I did to generate the dynamic library is the following:
- Compile the Python interpreter into a shared library using
emcc(I did not useSIDE_MODULE=1in the build step for this). This gives me alibpython3.5.sofile (which contains LLVM bitcode). - Converting the shared library into a Javascript library by running
emcc -s SIDE_MODULE=1 libpython3.5.so -o libpython3.5.js. This works fine. - Compiling my example program with
MAIN_MODULE=1without explicitly linking in the static Python library. - Inserting the following code to import the dynamic library:
EM_ASM({
Runtime.loadDynamicLibrary('/libpython3.5.js');
});
- Initializing the Python interpreter using
Py_InitializeEx(0).
Is this the correct way to build and use a dynamic library in this case?
The last step produces an error Python error: Py_Initialize: can't import _frozen_importlib which breaks many things and keeps the interpreter from initializing properly. The core of the interpreter seems to work though (as I can run simple code like 1+1 but not import anything or even print the results).
I created a Gtihub-hosted version with the failing example for easier debugging (it takes a while to load):
http://www.andreas-dewes.de/cpython-emscripten/dll/
The build config for the Python interpreter can be found here:
https://github.com/adewes/cpython-emscripten/tree/master/3.5.2
The build config for the example script is here:
https://github.com/adewes/cpython-emscripten/tree/master/examples/07-dll-loading
Any idea where the problem could be or how I could better debug this? Please let me know if you need any more information, it would really be great to get this working!
In general, is my understanding correct that it should be possible to dynamically load Python libraries through dlopen?
Emscripten version information:
clang version 4.0.0 (emscripten 1.37.13 : 1.37.13)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/[....]/emsdk-portable/clang/e1.37.13_64bit
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/6
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/6.2.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.1
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.2.0
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.2.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Candidate multilib: x32;@mx32
Selected multilib: .;@m64
INFO:root:(Emscripten: Running sanity checks)