Статья
Версия для печати
Обсудить на форуме
Delphi, кроссплатформенность... Lazarus?

Вводная

О кроссплатформенности можно говорить очень много, и большая часть сказанного выйдет далеко за рамки этой статьи. Поэтому отметим лишь один неоспоримый факт: всё больше и больше компаний по разным причинам задумываются о переходе на другие платформы. И в последние годы среди этих компаний начинают появляться достаточно серьёзные организации, в том числе федерального уровня. Понять функционеров всевозможных ФГУПов довольно просто: представьте себе, сколько сэкономит, например, Сбербанк, заменив все свои Windows-системы на POSIX в масштабах страны с населением более ста миллионов. С точки зрения администратора, ничего невозможного в этом нет, вопрос, как говорится, технический. А вот разработчик оказывается перед, мягко говоря, нетривиальной задачей. И не потому, что под Linux невозможно написать то, что написано под W32. А потому, что под W32 это уже написано. И задача сводится к тому, чтобы, по сути, написать с нуля достаточно сложный функционал, идентичный существующему, с сохранением данных, интерфейсных решений, совместимости с оборудованием и др. И если когда-нибудь тому же Сбербанку придёт в голову во всех сберкассах поставить Linux, кому-то придётся писать тот же самый софт, уже работающий под Windows, для расчётов с клиентами, приёма / оплаты коммунальных услуг, ведения кредитных договоров, и многого-многого другого. Всю сложность подобной задачи понимают не только программисты, но и сами заказчики. И поэтому не приходится удивляться, когда заказчик хочет не просто программу, а программу, которую он сможет безболезненно перенести на любую нужную ему платформу в ближайшей перспективе.
Да, можно, наверное, написать на Java апплет, работающий с фискальным регистратором, к примеру, и позиционировать его как кроссплатформенное решение. Но как-то исторически сложилось, что для работы с железом используются языки иного класса: такие, как C или Pascal. И вот здесь, есстественно, в голову приходит простая мысль - а вот хорошо бы писать под все платформы сразу. Технически это возможно уже сейчас, есть решения и помимо вышеупоминавшейся Java. И думается мне, что именно эта категория специалистов будет одной из наиболее востребованных в ближайшем будущем - а именно, специалистов, создающих платформенно-независимые системы. Весь вопрос в том, как именно эти системы создаются.
Подход, используемый в Java, наверное, можно считать классическим - платформенно-зависимый интерпретатор исполняет единожды скомпилированный платформенно-независимый код, причём скомпилирован он мог быть на любой платформе. Собственно, кроссплатформенность Java достигается именно за счёт того, что программа работает не в самой среде, а в специально написанной для этой среды виртуальной машине. Сегодня речь пойдёт о принципиально ином подходе, также обеспечивающем кроссплатформенность, но, скажем так, по своему :) Автор не может сказать, что этот подход лучше или хуже, он просто другой и в ряде случаев может представлять определённый интерес.

Немного истории

Поскольку Lazarus изначально создавался как среда для компилятора FPC, начнём с самого компилятора. На заре веков FreePascal был известен как FPK Pascal, по первым буквам имени своего творца, которого звали Florian Paul Klampfl. Но поскольку многие упорно расшифровывали эту аббревиатуру, как Free Pascal Kompiler (что не совсем грамматически правильно), позже решено было переименовать проект в FPC - Free Pascal Compiler. Несколько лет назад, когда в какой-то момент многим показалось очевидным, что Borland не собирается выпускать Delphi 8, Florian Paul Klampfl (будучи студентом!) начал собственный проект. Он основывался на Turbo Pascal 7.0, среда имела 16-ую архитектуру, и в скором времени стала позволять писать для одного из расширений ДОС. 32-х битная версия компилятора была выложена в сеть и у многих вызвала интерес. Потому что была бесплатной, с открытыми исходными кодами, на знакомом многим диалекте Pascal. За пять лет до появления на рынке Kylix, Michael van Canneyt портирует FreePascal на Linux. В 2003 году, после выхода версии 1.0.х, работавшей к тому времени в Windows (Win16 и Win32), ряде POSIX-систем и на платформе AmigaOS, в среду начинают активно добавляться многие функции и возможности Delphi. На сегодняшний день Lazarus декларирует 90% совместимость с наиболее распространёнными диалектами Pascal: turbo и object, а свободном доступе имеются версии 2.2.х (stable release) и 2.3.х - (development release).

