Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Install latest cairo lib in Ubuntu for weasyprint

I just installed an Ubuntu bionic instance. It comes with cairo 1.14.6 preinstalled. I need at least cairo 1.15.4 for weasyprint to work properly. Unfortunately, even after installing the latest cairo, python still picks up the old library. I would appreciate any clues.

# Install weasyprint dependencies
sudo apt-get install build-essential python3-dev python3-pip python3-setuptools python3-wheel python3-cffi libcairo2 libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info

# Check cairo lib version, prints "1.15.10-2ubuntu0.1"
dpkg -l '*cairo*'

# Install weasyprint
pip3 install weasyprint

# Test cairo version catch by python, still prints "1.14.6"
python3 -c "import cairocffi; print(cairocffi.cairo_version_string())"
like image 655
Josue Montano Avatar asked Feb 02 '19 01:02

Josue Montano


1 Answers

Bionic ships with Cairo 1.15 so I'm not sure how you got Cairo 1.14.

Python will sometimes keep an internal copy of libraries. The easiest first check is

find /usr/local/lib/python3*/dist-packages/PIL/ -iname '*.so*' | grep cairo

I expect you'll find another libcairo there, but if not, here's how you can track down what library cairocffi is finding.

Step 1: find the library that cairocffi is using

1.0 (Background)

cairocffi uses ctypes.util.find_library to try to locate libcairo. ctypes.util.find_library searches using these commands, in order, to try to locate libraries. I've converted the python code into shell script, and listed each one with a link to the original source.

1.1 - Find the alternate library

Run these each of these commands until you find the library. This emulates the find_library search.

1) find_library method 1

ldconfig -p | grep -Eo '\s+(libcairo\.\S+)\s+\(libc6,x86-64'

2) find_library method 2

gcc -Wl,-t -o /tmp/bla -lcairo 2> /dev/null | grep -E '([^\(\)]|\S)*libcairo\.([^\(\)]|\S)*'

3) find_library method 3

libs=$(for d in `echo $LD_LIBRARY_PATH | sed 's/:/ /g'`; do printf -- "-L$d "; done); ld -t $libs -o /dev/null -lcairo 2> /dev/null | grep -Eo '([^\(\)]|\S)*libcairo\.([^\(\)]|\S)*'

1.2 Verify the library version

Once you find the library, check its version.

strings /some/weird/place/libcairo.so.2 | grep -E '^P\?' | grep -Eo '[0-9.]+'

If it matches the bad version, continue. If it doesn't, keep seaching using 1.1. Alternatively, you can also try a generic search for all Cairo libs:

find /usr -iname '*cairo*.so*'

Step 2: Update the library

2.1 Determine who owns the library

The alternate library may have been installed using apt or pip. We'll check both. 1) Check apt

dpkg -S /some/weird/place/libcairo.so.2

2) Check pip:

pip list | tail -n +3 | cut -d" " -f1 | xargs pip show -f | grep /some/weird/place/libcairo.so.2

2.2 Update the library

If you can determine which package owns the old version, upgrade that package. If not, either delete it or manually upgrade it (copy the newer libcairo.so over it). This should solve your problem.

like image 77
Codebling Avatar answered Oct 20 '22 01:10

Codebling