Всем привет. Это снова мы — тимлид Mobile SDK в 2ГИС Александр Максимовский и Flutter-разработчик @Sameri11 Михаил Новосельцев. В предыдущих двух статьях мы рассказывали, как наша команда успешно разработала Flutter Mobile SDK для Android и iOS (часть 1, часть 2). Вслед за этим мы пошумели в СМИ, так как встроились и в новую российскую операционную систему — Аврору. В этой статье расскажем про технические детали адаптации.
ОС Аврора
Истоки ОС Аврора уходят в мир Linux. Когда-то компания Nokia разрабатывала собственную мобильную платформу на базе Linux, но проект был свёрнут. Его идеи продолжили энтузиасты, создавшие Sailfish OS. С 2012 года на базе открытых компонентов Sailfish началась работа над российской операционной системой Аврора, которую развивает компания «Открытая мобильная платформа».
За последние годы Аврора заметно эволюционировала: в её коде появилось множество решений и закрытых модулей, что отличает её от исходной Sailfish. Пятая версия системы, вышедшая в 2024 году, ориентирована не только на корпоративный сектор, но и на массового пользователя. Среди ключевых нововведений:
переработанная система управления жестами,
полноценная поддержка планшетов,
расширенные возможности персонализации,
переход на 64-битную архитектуру,
и повышенная устойчивость к внешним сбоям.
Экосистема Авроры продолжает расти: сейчас в официальном каталоге насчитывается более 150 приложений, среди которых как корпоративные инструменты, так и сервисы для частных пользователей — например, приложения для работы с госуслугами, банковские клиенты и офисные пакеты. С запуском отечественного магазина приложений RuStore процесс установки стал значительно проще: теперь пользователи могут находить и устанавливать нужные программы напрямую, без необходимости обращаться к представителям компаний.
Тем не менее, Аврора по-прежнему делает ставку на безопасность: для доступа к ряду корпоративных приложений требуется индивидуальная авторизация, что обеспечивает высокий уровень защиты данных. Хотя экосистема ещё формируется, уже сейчас можно говорить о серьёзном прогрессе в развитии платформы и её интеграции в российский IT-ландшафт.
Использование Flutter
Разработка под Аврору сегодня напоминает ранние этапы других мобильных платформ, но уже с учётом накопленного опыта индустрии. У операционной системы сформировалась собственная экосистема инструментов. Для создания приложений по-прежнему можно использовать C++ и Qt/QML — это обеспечивает высокую производительность и эффективное использование ресурсов устройства. Основным инструментом для нативной разработки остаётся Aurora IDE, основанная на QtCreator.
Однако за последний год экосистема Авроры заметно расширилась. Благодаря усилиям сообщества и поддержке разработчиков, появились стабильные решения для кроссплатформенной разработки: теперь официально поддерживаются Flutter и Kotlin Multiplatform. Это позволило привлечь больше разработчиков и упростить портирование существующих приложений.
Мы рассмотрели разные варианты и пришли к выводу, что оптимальным выбором для нашей команды стал Flutter:
У нас уже есть готовый Flutter Mobile SDK под другие операционные системы. Flutter позволяет быстрее создавать современные интерфейсы и поддерживать единую кодовую базу для разных платформ, что особенно важно в условиях ограниченных ресурсов.
На этом фреймворке сейчас разрабатывает гораздо больше специалистов, что облегчает поиск новых членов команды и обмен опытом.
После выбора подходящего фреймворка для внедрения нашего функционала в ОС Аврора, нам оставалось лишь реализовать необходимый платформенный функционал на Qt, а также разработать новый плагин для интеграции с компонентами приложений на Flutter.
Кросс-компиляция с использованием Clang и CMake
По умолчанию в Авроре рекомендуется установка Platform SDK (PSDK) и Flutter SDK — это основные инструменты для разработки. Официально поддерживаемая архитектура — x86_64.
Традиционная сборка проектов с использованием PSDK не предполагает кросс-компиляцию и базируется на инструментах GNU для компиляции и линковки программ и библиотек. Однако в нашем случае этот подход оказался непригодным по следующим причинам:
Использование Clang
В проекте активно применяются специфические возможности компилятора Clang, включая аннотации для кодогенератора. Это потребовало перехода на Clang в качестве основного компилятора. К счастью, как указано в официальной документации LLVM, Clang изначально разрабатывался с поддержкой кросс-компиляции и нативно её поддерживает.QEMU
При сборке под архитектуру, отличную от хостовой, использовался QEMU. Это решение позволяло запускать сборку, но драматически увеличивало её продолжительность — с десятков минут до десятков часов.Сложности с CI
Возникали трудности при сборке внутри Docker-контейнеров, используемых в системах непрерывной интеграции (CI). Это требовало дополнительных усилий по настройке окружения и усложняло автоматизацию.
Основные требования для кросс-компиляции
Для кросс-компиляции недостаточно одного только компилятора — также необходим слепок целевой файловой системы (rootfs). Он содержит все необходимые библиотеки и заголовочные файлы, соответствующие целевой платформе.
ОС Аврора предоставляет rootfs в составе Platform SDK, а также в виде отдельного таргета. Мы выбрали второй вариант, поскольку он не включает лишние зависимости, не требующиеся на этапе сборки, и позволяет упростить окружение.
После получения rootfs, его путь, имя таргета и некоторые другие параметры необходимо передать Clang'у. Простейшая команда компиляции может выглядеть так:
clang --target=aarch64-meego-linux-gnu --sysroot=<путь_до_таргета_x86_64-meego-linux-gnu>
Всё это — базовые параметры, необходимые для запуска кросс-компиляции. В зависимости от архитектуры могут потребоваться дополнительные флаги, такие как -march
(для указания архитектуры процессора) или -mtune
(для оптимизации под конкретный CPU), но ключевыми остаются --target
и --sysroot
. Подробнее об этом можно прочитать в официальной документации Clang.
Автоматизация кросс-компиляции с CMake
Разумеется, в реальных проектах вручную указывать флаги компиляции — не вариант. Для управления сборкой мы используем CMake, который поддерживает кросс-компиляцию с помощью так называемых тулчейн-файлов (toolchain files).
Для этого создаётся файл toolchain.cmake, в котором задаются все необходимые параметры кросс-компиляции. Подробную информацию можно найти в официальной документации CMake, но ниже приведены ключевые переменные, которые необходимо определить:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_SYSROOT <путь_до_rootfs>)
set(CMAKE_C_COMPILER_TARGET aarch64-meego-linux-gnu)
set(CMAKE_CXX_COMPILER_TARGET aarch64-meego-linux-gnu)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Поясним ключевые моменты:
CMAKE_SYSTEM_NAME
— указывает тип целевой ОС. В нашем случае — Linux.CMAKE_C_COMPILER и CMAKE_CXX_COMPILER
— путь к компиляторам Clang.CMAKE_SYSROOT
— путь к rootfs, который будет передан во флаг --sysroot.CMAKE_<LANG>_COMPILER_TARGET
— имя таргета, передаваемое во флаг --target.CMAKE_FIND_ROOT_PATH
— путь, по которому будут искаться библиотеки и заголовки.CMAKE_FIND_ROOT_PATH_MODE_*
— определяют, где искать программы, библиотеки и заголовки: на хосте или в rootfs.
Такой подход позволяет CMake корректно находить нужные зависимости и собирать проект под целевую платформу.
Для запуска сборки достаточно передать путь к тулчейн-файлу при вызове CMake:
cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake ..
Особенности и нюансы
Если в проекте используются сторонние системы управления зависимостями, такие как Conan, или альтернативные системы сборки (например, Autotools), могут потребоваться дополнительные настройки. Однако базовые принципы остаются прежними: необходимо корректно указать sysroot, target и пути к зависимостям.
Что мы получили
Переход на Clang и кросс-компиляцию дал нам ряд преимуществ:
Совместимость с кодом — мы смогли использовать Clang-специфичные фичи, без которых наша библиотека не собиралась.
Скорость сборки — отказ от QEMU позволил ускорить процесс до нативной скорости. Также мы можем использовать инструменты ускорения сборки, такие как ccache и distcc, поскольку они работают на хосте без виртуализации.
Унификация CI/CD — мы используем те же компиляторы и инструменты, что и для сборки под десктоп, что позволяет переиспользовать существующую инфраструктуру CI практически без изменений.
Если вы также сталкиваетесь с необходимостью кросс-компиляции под Аврору или другую Linux-платформу, то Clang и CMake — отличное сочетание, которое позволяет гибко и удобно настроить процесс сборки.
Взаимодействие с платформенной частью ОС
Общая структура Flutter Mobile SDK под ОС Аврора аналогична решениям под iOS и Android.

Различие заключается в платформенной части, которую вызывает C++ код. Для ОС Аврора она реализована в виде C++ библиотек, преимущественно использующих стандартные модули Qt. Ядро нашего SDK также написано на C++, что упрощает взаимодействие и не требует дополнительных обвязок, как например, в Android, где для платформенного взаимодействия используется JNI.
Для полноценного функционирования и взаимодействия ядра Flutter Mobile SDK с ОС Аврора, необходимо реализовать следующие ключевые компоненты, которые обеспечивают доступ к системным возможностям:
Позиционирование. Для определения географического положения устройства используется QGeoPositionInfoSource.
Сенсоры. Для доступа к аппаратным датчикам устройства задействуются специализированные модули Qt: QCompass (для компаса), QAccelerometer (для акселерометра), QGyroscope (для гироскопа) и QMagnetometer (для магнитометра).
Аудио. Управление воспроизведением звука в приложении осуществляется через QAudioOutput.
Пути до стандартных директорий. Для доступа к стандартным системным путям (например, к папкам документов или файлам загрузки) используется QStandardPaths.
Локаль. Для определения текущей локали используется QLocale.
Сеть. Для выполнения HTTP-запросов и обмена данными по сети используется curl, а для мониторинга и управления состоянием сетевых соединений — QNetworkConfigurationManager.
Отображение карты: Texture + PixelBuffer
Для отображения карты используется Texture — виджет для отображения текстуры, полученной с платформы. Подробнее про устройство MapWidget и использование Texture рассказали в предыдущей статье.
На момент интеграции Flutter Mobile SDK на ОС Аврора поддерживался только подход с PixelBuffer, аналогичный подходу при интеграции Flutter Mobile SDK в iOS. Процесс взаимодействия происходит следующим образом:
Регистрируется текстура во Flutter Embedder.
Когда карта подготавливает очередной кадр, во Flutter отправляется уведомление о готовности кадра.
После этого Flutter запрашивает данные, которые перекладываются из OpenGL в PixelBuffer.
Данный подход реализован с использованием тройной буферизации (о чём мы рассказывали ранее).

Следует отметить, что PixelBuffer не является оптимальным методом из-за копирования данных между GPU и CPU. В будущем ожидается, что Embedder на ОС Аврора будет поддерживать создание OpenGL текстур напрямую, что позволит графическому движку отрисовывать кадры без дополнительного копирования.
Как начать использовать
Поскольку ОС Аврора не предоставляет собственного аналога pub.dev, плагин интеграции Flutter Mobile SDK в эту ОС пока выкладывается и распространяется в отдельной ветке на GitHub.
Подробная инструкция по подключению нашего продукта в приложения для ОС Аврора доступна в разделе публичной документации.
В итоге
Flutter Mobile SDK был успешно интегрирован в ОС Аврора, включая доступ ко всем необходимым API. Это подтверждает, что Flutter не только жизнеспособен на платформе Аврора, но и может стать полноценным инструментом для создания современных, производительных и удобных приложений.
Мы убедились, что использование Flutter значительно ускоряет процесс разработки, снижает порог входа для новых участников команды и открывает широкие возможности для масштабирования решений в будущем.