Примерно в тоже время, т.е. в конце 90х, три человека основали проект по имени Megido. Их звали: Cliff Baeseman, Shane Miller и Michael A. Hess. Проект просуществовал недолго и был закрыт.
Offtopic:
Если вы зарегистрируетесь на сайте lazarus.freepascal.org, к вам придёт письмо с подтверждением регистрации. Обратите внимание на адрес, с которого придёт это письмо - mhess[at] miraclec.com. Это и есть Michael A. Hess, последний из стартовой лихой троицы, оставшийся в проекте на сегодняшний день
В 1999г. эти же трое собираются вновь и предпринимают вторую попытку написать бесплатную среду для бесплатного компилятора. Вторая версия проекта получает название Lazarus, по аналогии с библейским Воскрешением Лазаря. На сегодняшний день следует признать, что вторая попытка оказалось гораздо более плодотворной, потому что среда существует и развивается и поныне.

Эти краткие сведения были приведены с одной целью: показать, что как FPC, так и Lazarus - это не однодневные мотыльки, пишушиеся на коленке полутора калеками, а проекты, насчитывающие практически десяток лет. Ну а сейчас давайте "пощупаем" своими руками всё то, о чём говорилось выше.


Free Pascal Compiler - краткий обзор

Как уже говорилось, Lazarus представляет собой IDE (позиционирующееся, как RAD - Rapid Application Development) для FPC. Но сам по себе Free Pascal Compiler заслуживает более чем пристального внимания. Приведу только некоторые из характеристик FPC 2.2.0.

  • Минимальные требования
    • i386, x86_64, PowerPC или Sparc процессор
    • Win32:
      • Win95/98/Me/2000/XP или WinNT
      • 16 MB RAM
    • OS/2:
      • OS/2 Warp v3.0 с фикспаком FP 35 и выше
      • OS/2 Warp v4.0 с фикспаком FP5 и выше, с поддержкой WSeB, MCP или любой версии eComStation
      • (OS/2 2.0/2.1 - не поддерживаются, программы, скомпилированные под Warp - не запустятся)
    • Linux:
      • Любой дистрибутив на кернеле от 2.2.х
    • FreeBSD:
      • FreeBSD 4.x или 5.x с установленным COMPAT 4 (что есть дефолт)
    • Mac OS:
      • Mac OS X 10.2 или выше
      • Mac OS 9.2 (classic) - тестировалась, по идее, пойдёт от 7.5.3 и выше
  • Доступные платформы:
    • Linux-i386
    • Linux-x86_64 (amd64)
    • Linux-arm
    • Linux-powerpc
    • Linux-sparc
    • Win32-i386 (Win95/98/Me/XP/2000/Vista and WinNT)
    • Win64-x86_64 (XP/Vista)
    • Wince-arm (cross compiled from win32-i386)
    • FreeBSD-i386
    • Mac OS X/Darwin for PowerPC
    • Mac OS X/Darwin for Intel (i386)
  • Программные возможности:
    • Распространяется с исходными кодами на условиях GPL. Может перекомпилировать сам себя (в Lazarus, кстати, именно так ставятся новые пакеты компонентов)
    • Поддержка 32-х и 64-х битных архитектур
    • Условная совместимость с Turbo Pascal, Object Pascal и Delphi Pascal
    • Поддержка ANSI и WIDE строковых типов
    • Поддержка исключительных ситуаций
    • Поддержка RTTI (Runtime Type Information)
    • Перегрузка операторов и процедур
    • Поддержка COM, CORBA и интерфейсных типов
    • Динамические массивы и варианты
    • Инлайн-код
    • Встроенный парсер ассемблера
    • Возможность компилировать код в исходные коды следующих ассемблеров:
      • Gnu ассемблер (GAS)
      • Netwide ассемблер (Nasm)
      • Microsoft / Turbo ассемблер (Masm/Tasm)
      • Watcom ассемблер (WASM)
    • Встроенный вызов внешнего C-кода (в дитрибутив входит утилита для переконвертации хидеров (*.h файлов) в модули Pascal)
    • Встроенный отладчик для большинства платформ (также поддерживается GNU-debugger)
    • Компилируемый бинарный файл является "родным" для той платформы, на которой он был скомпилирован, и может быть запущен на любом дистрибутиве Linux без создания установочного пакета
    • И многое другое :)

Остаётся добавить, что FPC имеет собственное IDE, больше всего напоминающее старый добрый TP7.0.:


Как и Turbo Pascal, FPC включает ряд примеров, от простых задач до создания виндовых (или, если хотите, gtk-шных) приложений.

Ещё раз повторюсь, чем принципиально отличается религия FPC от религии Java. Программа, скомпилированная на FPC для определённой среды, является родной для этой среды. И она будет работать без каких бы то ни было интерпретаторов, виртуальных маших, установочных пакетов и пр. (при желании, конечно, ничто не запрещает сделать и установочный пакет). Следует также отметить забавную возможность так называемой кросс-компиляции, т.е. сидя, например, под Ubuntu, можно в качестве target-платформы установить Мак Ос. Но об этом поговорим чуть ниже.

