Mathics3 / mathicsscript

Terminal CLI to Mathics3
GNU General Public License v3.0
52 stars 7 forks source link

``OSError: no library called "cairo-2" was found`` #76

Open Li-Xiang-Ideal opened 10 months ago

Li-Xiang-Ideal commented 10 months ago

Description

A well-known bug of cairo

How to Reproduce

On Windows, Python 3.8+

  1. Install mathicsscript pip install mathicsscript
  2. Enter mathicsscript

Output Given

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Program Files\Python311\Scripts\mathicsscript.exe\__main__.py", line 4, in <module>
  File "C:\Program Files\Python311\Lib\site-packages\mathicsscript\__main__.py", line 39, in <module>
    from mathicsscript.format import format_output, matplotlib_version
  File "C:\Program Files\Python311\Lib\site-packages\mathicsscript\format.py", line 46, in <module>
    from cairosvg import svg2png
  File "C:\Program Files\Python311\Lib\site-packages\cairosvg\__init__.py", line 26, in <module>
    from . import surface  # noqa isort:skip
    ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\site-packages\cairosvg\surface.py", line 9, in <module>
    import cairocffi as cairo
  File "C:\Program Files\Python311\Lib\site-packages\cairocffi\__init__.py", line 47, in <module>
    cairo = dlopen(
            ^^^^^^^
  File "C:\Program Files\Python311\Lib\site-packages\cairocffi\__init__.py", line 44, in dlopen
    raise OSError(error_message)  # pragma: no cover
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: no library called "cairo-2" was found
no library called "cairo" was found
no library called "libcairo-2" was found
cannot load library 'libcairo.so.2': error 0x7e.  Additionally, ctypes.util.find_library() did not manage to locate a library called 'libcairo.so.2'
cannot load library 'libcairo.2.dylib': error 0x7e.  Additionally, ctypes.util.find_library() did not manage to locate a library called 'libcairo.2.dylib'
cannot load library 'libcairo-2.dll': error 0x7e.  Additionally, ctypes.util.find_library() did not manage to locate a library called 'libcairo-2.dll'

Expected behavior

Mathicscript: 6.0.0, Mathics 6.0.3
on CPython 3.11.5 (tags/v3.11.5:cce6ba9, Aug 24 2023, 14:38:34) [MSC v.1936 64 bit (AMD64)]

Using:
SymPy 1.12, mpmath 1.3.0, numpy 1.24.4
cython 3.0.4, matplotlib 3.8.0,
Asymptote version 2.85

Copyright (C) 2011-2023 The Mathics Team.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
See the documentation for the full license.

Quit by evaluating Quit[] or by pressing CTRL-BREAK.

In[1]:=

Your Environment

Windows 10, Python 3.11

Source of this bug

  1. Cairo is not built for Windows, cairocffi needs an additional libcairo-2.dll file in a directory listed in the PATH environment variable to work. See Installing cairo on Windows.
  2. Python 3.8+ no longer searches for DLLs in PATH, we have to add everything in PATH manually. See django OSError: no library called "cairo" was found on windows or PyCairo Windows Python3.8 Import Issue

How to fix it

Step 1

Install GTK3 for Windows or UniConvertor.

Step 2

Method 1

Add the following contents to cairocffi/__init__.py

import os
# from ctypes.util import find_library # If find_library is not imported in __init__.py, uncomment this line

def set_dll_search_path():
    # Python 3.8+ no longer searches for DLLs in PATH, so we have to add
    # everything in PATH manually. Note that unlike PATH add_dll_directory
    # has no defined order, so if there are two cairo DLLs in PATH we
    # might get a random one.
    if os.name != "nt" or not hasattr(os, "add_dll_directory"):
        return
    for p in os.environ.get("PATH", "").split(os.pathsep):
        try:
            os.add_dll_directory(p)
        except OSError:
            pass

if not find_library('libcairo-2'):
    set_dll_search_path()

Method 2

Install cairocffi from pipwin

pip install pipwin
pipwin install cairocffi

cairocffi installed from pipwin is somewhat outdated (currently 1.3.0->1.6.1)

rocky commented 10 months ago

Thanks for the report. If you are able and willing put in a PR for this, please do.

Li-Xiang-Ideal commented 10 months ago

Thanks for the report. If you are able and willing put in a PR for this, please do.

Tried to put in one.