Вопрос или проблема
Debian 8 Jessie, версия OpenSSL 1.1.0,
версия cURL: 7.50.2
Я пытаюсь собрать curl на системе Linux Debian. Все этапы проходят нормально до попытки сборки с помощью команды make
. Этап линковки завершается ошибкой, приведенной ниже:
CC ../lib/curl-nonblock.o
CC ../lib/curl-warnless.o
CCLD curl
../lib/.libs/libcurl.so: неопределенная ссылка на 'RAND_egd'
collect2: ошибка: ld вернул статус выхода 1
Makefile:771: рецепт для цели 'curl' не удался
make[2]: *** [curl] Ошибка 1
Функция RAND_egd является частью библиотеки OpenSSL, поэтому я выполнил ldd на файле libcurl.so, чтобы убедиться, что библиотека OpenSSL найдена, и это так, судя по выводу ldd ниже.
linux-vdso.so.1 (0x00007ffceb5a1000)
libnghttp2.so.14 => /usr/lib/x86_64-linux-gnu/libnghttp2.so.14 (0x00007ff9ffc05000)
libidn.so.11 => /usr/lib/x86_64-linux-gnu/libidn.so.11 (0x00007ff9ff9d1000)
libssh2.so.1 => /usr/lib/x86_64-linux-gnu/libssh2.so.1 (0x00007ff9ff7a8000)
libssl.so.1.1 => /usr/local/lib/libssl.so.1.1 (0x00007ff9ff53a000)
libcrypto.so.1.1 => /usr/local/lib/libcrypto.so.1.1 (0x00007ff9ff0af000)
liblber-2.4.so.2 => /usr/lib/x86_64-linux-gnu/liblber-2.4.so.2 (0x00007ff9feea0000)
libldap_r-2.4.so.2 => /usr/lib/x86_64-linux-gnu/libldap_r-2.4.so.2 (0x00007ff9fec4e000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007ff9fea33000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff9fe688000)
libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 (0x00007ff9fe3a6000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff9fe1a2000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff9fdf85000)
libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007ff9fdd6e000)
libsasl2.so.2 => /usr/lib/x86_64-linux-gnu/libsasl2.so.2 (0x00007ff9fdb52000)
libgnutls-deb0.so.28 => /usr/lib/x86_64-linux-gnu/libgnutls-deb0.so.28 (0x00007ff9fd833000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffa0009e000)
libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007ff9fd621000)
libp11-kit.so.0 => /usr/lib/x86_64-linux-gnu/libp11-kit.so.0 (0x00007ff9fd3db000)
libtasn1.so.6 => /usr/lib/x86_64-linux-gnu/libtasn1.so.6 (0x00007ff9fd1c7000)
libnettle.so.4 => /usr/lib/x86_64-linux-gnu/libnettle.so.4 (0x00007ff9fcf95000)
libhogweed.so.2 => /usr/lib/x86_64-linux-gnu/libhogweed.so.2 (0x00007ff9fcd66000)
libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007ff9fcae3000)
libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007ff9fc8db000)
Итак, библиотека есть. Я также проверил файл rand.h в каталоге include OpenSSL, и, конечно, объявление функции присутствует, так что оно должно быть определено в библиотеке. Как я могу выяснить причину и разрешить эту ошибку?
Как решить неопределенную ссылку на ‘RAND_egd’
Я полагаю, вам следует теперь использовать RAND_add_egd
. Также смотрите упрощение API rand_egd на рассылке openssl-dev.
Код, который вы компилируете, должен иметь условие для OpenSSL 1.1.0. Может быть что-то вроде:
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
int rc = RAND_egd(<path>);
...
#else
int rc = RAND_add_egd(<path>);
...
#endif
Дэниел обычно очень хорошо следит за новостями OpenSSL. Похоже, что вы получаете устаревшую версию чего-то от дистрибутива.
Согласно cURL Issue 763, cURL впервые добавил поддержку openssl-1.1.0-dev как минимум в апреле 2016 года. Полный журнал изменений доступен по адресу cURL Changelog.
В этом отношении вам, вероятно, стоит перейти на cURL 7.50.2. У него 12 известных уязвимостей. Похоже, что версия 7.51.0 была выпущена 2 ноября 2016 года.
В моем случае на Ubuntu 16.04.7 LTS (Xenial Xerus) эта ошибка произошла, когда я собрал исходный код php-7.4 с openssl 1.1.1m.
Итак, я скачал и собрал egd (в моем случае egd-0.9), основываясь на этой ссылке (содержит ссылку для скачивания) OpenSSL – RAND_egd, и пересобрал исходный код PHP, и теперь он работает в моем случае.
Ответ или решение
Ошибка "undefined reference to ‘RAND_egd’" при сборке cURL на системе Debian 8 Jessie с OpenSSL версии 1.1.0 и cURL версии 7.50.2 может возникнуть по нескольким причинам, в основном связанным с изменениями в API OpenSSL между версиями. Давайте внимательно рассмотрим, как можно разрешить данную проблему.
1. Изменения в API OpenSSL
С версии OpenSSL 1.1.0 функция RAND_egd
была удалена, и вместо нее рекомендуется использовать RAND_add_egd
. Если вы компилируете код, который не учел эти изменения, это может вызвать указанную ошибку.
2. Проверка совместимости кода
Если вы имеете доступ к исходному коду, внесите следующие изменения:
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
int rc = RAND_add_egd(<path>);
#else
int rc = RAND_egd(<path>);
#endif
Таким образом, код будет совместим как с версиями до OpenSSL 1.1.0, так и с более новыми версиями.
3. Обновление cURL
Кроме того, ваша версия cURL (7.50.2) довольно устарела и имеет известные уязвимости (12 известных уязвимостей, согласно официальной документации cURL). Рекомендуется обновить cURL до более свежей версии (рекомендуемая версия — 7.51.0 и выше), которая уже имеет поддержку OpenSSL 1.1.0 и исправления безопасности.
4. Подключение библиотеки OpenSSL
Убедитесь, что при компиляции cURL пути к библиотекам OpenSSL правильно указаны и доступны. Возможно, вам нужно будет явно указать путь к библиотекам в ваших настройках сборки (например, через ./configure --with-openssl=/usr/local/lib
).
5. Проверка конфигурации и сборки
Убедитесь также, что конфигурация и сборка выполняются правильно, путем очистки предыдущих сборок:
make clean
./configure
make
6. Дополнительные шаги
Если вы продолжаете сталкиваться с ошибкой:
- Проверьте логи и сообщения об ошибках во время сборки.
- Убедитесь, что установлены все нужные зависимости для сборки cURL с поддержкой OpenSSL.
- Если необходимо, попробуйте установить и скомпилировать поддержку для
EGD
(Entropy Gathering Daemon), если это имеет отношение к вашему проекту.
Заключение
По сути, проблема связана с изменениями в библиотеке OpenSSL и устаревшей версией cURL. Обновление кодовой базы и использование правильных функций API должна помочь вам избежать ошибок на этапе связывания. Убедитесь, что вы используете актуальные версии используемых вами инструментов и библиотек для предотвращения подобных проблем в будущем.