На среду разработки, обладающую подобными характеристиками, уже нельзя смотреть как на чьё-то сиюминутное баловство, и, в общем-то, не удивительно, что форумы FPC насчитывают тысячи пользователей. Но разработчику, привыкшему к Delphi и в глаза не видевшему Turbo Pascal, это IDE, конечно, покажется убогим. И вот здесь на сцену выходит Lazarus.

Lazarus глазами разработчика

Для данной статьи использовалась сборка v0.9.24 beta. Список платформ, поддерживаемых Лазарусом, намного скромнее аналогичного у FPC, но в нём по-прежнему красуются Windows, Linux & Mac OS.
При первом запуске мы увидим знакомые, в общем-то, окна среды: те же самые MainIDE, Object Inspector, Source Editor, Message Window и т.д. "Дельфин" ничего принципиально нового для себя не увидит, поэтому перейдём непосредственно к самому интересному: палитре компонентов:


По предоставляемому функционалу слегка напоминает Delphi 2, но уже сразу радует наличие TActionList и включенный в состав SynEdit. Элементы привычных страниц Standard, Additional, Common Controls (аналог Win32 - тулбары и пр.) практически идентичны. Standard отличается только отсутствием фрэймов (да и слава Богу), Additional потерял ActionManager и связанные с ним приблуды для создания XP тем (тоже невелика потеря), Common Controls и Misc примерно соответствуют дельфийскому Win32: деревья, списки, Page и Tab control'ы, полосы прокрутки, статусбар и др. Что-то, по сравнению с Delphi, отсутствует, а что-то и появилось (например, TButtonPanel - четырёхкнопочная панелька для диалогых окон с настраиваемыми педалями "Справка", "Закрыть", "Ок" и "Отмена"). Вкладки диалогов также практически идентичны. В целом, что касается стандартных (читай - виндовых) элементов управления, Lazarus практически не уступает Delphi.

Собственно говоря, учитывая темпы развития открытого ПО, не стоит ужасаться, если вы не обнаружили своего любимого компонента. Рано или поздно он сам, либо его аналог, появятся. Так, например, широко известная компания Nevrona портировала под Lazarus весь пакет Indy (за что ей горячее спасибо), силами энтузиастов был написан пакет FBL, предоставляющий функциональность, аналогичную хорошо знакомым FIB-ам, и т.д. Всё это, как и многое другое, легко найти в сети за 5 минут, и ставится оно, как правило, без явных проблем. Конечно, любителям DevExpress, FastReport 4. EhLib и других платных (закрытых) библиотек при портировании проектов может прийтись очень туго. Безусловно, неудобства есть. Но бесплатность и открытость кода, возможность использовать его в коммерческих разработках на законных основаниях, возможность портировать собственные приложения на самые популярные платформы - всё это способно с лихвой окупить и не такие неудобства.

Однако, всё это болтология. Как и подобает истинным программистам, давайте отложим подальше всевозможные мануалы, справочники, readme-файлы и статьи из Википедии, и попробуем тупо написать программу. И попытаться на основе единожды написанного кода родить два бинарника: для Linux и Windows. И оценить, в какие нервы и усилия нам это обойдётся и что вообще из этого получится. Одним словом, попытаемся воплотить в жизнь слоган Лазаруса: "Write once - compile everywhere!".  Писать будем что-нибудь простенькое, например, виндового Сапёра, т.к. сейчас главное - это убедиться в принципе в том, что Лазарус действительно позволяет писать программы под разные ОС.

Процесс разработки практически неотличим от разработки в привычных Delphi, хоть и происходит он (в моём случае) на Linux. Поэтому я просто приведу несколько скриншотов. Как сказала бы CNN, вас приветствует рубрика "No Comments".



Касательно нашей мегаигры, скажу, что она представляет собой упрощённый донельзя Сапёр. Размер поля - 10х10, количество мин - 10, игрок выигрывает, если количество закрытых клеток равно количеству мин (т.е. он открыл все возможные 90 клеток), и проигрывает - если открыл мину. Скриншот мегаигры приведён ниже:


