libfreetype.so when system == Emscripten
in pyodide system = platform.system() is equal to Emscripten, which results to library_name = 'libfreetype.so', lib file (if I understand correctly) which can't be found. Is it something on your side or is it my incompetency?
File "/lib/python3.10/site-packages/freetype/raw.py", line 49, in <module>
_lib = ctypes.CDLL(filename)
File "/lib/python3.10/ctypes/__init__.py", line 374, in __init__
self._handle = _dlopen(self._name, mode)
OSError: Could not load dynamic lib: libfreetype.so
Error: libfreetype.so: file not found, and synchronous loading of external files is not available
i'm not even sure that loading dynamic libraries via cytpes is supported with emscripten python.. googling around I found this https://github.com/pyodide/pyodide/issues/728
since https://github.com/pyodide/pyodide/pull/1656 was merged, ctypes is supposedly supported in pyodide. Maybe you simply don't have the libfreetype.so installed, or your linker can't find it in the default library search paths (try setting LD_LIBRARY_PATH or DYLD_LIBRARY_PATH).
I also found https://github.com/pyodide/pyodide/issues/2338 while searching for "synchronous loading of external files is not available" error.
I've never used emscripten python, maybe other maintainers know more.
Are you on mac os x or windows (where it would be libfreetype.dylib or freetype6.dll)?
I am on MacOs, but that shouldn't influence Pyodide, right? Thanks for pointing out the issue on Pyodide. Sorry, I am not that knowledgeable. I think my comment has nothing to do with this library, but rather with Pyodide.
This wrapper relies on the FreeType installed by the OS, like via brew, right? I guess the browser won't be able to access it anyway, even after the fix. Then I need to compile FreeType to .so and put it somewhere so freetype/raw.py can find it and then generate wheel out of this package, I believe 🙈
we do provide precompiled wheels for most platforms/py-versions already, they are published on the Python Packaging Index (PyPI), it's what gets normally installed when you do pip install freetype-py
ok you're on mac so you should find the library under the name "libfreetype.dylib".. but instead of "Darwin" you get "Emscripten" from platform.system() so it falls back to the (implicit) "Linux" else branch of the if statement.
Not sure what's the best way to detect this situation.
how did you install freetype-py in pyodide? Using micropip.install?
not sure, but maybe we need to build a custom Pyodide package where the freetype library itself is converted to webassembly?
https://pyodide.org/en/stable/development/new-packages.html#c-library-dependencies
You don't really need to build freetype - you just need to duplicate libfreetype.dylib as libfreetype.so, right next to wherever it is on your system, or modify that line of freetype-py code to look for dylib instead of so. Assuming you have libfreetype.dylib on your machine. If not, download one of the binaries...
pyodide is cpython compiled to webassembly, it runs in a special vm inside the browser, it doesn't have access to external libraries. We need to make a pyodide package as explained in the pyodide docs link I posted above. We're lucky in that there's already an emscripten port for the freetype library itself, so it's a matter of doing something similar to what they do for the pyodide package for "matplotlib" module (which also depends on the freetype library): https://github.com/pyodide/pyodide/blob/38fae6e9cbcdd8e932a53bf1c763279dc55729d5/packages/matplotlib/meta.yaml#L24-L26
Argh yes. The emscripten port of freetype is really old though.
The emscripten port of freetype is really old though
yeah, 2.6 is quite old. Some user of the emscripten port reported success in building freetype with the emcmake tool
I discovered that the latest FreeType builds fine using emcmake cmake with their latest CMakeLists.txt file, so I switched to using that in my workflow.
https://github.com/emscripten-ports/FreeType/issues/4#issuecomment-832213811
So it's technically feasible, only need someone to take the time to understand how to build a pyodide package and make a PR upstream to include in pyodide's own built-in packages.