rmn
rmn

Reputation: 131

Python : Import cairo error (2.7 & 3.6) undefined symbol: cairo_tee_surface_index

I get the following error when trying to import gtk in Python 2.7 :

>>> import gtk Traceback (most recent call last): File "<stdin>", line 1, in <module> File "gtk/__init__.py", line 40, in <module> from gtk import _gtk File "/usr/lib/python2.7/site-packages/cairo/__init__.py", line 1, in <module> from ._cairo import * # noqa: F401,F403 ImportError: /usr/lib/python2.7/site-packages/cairo/_cairo.so: undefined symbol: cairo_tee_surface_index

And I get the following error when trying to import cairo from Python 3.6:

>>> import cairo Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.6/site-packages/cairo/__init__.py", line 1, in <module> from ._cairo import * # noqa: F401,F403 ImportError: /usr/lib/python3.6/site-packages/cairo/_cairo.cpython-36m-x86_64-linux-gnu.so: undefined symbol: cairo_tee_surface_index

I compiled and built the modules in the order as given in the BLFS book. I also installed cairo as given in the book with tee enabled.

My system is an LFS, with 4.14.4 Kernel Version, with Python 2.7.14 and Python 3.6.4.

EDIT: Downloaded the source and did 'make uninstall' and then reinstalled it. Now I can import cairo without any errors.

Upvotes: 11

Views: 10165

Answers (9)

robertspierre
robertspierre

Reputation: 4441

It looks like it got broken with pycairo 1.23

Please install pycairo 1.22

pip3 install pycairo==1.22

Upvotes: 1

Vicrobot
Vicrobot

Reputation: 3988

I just shifted on older version of pycairo. Try downloading version 1.11.0.

pip uninstall pycairo pip install pycairo==1.11.0

You can do shift on other versions available too. At this time; they are:-

1.11.0, 1.11.1, 1.12.0, 1.13.0, 1.13.1, 1.13.2, 1.13.3, 1.13.4, 1.14.0, 1.14.1, 1.15.0, 1.15.1, 1.15.2, 1.15.3, 1.15.4, 1.15.5, 1.15.6, 1.16.0, 1.16.1, 1.16.2, 1.16.3, 1.17.0, 1.17.1, 1.18.0

I don't know much about its internals, i just used brute force to get a solution. Hope it helps.

Upvotes: 6

Swain Subrat Kumar
Swain Subrat Kumar

Reputation: 523

conda install -c conda-forge pycairo

Just install your pycairo using this command, it will work fine and run fine. No need to do anything.

Upvotes: 4

Maria
Maria

Reputation: 309

I faced a similar problem while installing PyGObject.

File "/tmp/pip-build-env-dyg6e3zi/overlay/lib/python3.7/site-packages/cairo/__init__.py", line 1, in <module>
      from ._cairo import *  # noqa: F401,F403
  ImportError: /tmp/pip-build-env-dyg6e3zi/overlay/lib/python3.7/site-packages/cairo/_cairo.cpython-37m-x86_64-linux-gnu.so: undefined symbol: cairo_svg_surface_set_document_unit
  ----------------------------------------
  ERROR: Failed building wheel for PyGObject

The following steps worked for me. Firstly make sure that you are not using conda, as paths would be different for it. Then,

sudo apt update
sudo apt install python3-pip -y

Install these dependencies

sudo apt install libjpeg8-dev zlib1g-dev libtiff-dev libfreetype6 libfreetype6-dev libwebp-dev libopenjp2-7-dev libopenjp2-7-dev -y

Also update pip universally.

sudo -H pip3 install -U pip

Upvotes: 0

lalebarde
lalebarde

Reputation: 1816

This is the same solution no 1 of Juraj Michalak with conda: undefined symbol: cairo_tee_surface_index, with detailed process.

>>> import cairo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/lalebarde/anaconda3/lib/python3.7/site-packages/cairo/__init__.py", line 1, in <module>
    from ._cairo import *  # noqa: F401,F403
ImportError: /home/lalebarde/anaconda3/lib/python3.7/site-packages/cairo/_cairo.cpython-37m-x86_64-linux-gnu.so: undefined symbol: cairo_tee_surface_index

I have the cairo_tee_surface_index symbol both in cairo (1.14.12) but not in the libcairo it makes use of:

ldd /home/lalebarde/anaconda3/lib/python3.7/site-packages/cairo/_cairo.cpython-37m-x86_64-linux-gnu.so
    libcairo.so.2 => /home/lalebarde/anaconda3/lib/libcairo.so.2 (0x00007f5a82de8000)
strings /home/lalebarde/anaconda3/lib/python3.7/site-packages/cairo/_cairo.cpython-37m-x86_64-linux-gnu.so | grep cairo_tee_surface_index
cairo_tee_surface_index
cairo_tee_surface_index
cairo_tee_surface_index
strings /home/lalebarde/anaconda3/lib/libcairo.so.2 | grep cairo_tee_surface_index

