Проблемы с установкой .deb из-за функций login_tty и openpty в Lazarus и FPC
Введение
В сообществе разработчиков на Delphi и Pascal, использующих Lazarus и Free Pascal Compiler (FPC) на Linux, возникла серьезная проблема, связанная с функциями login_tty и openpty. Эти функции, используемые в Lazarus IDE, могут вызывать проблемы при установке .deb пакетов на системах с устаревшими версиями glibc (ниже 2.34). В этой статье мы подробно разберем суть проблемы, ее причины и возможные решения.
Суть проблемы
При анализе исполняемого файла lazarus-ide обнаружилось, что большинство функций из libc имеют версию GLIBC_2.2.5, но две функции - login_tty и openpty - требуют GLIBC_2.34. Это создает следующие проблемы:
Невозможность запуска Lazarus IDE на системах с glibc старше 2.34
Проблемы с установкой через FPCUpDeluxe на старых системах
Как отмечает участник форума robert rozee, это может быть связано с частичной компиляцией на разных дистрибутивах Linux или использованием модифицированного компилятора FPC.
Технические детали
Функции login_tty и openpty используются в следующих файлах:
/usr/share/lazarus/3.6.0/components/fpdebug/fpdbglinuxclasses.pas - активное использование
/usr/share/fpcsrc/3.2.2/packages/libc/src/ptyh.inc - только объявление
/usr/share/fpcsrc/3.2.2/packages/libc/src/utmph.inc - только объявление
Пример объявления этих функций в коде:
function login_tty(__fd: longint): longint; cdecl; external 'c' name 'login_tty';
function openpty(__amaster: Plongint; __aslave: Plongint; __name: Pchar;
__termp: pointer{Ptermios}; __winp: pointer{Pwinsize}): longint;
cdecl; external 'util' name 'openpty';
Причины проблемы
Как отмечает PascalDragon, эти функции существуют в коде уже более 10 лет, задолго до их перемещения из libutil в libc в проекте glibc. Основная проблема заключается в том, что приложение, скомпилированное на современной системе Linux, может не работать на более старых.
Fred vS предлагает правильный подход к объявлению этих функций с указанием версий GLIBC:
const
{$if defined(linux) and defined(cpux86_64)}
LIBC_SUFFIX = '@GLIBC_2.2.5';
{$else}
{$if defined(linux) and defined(cpuarm)}
LIBC_SUFFIX = '@GLIBC_2.4';
{$else}
{$if defined(linux) and defined(cpui386)}
LIBC_SUFFIX = '@GLIBC_2.0';
{$else}
LIBC_SUFFIX = '';
{$endif}
{$endif}
{$endif}
function login_tty(__fd: longint): longint; cdecl; external 'c' name 'login_tty' + LIBC_SUFFIX;
function openpty(__amaster: Plongint; __aslave: Plongint; __name: Pchar;
__termp: pointer; __winp: pointer): longint;
cdecl; external 'util' name 'openpty' + LIBC_SUFFIX;
Предлагаемые решения
1. Комментирование неиспользуемого кода
Если функции login_tty и openpty не используются активно в IDE (как предполагает robert rozee), их можно просто закомментировать в исходном коде.
2. Динамическая загрузка функций
Более гибкое решение - использовать динамическую загрузку этих функций через dlopen/dlsym. Пример реализации:
type
TLoginTtyFunc = function(__fd: longint): longint; cdecl;
TOpenPtyFunc = function(__amaster: Plongint; __aslave: Plongint;
__name: Pchar; __termp: pointer; __winp: pointer): longint; cdecl;
var
LoginTty: TLoginTtyFunc = nil;
OpenPty: TOpenPtyFunc = nil;
LibHandle: Pointer = nil;
procedure LoadLibCFunctions;
begin
LibHandle := dlopen('libc.so.6', RTLD_LAZY);
if Assigned(LibHandle) then
begin
LoginTty := TLoginTtyFunc(dlsym(LibHandle, 'login_tty'));
OpenPty := TOpenPtyFunc(dlsym(LibHandle, 'openpty'));
end;
end;
initialization
LoadLibCFunctions;
finalization
if Assigned(LibHandle) then
dlclose(LibHandle);
3. Исправление версий GLIBC в FPC
Как предлагают участники обсуждения, можно модифицировать компилятор FPC для принудительного использования старых версий символов GLIBC (2.2.5 вместо 2.34).
4. Сборка из исходников на целевой системе
Самый надежный способ избежать проблем - собирать Lazarus и FPC непосредственно на той системе, где они будут использоваться:
# После установки Lazarus
cd /usr/share/lazarus
sudo make bigide
Альтернативное решение: использование статической линковки
Для обеспечения максимальной совместимости можно рассмотреть вариант статической линковки с libc, хотя это имеет свои ограничения и не всегда возможно.
Заключение
Проблема с функциями login_tty и openpty в Lazarus на Linux демонстрирует сложности поддержки совместимости между разными версиями glibc. Наиболее перспективными решениями представляются:
Исправление объявлений функций с указанием правильных версий GLIBC
Переход на динамическую загрузку потенциально проблемных функций
Сборка Lazarus непосредственно на целевой системе
Разработчикам, столкнувшимся с этой проблемой, рекомендуется либо обновить систему до версии с glibc 2.34 и выше, либо использовать предложенные в статье методы для обеспечения совместимости.
Проблема с установкой .deb-пакетов в Lazarus и FPC из-за функций login_tty и openpty, требующих устаревших версий glibc.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.