В этой статье я бы хотел рассказать о том, что Windows проекты на Delphi возможно перевести на Linux в разумные сроки и с разумными трудозатратами. Что такое SCADA-система, рассказывать не буду, а перейду сразу к делу.

Runtime ядро SCADA работает под Windows в качестве сервиса. Функции стандартные «как у всех»: сбор, обработка, архивирование данных, передача данных в другие SCADA-системы по стандартным протоколам обмена. Визуализация только через Web. Runtime ядро SCADA написано на Delphi. Решено было адаптировать исходный код под  FreePascal/Lazarus, так чтобы код под Windows компилировался и в FreePascal и в Delphi, вторым этапом было допиливание проекта непосредственно на Linux машине и переделка его в демон. В FreePascal привлекала возможность компиляции как для x64, так и для плат Raspberry pi (архитектуры ARMv7, ARM64 (aarch64)).

Конфигуратор работает под Windows в виде графического приложения. Пока решено не переводить его на Linux, в крайнем случае можно запустить под Wine.

Теперь перейдем к Runtime и будем говорить о нём. В нём применяются разнообразные компоненты:

  • Работа с сетью. Компоненты Indy: IdTCPServer, IdTCPClient для реализации промышленных протоколов обмена. idHTTPServer для Web-сервера. Под Linux FreePascal они тоже есть. Оставляем без изменений.

  • Работа с базами данных. В Windows применялся FireDAC. Под Linux FreePascal его не было, и не предвиделось. Решено было добавить функцию работы с архивами с использованием компонентов ZeosLib. Отзывы о данной библиотеке были самыми разнообразными: начиная от хороших, заканчивая негативными. Библиотека показала себя с хорошей стороны. Несомненное достоинство в том, что она работает как в Delphi так и в FreePascal Windows и Linux.

  • Скриптовой движок. В Windows использовался DWScript. Использование его под Linux FreePascal невозможно. Параллельно с ним для Linux – версии добавлен RemObjects Pascal Script. Скрипты, написанные для DWScript могут быть перенесены в RemObjects Pascal Script с минимальными переделками. В Windows могут работать скрипты обоих движков одновременно. RemObjects Pascal Script не работают на архитектуре aarch64, поэтому версия для этой архитектуры без скриптов.

  • Работа с СОМ-портом. Использовались не компоненты , а функции. А в Linux они полностью отличаются от Windows.

Нужно подключить необходимые модули:

Uses

{$IFDEF UNIX}

  termio, baseunix, unix,

{$ELSE}

Открытие СОМ-порта функцией fpOpen вместо CreateFile. Запись Filewrite вместо WriteFile. Чтение FileRead вместо ReadFile. И многое другое, про это можно написать целую статью.

Основные моменты, с которыми приходится сталкиваться при переводе проектов Delphi на Linux FreePascal:

  1. Строки. Функция Length() выдаёт разный результат в Delphi и Lazarus если в строке есть русские буквы. Потому что функция работает с ANSI-строками, то есть с теми, что занимают по 1 байту на символ. А кириллица - это не ANSI а UTF8, и требует по 2 байта на символ. Вместо Length() можно использовать UTF8Length(), но такой функции нет в Delphi. В этой ситуации однозначной рекомендации нет, либо использовать директивы условной компиляции, либо использовать обходные варианты, которые в Delphi и Lazarus работают одинаково.

  2. Cthreads. Чтобы работать с потоками в  Linux нужно подключать модуль cthreads. uses {$IFDEF UNIX} cthreads, {$ENDIF}. Причем подключать его надо самым первым непосредственно в lpr-файле. Это касается не только программы, но и динамических библиотек so.

  3. {$MODE Delphi}. Если не компилируется что-то, что работает в Delphi, укажите в начале модуля режим совместимости с Delphi {$IFDEF FPC} {$MODE delphi} {$ELSE} {$ENDIF}.

По аналогии были переведены на Linux драйверы для протоколов МЭК 60870-5-104, МЭК 60870-5-101, MQTT, SNMP, работа с ini-файлами, а так же периодический Ping.  Драйверы представляют из себя динамические библиотеки so, которые подключаются при запуске демона.

Так же были переведены на Linux OPC UA серверы некоторых стандартных и не очень протоколов.

Небольшие субъективные выводы, которые я сделал после проделанной работы:

  1. Переводить на Linux приложение без графической оболочки проще, чем с GUI.

  2. Практически любой проект на Delphi без графической оболочки можно перевести на Linux за вполне вменяемые сроки.

  3. Переписать всё с нуля на более модном языке не проще.

Время перевода заняло около полугода. Результат здесь.

И напоследок скриншот: