Pyenv: The Python ssl extension was not compiled. Missing the OpenSSL lib? — решение


Tagged , , , ,

При сборке старых версий питона в pyenv возникает ошибка сборки ssl модуля. Есть две возможные причины возникновения это ошибки.

  1. У вас не стоят хидеры для openssl. Решается это просто — поставить пакет openssl-devel для CentOS/RH или libssl-dev для Ubuntu/Debian.
  2. Версия вашего системного openssl слишком новая для питона. Тут все немного сложнее. Характеризуется наличием DEPRICATED ошибок в логе python-build. Про решение этой проблемы пойдет речь ниже.

Важное замечание! Перед тем как приступать, удалите пакет с хидерами от вашего openssl (openssl-devel, libssl-dev и т.д.).

Первое что надо сделать, это понять какую версию openssl нужно собрать для компиляции нужного вам питона. Для старых версий питона чаще всего это будет openssl-1.0.1, при условии то в системе у вас стоит минимум openssl-1.1.0. Если вы хотите собрать новую версию питона на старом линуксе, то все будет наоборот.

Итак, мы определились. В моем случае мне нужен openssl-1.0.1. Качаем исходники c https://ftp.openssl.org/source/old/1.0.1/ . Я взял последнюю версию openssl-1.0.1u.tar.gz. Распаковываем исходники и заходим в директорию. Прежде чем компилить, ставим компилятор и сопутствующие библиотеки. Для CentOS 8 это:

# dnf install make gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel tk-devel libffi-devel tar patch

Конфигурируем сборку:

# ./config --prefix=/opt/openssl-1.0.1 shared

Я буду ставить сборку в /opt/openssl-1.0.1, просто потому что мне так удобнее. Ключ shared явно указывает создавать shared libraries, которые нужны питону.

Собираем и устанавливаем:

# make
.......
# make install

Openssl-1.0.1 собран и установлен. Теперь надо заставить pyenv видеть его. И вот тут я потратил не мало времени, чтобы понять почему не подхватывается новый openssl. А ларчик открывается просто.

При компиляции питона, в скрипте setup.py указаны пути, по которым ищутся заголовочные файлы openssl. Это директории /usr/include, /usr/local/ssl, /usr/contrib/ssl/include/. Дак вот, чтобы pyenv подхватил наш openssl надо создать симлинк от нашего openssl до одной из эти директорий.

# ln -s /opt/openssl-1.0.1/ /usr/local/ssl

Для себя я решил, что это будет путь /usr/local/ssl, т.к. создавать симлинки вручную в /usr/include это костыль.

Но это еще не все. Для того, чтобы при компиляции подхватились нужные нам shared libraries, нужно указать переменную окружения LD_LIBRARY_PATH=/opt/openssl-1.0.1/lib/

Либо добавить эту переменную окружения пользователю в .bash_profile:

# echo 'export LD_LIBRARY_PATH="/opt/openssl-1.0.1/lib/"' >> ~/.bash_profile
# bash

или указать при сборке pyenv:

# LD_LIBRARY_PATH="/opt/openssl-1.0.1/lib/" pyenv  install 3.5.2

Готово, Питон собирается и использует нужный нам openssl.

Один маленький нюанс. Пользователь от которого будет работать ваше приложение с этой версией питона должен так же иметь переменную окружения LD_LIBRARY_PATH=/opt/openssl-1.0.1/lib/

Как уже было указано выше, можно добавть в .bash_profile, можно добавить в systemd service файл вашего демона Environment=’LD_LIBRARY_PATH=/opt/openssl-1.0.1/lib/’, есть и другие варианты. Это уже надо смотреть исходя из того как вы собрались запускать приложение на питоне.

Share:

No comments

RSS / trackback

Respond