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

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

Open
Li-Xiang-Ideal opened this issue Nov 21, 2023 · 2 comments
Open

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

Li-Xiang-Ideal opened this issue Nov 21, 2023 · 2 comments

Comments

@Li-Xiang-Ideal
Copy link

Li-Xiang-Ideal commented Nov 21, 2023

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
Copy link
Member

rocky commented Nov 21, 2023

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

@Li-Xiang-Ideal
Copy link
Author

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

Tried to put in one.

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