Проблема создания переносимых приложений возникла не вчера, но если во времена, когда большинство приложений разрабатывались на языке ассемблера, основным фактором, определяющим сложность переноса приложения между платформами, было сходство языков ассемблера соответствующих аппаратных архитектур, то сегодня на первый план выходит проблема стандартизации интерфейсов приложения с операционной системой.
К настоящему времени разработано множество операционных систем, и можно с уверенностью сказать, что лидером по количеству разнообразных вариаций является Linux, однако обеспечение переносимости приложения во многих случаях требует дополнительных трудозатрат. И хотя разнообразие альтернативных операционных систем и различных вариаций одной и той же ОС предоставляет богатый выбор пользователям, это усложняет создание переносимых программ, способных работать на достаточно большом числе платформ.
Один из способов упрощения переноса приложений между различными платформами – стандартизация в сфере интерфейсов взаимодействия операционной системы с приложениями. Следование стандартам API (Application Programming Interface) позволяет осуществлять перенос приложений на новые платформы путем их перекомпиляции, а целью стандартизации ABI (Application Binary Interface) является возможность переноса непосредственно бинарных файлов приложения без изменений. В качестве примеров соответствующих стандартов можно привести POSIX и LSB (Linux Standard Base) – первый позволяет осуществить сборку из исходного кода приложения, использующего только стандартизированные интерфейсы; второй гарантирует успешность запуска и корректность функционирования LSB-совместимого приложения в любой системе.
Тем не менее зачастую оказывается, что при разработке определенного класса систем ориентироваться на один конкретный стандарт не получается – существующие спецификации либо слишком узки и не описывают всех необходимых интерфейсов, либо, наоборот, слишком объемны и содержат много информации, излишней для рассматриваемого класса задач. Так, базовая часть стандарта SUSv2 (Single UNIX Specification Version 2) была рассчитана на широкий класс систем и не описывала многих интерфейсов, необходимых для программ, функционирующих на рабочих станциях и ПК (в частности, GUI). И наоборот, анализ применимости стандарта LSB к системам, работающим на мобильных устройствах, показывает, что в данном случае многие возможности, описанные в LSB, оказываются неактуальными (например, подсистема печати и утилиты администрирования серверов). Однако вести разработку совершенно новых стандартов во многих случаях нецелесообразно, поскольку существующие спецификации уже охватывают большую часть предметной области. В таких ситуациях создаются профили стандартов, опирающиеся на существующие документы, но специфицирующие только те аспекты, которые важны для рассматриваемой предметной области.
Подмножества стандарта востребованы, как правило, при создании узкоспециализированных продуктов – например, предназначенных только для работы на сервере, для обработки мультимедиа либо для установки в мобильных телефонах. Так, при разработке ОС реального времени полезен соответствующий профиль POSIX (IEEE Std 1003.13), а интерфейсы, описанные в других разделах этого стандарта (например, X/Open Curses – функции управления терминалом), в таких системах могут отсутствовать. Иногда необходимо объединить несколько стандартов с целью охвата сложной предметной области, включающей в себя множество разнородных компонентов, для каждого из которых приходится формулировать свои требования. Возможно объединение как стандартов целиком, так и их подмножеств. Например, профиль Carrier Grade Linux включает в себя только две части стандарта LSB – LSB Core и LSB CXX.
Формально стандарт – это текстовый документ, регламентирующий набор требований к объектам стандартизации. Но одного текста, как правило, недостаточно для эффективного использования стандарта целевой аудиторией, особенно если стандарт достаточно велик. Стандарты, стремящиеся соответствовать веяниям времени, специфицируют множество интерфейсов – например, LSB версии 4.0 содержит описания более чем 38 тыс. функций из 57 библиотек. При таком количестве стандартизированных интерфейсов разработчикам приложений зачастую непросто проверить, что их программы используют только разрешенные функции. Для упрощения использования стандартов создаются различные дополнительные компоненты, формирующие окружение стандарта, – вспомогательные инструменты, информационные ресурсы и пр. Так, для многих стандартов (включая POSIX и LSB) доступны их онлайн-версии, сопровождаемые дополнительными материалами и комментариями. Например, LSB Navigator предоставляет информацию об интерфейсах, включенных в LSB, и описание причин отсутствия в стандарте ряда функций (наличие известных проблем с безопасностью, отсутствие обратной совместимости и др.).
Помимо информационных ресурсов, в помощь разработчикам приложений могут предоставляться программные продукты, использование которых позволяет обойти определенные проблемы, возникающие в ходе создания удовлетворяющих стандарту продуктов. Так, для разработки программ, отвечающих требованиям LSB, может быть использован специализированный набор инструментов – LSB Software Development Kit (LSB SDK), применение которого автоматически решает ряд проблем, часто встающих перед разработчиками.
Например, одной из причин несоответствия ряда приложений стандарту LSB является зависимость исполнимых файлов приложений от арифметических функций из libgcc_s, библиотеки поддержки компилятора GCC, которые не входят в LSB. В большинстве современных дистрибутивов Linux такие интерфейсы в libgcc_s присутствуют, и при сборке приложения в этих дистрибутивах могут появиться соответствующие зависимости, лишающие приложение совместимости с LSB. Для решения этой проблемы при сборке приложения можно использовать библиотеку libgcc_s из LSB SDK.
На рисунке приведен перечень ресурсов, предоставляемых производителям дистрибутивов и приложений, ориентирующимся на стандарт LSB.
Все компоненты, образующие окружение стандарта, должны быть согласованы между собой и с текстом стандарта – в частности, добавление и удаление интерфейсов из стандарта должно находить отражение во всех компонентах, где это необходимо. Для поддержания высоких темпов развития стандартов подобное обеспечение согласованности желательно автоматизировать – в противном случае разработка окружения может оказаться более трудоемкой, чем разработка самого стандарта.
Интерфейсные стандарты открытых систем и их профили
Появившись в конце 80-х годов, POSIX изначально описывал базовые системные функции, которые должны быть доступны приложениям. Эта часть стандарта не привязана к конкретной операционной системе или семейству ОС, и в настоящее время ее требованиям удовлетворяют как Unix-системы, так и некоторые редакции Windows (в частности, подсистема Unix встроена в редакции Windows Vista Enterprise и Ultimate). Разработчики glibc (GNU C Library) – основы всех дистрибутивов GNU/Linux – также ориентируются на совместимость с POSIX (хотя ни один из дистрибутивов Linux не проходил формальной сертификации на соответствие POSIX).
Однако функций, входящих в POSIX, для большинства приложений недостаточно: «за бортом» остаются такие области, как графический интерфейс пользователя, мультимедиа и пр. Поэтому консорциум The Open Group в спецификации SUSv2, предшественницы POSIX 2001, служившей основой для сертификации UNIX 98, ввел три профиля:
- UNIX 98 – соответствие базовой части стандарта;
- UNIX 98 Workstation – базовый стандарт, дополненный требованиями к пользовательскому интерфейсу (в основе требований лежали графическая среда Common Desktop Environment и графическая библиотека Motif);
- UNIX 98 Server – дополнительные расширения для поддержки различных сетевых сервисов, а также среды исполнения Java (на тот момент – JRE 1.1).
В отличие от базовой спецификации, многие расширения в профилях Workstation и Server (в частности, CDE, Motif, X11 Window System) ориентированы на Unix-системы.
Среди причин возникновения стандарта LSB было осознание того факта, что общепризнанные спецификации POSIX и Single Unix Specification слишком узки – попытка охватить большое количество систем (родственных, но все-таки достаточно далеких друг от друга) привела к тому, что многие широко используемые функции и команды либо вовсе не попали в спецификации, либо стандартизованной оказалась лишь небольшая часть их возможностей. С другой стороны, многие требования расширенных профилей Unix 98 не выполнялись в дистрибутивах Linux – например, отсутствовала свободная реализация среды CDE.
Первоначальной целью Free Standards Group, занимавшейся созданием LSB, была разработка профиля-расширения базовой части POSIX, ориентированного только на дистрибутивы Linux. В результате появилась спецификация LSB Core, описывающая порядка трехсот функций, не входящих в POSIX, а также дополняющая описания многих функций из POSIX деталями, специфичными для Linux (например, расширяя наборы допустимых значений входных параметров и описывая поведение функции при таких параметрах или определяя дополнительные коды ошибок).
Дальнейшим развитием LSB стало включение в спецификацию функций стандартной библиотеки C++, а также библиотек графического интерфейса пользователя, входящих в стеки Gtk+ и Qt. При этом для версий LSB 3.x дистрибутивам предоставлялась возможность сертификации на соответствие одному из трех профилей стандарта – Core, Core & C++ и Core & C++ & Desktop (последний профиль соответствует всему стандарту, а первые два являются его подмножествами). В LSB 4.0 такое разделение на профили было удалено, однако были добавлены опциональные требования, нарушение которых не препятствует получению сертификата.
Разработчики LSB по-прежнему ориентируются на существующие спецификации – если некоторая функция уже описана в каком-либо документе, то в LSB публикуется не ее описание, а только ссылка на документ. В роли подобных документов могут выступать другие стандарты и документация, предоставляемая разработчиками библиотек (при условии, что она достаточно подробна и полна), например, для большинства функций Qt и Gtk стандарт LSB ссылается на соответствующие справочные руководства. Всего LSB 4.0 содержит ссылки более чем на 100 спецификаций.
Еще одна особенность LSB происходит из того, что объектом стандартизации являются различные аспекты ABI, но поскольку многие аспекты ABI специфичны для конкретных аппаратных платформ, то для каждой платформы требуется своя версия стандарта (начиная с версии 3.2 LSB поддерживает семь аппаратных архитектур: x86, x86-64, IA64, PPC32, PPC64, S390 и S390X). Все семь версий имеют много общего – пересечение составляет порядка 90%, поэтому для облегчения работы со стандартом требования, общие для всех платформ, выделяются в отдельную спецификацию LSB Generic Specification.
Параллельно с работами по развитию LSB, проводимыми Free Standards Group, шло создание других спецификаций и профилей, нацеленных на специализированные дистрибутивы Linux, используемые в определенных сегментах рынка. Так, организацией Open Source Development Labs (OSDL) был разработан профиль стандартов Carrier Grade Linux (CGL), определяющий требования, которым должен удовлетворять дистрибутив Linux, чтобы считаться системой класса carrier grade (в телекоммуникациях этим термином обозначают продукты, отличающиеся высокой надежностью и малым временем восстановления после сбоя). Последняя версия профиля, CGL 4.0, выпущенная в июне 2007 года, объединяет требования более чем тридцати стандартов и спецификаций, основными из которых являются LSB 3.0, POSIX 2001 и различные запросы комментариев (Request for Comments, RFC), в частности требования к реализациям протоколов IPv6, IPSec, SCTP и др. В начале 2007 года FSG и OSDL объединились, образовав консорциум The Linux Foundation, под эгидой которого теперь ведется разработка LSB и CGL.
Попытки создания спецификаций предпринимались и в области встроенных и мобильных устройств, например, в 2002 году консорциум Embedded Linux Consortium разработал соответствующий профиль на основе LSB 1.2, POSIX 2001 и SUSv3. Из активно развивающихся открытых спецификаций для мобильных платформ стоит выделить LiMo Platform Specification, созданием которой занимается LiMo Foundation (помимо спецификации она разрабатывает и реализацию этой платформы), а также спецификацию для мобильной платформы Moblin, разрабатываемой Linux Foundation посредством расширения LSB. Из таблицы можно понять масштабы работ, проделанных в области стандартизации LSB.
Инфраструктура LSB
LSB является одним из самых крупных на сегодня открытых интерфейсных стандартов и помимо непосредственно текста имеет набор сопутствующих продуктов: сертификационные тесты, LSB Navigator, LSB SDK и др. Кроме того, для эффективной разработки и поддержки стандарта LSB и семейства сопутствующих продуктов Linux Foundation совместно с Центром верификации ОС Linux (linuxtesting.ru) при Институте системного программирования РАН ведет разработку специализированной инфраструктуры, позволяющей автоматизировать существенную часть задач. Основой инфраструктуры является база сведений о стандартизированных интерфейсах (функции и их сигнатуры, состав типов данных и др.), а также различная вспомогательная информация, используемая компонентами окружения LSB (например, причины, по которым тот или иной интерфейс не включен в стандарт, хотя рассматривался в качестве кандидата). Информация для базы собирается с помощью автоматизированных инструментов посредством анализа библиотек и заголовочных файлов дистрибутивов Linux, а также документации к библиотекам от их разработчиков.
Сведения из базы используются для автоматической генерации частей различных компонентов окружения LSB (в частности, заголовочных файлов и библиотек-заглушек LSB SDK, а также некоторых тестовых наборов) и даже частей текста стандарта (например, перечней библиотек и предоставляемых ими функций). Автоматизация рутинных, но ресурсоемких задач позволяет осуществлять поддержку и развитие целого ряда продуктов (SDK, Navigator, наборы тестов libchk, cmdchk и др.) силами нескольких инженеров.
Члены рабочей группы, занимающейся развитием стандарта, могут либо обращаться непосредственно к базе данных LSB, либо использовать аналитические инструменты, встроенные в Web-систему LSB Navigator. При этом все, что требуется сделать для включения определенного интерфейса в стандарт, – это пометить его соответствующим образом в базе данных. После этого происходит автоматический анализ зависимостей нового интерфейса, и сущности, необходимые для полноты спецификации (например, типы, используемые в качестве параметров новой функции), также добавляются в стандарт (естественно, члены рабочей группы получают отчеты о таких автоматически добавленных элементах).
Навигатор полезен не только членам рабочей группы LSB, но и разработчикам, использующим LSB на практике, для них LSB Navigator предоставляет «интерактивную» версию стандарта, дополненную вспомогательной информацией и комментариями. В частности, для каждой функции, входящей в стандарт, можно увидеть ее сигнатуру, данные о ее присутствии в различных дистрибутивах и использовании в приложениях, а также получить ссылку на непосредственное описание поведения функции.
Данные об интерфейсах, предоставляемых различными дистрибутивами, а также используемых приложениями Linux, необходимы для определения дальнейшего направления развития стандарта – на основе этих данных выделяются наиболее востребованные и распространенные библиотеки и функции, которые желательно стандартизировать в первую очередь, а также устаревающие и выходящие из употребления интерфейсы, вместо которых следует предлагать более совершенные аналоги. Наличие автоматизированных средств поддержки такого анализа позволило при создании LSB 4.0 обработать сведения обо всех версиях дистрибутивов 12 различных производителей, выпущенных за последние четыре года, и более чем о тысяче приложений.
Инфраструктура позволяет автоматизировать формирование профилей на основе стандарта LSB, для чего в схеме базы данных введена специальная сущность, каждый экземпляр которой соответствует конкретному профилю. Индикатором того, что некоторый интерфейс включен в профиль, служит наличие связи между этим интерфейсом и соответствующим экземпляром сущности. Более того, если профиль формируется согласно некоторым формальным правилам, то эти правила можно заложить в инструменты, работающие с базой данных, с целью автоматического выделения профиля. Например, текущий инструментарий производит автоматическое отслеживание интерфейсов, включенных в спецификации для всех семи поддерживаемых архитектур, и добавляет их в спецификацию LSB Generic.
Отметим, что база данных LSB используется не только для разработки самого стандарта и связанных с ним продуктов – информация о существующих дистрибутивах Linux востребована при анализе совместимости конкретных приложений с конкретными дистрибутивами. Возможность проведения подобного статического анализа (не требующего запуска приложений) предоставляется инструментом Linux Application Checker, разработку которого также ведет Linux Foundation совместно с ИСП РАН.
Денис Силаков (silakov@ispras.ru) – соискатель степени кандидата физико-математических наук, ведущий разработчик ИСП РАН (Москва).
Рисунок. Структура сетевого ресурса для разработчиков компонентов и приложений Linux (Linux Development Network, ldn.linuxfoundation.org)
Таблица. Функции и размер их описаний в различных спецификациях
Cервис для кампуса ННГУ
Система LIST дает возможность студентам, сотрудникам и гостям кампуса Нижегородского государственного университета получать всю необходимую информацию о деятельности вуза. LIST позволяет ориентироваться на территории кампуса, узнавать расписание занятий и экзаменов, адаптирована к особенностям компактных мобильных устройств, содержит личные страницы студентов и сотрудников ННГУ, а также доски объявлений, форумы и чаты, тематические новостные каналы. Система разработана лабораторией физических основ и технологий беспроводной связи ННГУ в рамках академической программы компании Intel.
Программирование с помощью картинок
В исходном коде программ на графическом языке Sikuli, созданном в Массачусетском технологическом институте, могут встречаться не только обычные для языков программирования выражения и ключевые слова, но и изображения. Авторы нового языка считают, что некоторые задачи, например по автоматизации тестирования пользовательского интерфейса или поиску информации в базе данных, проще выполнять с помощью визуальных средств. Sikuli использует алгоритмы распознавания текста и индексации изображений с помощью «визуальных слов». Встроенные функции языка принимают в качестве параметров графические данные. Можно представить, например, команду для поиска на карте города нужного перекрестка: street_corner=find( ). Внутри скобок программист помещает фрагмент, который нужно отыскать на большой карте, выдаваемой сторонней программой. Предположим, что такая программа динамически отображает на карте положение городского автобуса, и тогда можно написать простую программу на языке Sikuli, которая будет следить, когда изображение автобуса появится на карте в границах найденного фрагмента.