My system one is alright (1.14.8-1):

strings /usr/lib/x86_64-linux-gnu/libcairo.so.2 | grep cairo_tee_surface_index
cairo_tee_surface_index

So, what I have tried is to downgrade cairo under the condaenvironment to the version of my system (downloaded from the conda repo here for version 1.14.8), in order to replace the default lib by the system one which has the missing symbol:

conda uninstall cairo
The following packages will be REMOVED:
  cairo-1.14.12-h8948797_3
conda install cairo-1.14.8-0.tar.bz2

Then again:

ldd /home/lalebarde/anaconda3/lib/python3.7/site-packages/cairo/_cairo.cpython-37m-x86_64-linux-gnu.so 
    libcairo.so.2 => /home/lalebarde/anaconda3/lib/libcairo.so.2 (0x00007f9b163c9000)
strings /home/lalebarde/anaconda3/lib/python3.7/site-packages/cairo/_cairo.cpython-37m-x86_64-linux-gnu.so | grep cairo_tee_surface_index
cairo_tee_surface_index
cairo_tee_surface_index
cairo_tee_surface_index
strings /home/lalebarde/anaconda3/lib/libcairo.so.2 | grep cairo_tee_surface_index

Nothing but expected. Now I replace it with the system one:

cp /home/lalebarde/anaconda3/lib/libcairo.so.2 /home/lalebarde/anaconda3/lib/libcairo.so.2.old
cp /usr/lib/x86_64-linux-gnu/libcairo.so.2 /home/lalebarde/anaconda3/lib/
strings /home/lalebarde/anaconda3/lib/libcairo.so.2 | grep cairo_tee_surface_index
cairo_tee_surface_index

Now, import cairo works !

Upvotes: 0

Jingpeng Wu
Jingpeng Wu

Reputation: 522

I find that the root error is not finding the py3cairo.h

just locate py3cairo.h, and ln -s /usr/include/pycairo/py3cairo.h /usr/include/py3cairo.h

then the compilation works without error.

Upvotes: 0

Juraj Michalak
Juraj Michalak

Reputation: 1216

I'm using conda and I have same issue, but path are little bit different due to conda env: ImportError: /home/juro/anaconda3/envs/py37/lib/python3.7/site-packages/cairo/_cairo.cpython-37m-x86_64-linux-gnu.so: undefined symbol: cairo_tee_surface_index $ ldd /home/juro/anaconda3/envs/py37/lib/python3.7/site-packages/cairo/_cairo.cpython-37m-x86_64-linux-gnu.so $ outputs: ... libcairo.so.2 => /home/juro/anaconda3/envs/py37/lib/libcairo.so.2 (0x00007ff6d8ad9000) ...

It seems that conda (anaconda) package cairo is broken or pip pycairo package is broken (I don't know who's fault it is ;)). It's missing symbol cairo_tee_surface_index in "libcairo.so.2" library. That symbol is required by pycairo package (pip install pycairo), so when you do "import cairo" you get that failure.

You have these options:

  1. I found out that my system (debian) libcairo.2 has that missing symbol: $ strings /usr/lib/x86_64-linux-gnu/libcairo.so.2.11400.8 | grep cairo_tee_surface_index. So I just downgraded my conda's cairo to the same version as on my system conda install cairo=version and copied my system libcairo over my conda libcairo:cp /usr/lib/x86_64-linux-gnu/libcairo.so.2.11400.8 ~/anaconda3/lib/libcairo.so.2.11400.8. You can backup the original one, but don't use move command (mv) because those libraries are hardlinks (those libraries can be shared among multiple conda environments). Use just cp for backup.
  2. You can change RPATH inside "_cairo.cpython-36m-x86_64-linux-gnu.so" libary file using chrpath command (man chrpath) to point to folder where is correct libcairo.so.2. With correct one I mean the library build with cairo_tee_surface_index symbol.
  3. build your own cairo library (same version as in your conda '$ conda list cairo') and copy it over ~/anaconda3/lib/libcairo.so.2.{additional_version_characters}.

Where is your system's libcairo? /sbin/ldconfig -p | grep libcairo

Upvotes: 2

Ron Humble
Ron Humble

Reputation: 1

For me,
ldd /usr/lib64/python3.6/site-packages/cairo/_cairo.cpython-36m-x86_64-linux-gnu.so
showed: libcairo.so.2 => /usr/local/lib/libcairo.so.2

I had a stale self-compiled cairo installation. If you still have the original compile tree, you can run make uninstall within it. Otherwise, simply move the offending cairo files in /usr/local/lib manually to another location, and delete once you are sure the files are unnecessary.

Upvotes: 0

neouyghur
neouyghur

Reputation: 1647

install cairocffi, and replace import cairocffi with import cairocffi as cairo.

Upvotes: 3

Related Questions