Тут нас ждёт первый сюрприз. Как вы считаете, сколько весит программа, состоящая из одной формы, на которой лежит один компонент (TStringGrid)? В нашем случае программа весит > 16 мегабайт. Чудовищные размеры исполняемых файлов побудили разработчиков включать в дитрибутив специальные упаковщики (аналоги виндового ExePack и ему подобных). Но в наше время размер программы не так уж и критичен, так что продолжим эксперименты. Сразу скажу, что с задекларированной "кросс-платформенной" компиляцией всё обстоит совсем не так просто. Нет, компилятор FPC действительно позволяет задать target в качестве входящей опции. Но в создании бинарника участвует не только компилятор, - это только "первый шаг". Ещё есть сборщик (assembler) и линкер (собственно - linker). И если сам по себе FPC умеет генерировать машинный код под нужную платформу, то сборщик с линкером - всегда платформо-зависимы. Конечный бинарник, который мы получаем после компиляции - это ведь не только то, что мы написали. Более того, это в основном не то, что мы писали. И для того, чтобы этот бинарник получить, понадобится предпринять ряд телодвижений. Сводятся они к тому, чтобы перекомпилирировать системные файлы FPC (и не только - LCL (Lazarus Component Library - аналог VCL) тоже придётся перекомпилировать), а также ряд бинарных файлов (binutils). На деле всё это не так страшно, но полдня на всё это угробится смело. Поэтому описывать здесь этот чудный процесс я не буду, скажу только, что кросс-компиляция может сработать :).
Мы пойдём более простым путём. Скачаем Лазарус для Win32, установим его, запустим под Wine, и уже в нём скомпилируем нашу мегаигру. Особо расписывать тут нечего, единственное: иногда может понадобиться поменять дефолтовые пути Лазаруса к библиотекам (работая под Wine, он будет продолжать искать диск С и т.д.). Сама компиляция также проходит тривиально: переименовываем текущий бинарник игры, открываем проект, компилируем, закрываем. И имеем два бинарника - для Linux и для Windows.

Собственно говоря, ничто не мешает сделать и наоборот. Под Windows поднять виртуальную машину, установить на неё *.nix, и компилировать под *.nix свои виндовые проекты. Ну, а желающим всё-таки разобраться с кросс-компиляцией, можно посоветовать обратиться к Википедии (которая существует как для Лазаруса, так и для FreePascal'а), где этот процесс подробно описан, причём для разных платформ (в том числе MacOS и WinCE). Получить экзешник под Mac OS мешает только отсутствие под рукой самой Mac OS. Можно считать, что в принципе мы поставленную задачу решили. Но на нормальных проектах наверняка будут нюансы. Например, я совсем не уверен, что русские буквы, нарисованные в Linux (т.е. на UTF-8) нормально отобразятся под Windows (т.е. в cp1251). Наверняка, будут и другие приколы. Важно тут, на самом деле, не это. Важен сам факт, что мы получили два исполняемых файла под разные ОС на основе одного и того же исходного кода.

Заключение

"В чём же подвох?", - спросит опытный менеджер или программист. И будут абсолютно правы, потому что если бы всё было так чудесно - компания Борланд уже давно пошла бы по миру, а Нортон доедал в углу свой последний носок. Главный подвох Лазаруса в его неимоверной глючности. Листая исходные коды легко увидеть, что в некоторых местах IFDEF-ов намного больше, чем самих исходных кодов, что крайне затрудняет отладку платформенно-зависимых участков кода. В любой момент среда может встать раком на совершенно ровном месте, например, при запуске диалога на выбор файла. Причём после того, как вы пересоберёте сам Лазарус под другой widget-set (да, возможно и такое ;)), диалог отработает вполне благополучно. Может ни с того ни с сего перестать отрисовываться мемо-поле в design-time. Работая под Linux, Лазарус может решить, что он запущен под Windows, и примется горько плакать, не находя *.res - файлов. И многое, многое другое. Удивительный мир Лазарусовских багов непознаваем, безграничен и ждёт своих первооткрывателей. О нём можно говорить часами.

В защиту Лазаруса следует привести то, что за вот уже три месяца плотной работы под этой средой я не встретил ни одного "фатального" бага, который нельзя было бы исправить или обойти. Кроме того, глючность Лазаруса - это глючность именно Лазаруса, сам  компилятор FPC по своей стабильности сравним с компилятором Борланда. А что касается доработок самой среды, то они ведутся. Не удивлюсь, если ситуация в корне изменится буквально через несколько лет.

Вторая причина довольно скромной позиции Лазаруса в профессиональных средах заключается в его... неизвестности. Как и многие open-source проекты, Лазарус практически не занимается рекламой. Вы когда-нибудь видели баннер со слоганом "Write Once Compile Everywhere"? Вам на почту сваливался спам о пресс-конференции, даваемой разработчиками Лазаруса? Полное, и, может быть, где-то даже сознательное отсутствие какого бы то ни было маркетинга превращает эту мощную среду в тёмную лошадку, о которой многие где-то краем уха слышали, но не слышали ничего, важного настолько, чтобы поставить себе эту среду и взглянуть на неё собственными глазами. А она того,  безусловно, стоит. И не среда сама по себе, а открываемые ею возможности.

Ссылки

Free Pascal - официальный сайт
Lazarus IDE - официальный сайт
Вики - Lazarus & FreePascal

Игра::Исходники
Игра::Linux executable
Игра::Win32 executable

x77 (Юргелевичюс Игорь), 03/07/2008
Версия для печати
Обсудить на форуме