Dart уже предлагает обширный набор компиляторов для создания кода, оптимизированного для мобильных устройств и Интернета. Эти гибкие компиляторы позволяют нашим партнерам по фреймворку ориентироваться на широкий спектр форм-факторов: приложения Flutter для Android и iOS, приложения Flutter для Интернета и рабочего стола, приложения AngularDart в Интернете и Google Assistant для встраиваемые устройства .

Сегодня мы анонсируем dart2native, расширение нашего существующего набора компиляторов, с возможностью компилировать программы Dart в автономные исполняемые файлы, содержащие заранее скомпилированный машинный код. С dart2native вы можете создавать инструменты для командной строки в macOS, Windows или Linux с помощью Dart. Изображение анонса этой функции реализовано с использованием самой функции :-)

Dart Native и компилятор dart2native

Dart уже несколько лет поддерживает компиляцию AOT (опережающую) в машинный код, и, таким образом, Dart Native является довольно зрелой технологией. Однако раньше мы предоставляли эту возможность только на мобильных устройствах iOS и Android через Flutter.

В dart2native мы расширяем нашу встроенную поддержку компиляции для поддержки традиционных настольных операционных систем под управлением macOS, Windows и Linux. Поскольку исполняемые файлы, созданные с помощью dart2native, являются самодостаточными, их можно запускать на компьютерах, на которых не установлен Dart SDK. А поскольку они скомпилированы с помощью компилятора Dart AOT, исполняемые файлы запускаются всего за несколько миллисекунд. Как и в случае с другими компиляторами и средами выполнения Dart, тот же набор богатых и согласованных основных библиотек доступен в Dart при компиляции в собственный код.

Мы слышали, как многие клиенты просят о компиляции AOT для настольных операционных систем - шестая проблема с самым высоким рейтингом в нашей системе отслеживания проблем, - поэтому мы рады сделать эту функцию доступной.

Если раньше вы использовали dart2aot, то с версии 2.6 вы будете использовать dart2native. Он предоставляет расширенный набор функций dart2aot.

Создание приложений командной строки с помощью dart2native

Компилятор dart2native - отличный выбор для создания и развертывания приложений на основе Dart для командной строки. Эти приложения часто используют библиотеки, такие как dart:io (базовый ввод-вывод), package:http (сеть) и package:args (анализ аргументов). Давайте рассмотрим основы компиляции приложения привет, мир в исполняемый файл:

Исходный код hello.dart:

main() {
  print(‘Hello Dart developers’);
}

Скомпилируйте hello.dart в hello исполняемый файл:

$ dart2native src/hello.dart -o hello
Generated: /Users/mit/hello

Run hello измерение времени выполнения:

$ time ./hello
Hello Dart developers
real 0m0.049s
user 0m0.018s
sys 0m0.020s

Обратите внимание, как команда запускается, выводится на стандартный вывод и завершается всего за 49 миллисекунд!

Мы видели, как несколько разработчиков Dart уже экспериментировали с dart2native инструментами командной строки:

  • Натали из команды SASS (популярный инструмент расширения CSS) сообщает, что после переключения их реализации SASS на основе Dart на компиляцию с dart2native, теперь она конкурентоспособна по производительности с LibSass, реализацией на C ++.
  • Филип из команды Dart DevRel перекомпилировал свой инструмент linkchecker с помощью dart2native и увидел 27-кратное ускорение при проверке небольших сайтов.

Взаимодействие с кодом C через dart: ffi

Нативным приложениям часто требуется доступ к встроенным функциям из окружающей операционной системы. Эти системные API-интерфейсы обычно представлены в собственных библиотеках на основе C, и Dart поддерживает взаимодействие с этими библиотеками через dart:ffi, наш новый механизм взаимодействия с C, который мы запустили в предварительной версии в Dart 2.5. Компилятор dart2native совместим с dart:ffi, поэтому вы можете создавать и компилировать исходные приложения Dart, которые его используют.

Один член команды недавно использовал dart:ffi для создания dart_console библиотеки для разработки консольных приложений, которая имеет такие функции, как получение размеров окна, чтение и установка местоположения курсора, управление цветами, а также чтение ключей и управляющих последовательностей. Возможность использовать dart:ffi делает Dart очень мощным языком для консольных приложений.

kilo: редактор кода размером 7 МБ, написанный менее чем на 500 строк кода Dart

Используя основные библиотеки Dart, dart:ffi и библиотеку dart_console, мы можем создавать довольно интересные консольные приложения. Пакет dart_console включает полную демонстрацию kilo, текстового редактора консоли, написанного всего на ~ 500 строках кода Dart. Название kilo происходит от его происхождения, kilo.c, которое представляло собой реализацию C примерно в 1000 строк кода.

С новым компилятором dart2native мы можем легко упаковать это, и в итоге мы получим автономный редактор кода размером 7 МБ. Вот демонстрация компиляции редактора и последующего использования скомпилированного редактора для редактирования собственного исходного кода с целью исправления ошибки:

Строительные услуги с dart2native

Еще одно потенциальное использование компилятора dart2native - для небольших сервисов, например, для серверной части, поддерживающей интерфейсное приложение, написанное с использованием Flutter. В последние годы растущей тенденцией стало использование сервисов, работающих на бессерверных вычислениях. Это полностью управляемые службы, которые автоматически масштабируются, включая масштабирование от нуля и до нуля (не работает), что дает возможность значительно снизить затраты, поскольку они выставляются счет только при фактическом запуске. Google Cloud делает бессерверные вычисления доступными через Cloud Run.

Для бессерверных бэкэндов очень важно, чтобы служба запускалась быстро. Традиционно службы на основе Dart работают с нашим JIT-компилятором (точно в срок), но выполнение на основе JIT имеет высокую задержку при запуске, поскольку код необходимо скомпилировать и разогреть, прежде чем он сможет начать выполнение. Заранее скомпилировав код вашей службы в собственный код, вы сможете избежать этой задержки и сразу же начать работу. Кроме того, с помощью собственного кода вы можете создавать службы Dart, занимающие мало места на диске и являющиеся самодостаточными, что значительно уменьшает размер контейнера, в котором работает служба Dart. Разработчик Dart Пол Мундт недавно задокументировал свой опыт использования компилятора dart2native; он смог уменьшить размер своего образа Docker на 91% с 220 МБ, используя код, скомпилированный с помощью JIT, до 20 МБ, используя собственный код! См. Нашу документацию для получения более подробной информации о серверных приложениях и пакетах.

Доступность

Компилятор dart2native доступен в Dart SDK начиная с версии 2.6, которая доступна с сегодняшнего дня по адресу dart.dev/get-dart. После установки SDK вы должны увидеть новый компилятор в каталоге bin / и в папке PATH. У Dart.dev есть дополнительная документация.

Если вы получаете Dart SDK через Flutter, обратите внимание, что текущие сборки Flutter не имеют полной поддержки dart2native. Мы рекомендуем вам установить Dart 2.6 SDK с сайта dart.dev/get-dart.

Известные ограничения

Эта начальная версия dart2native компилятора имеет несколько известных ограничений, перечисленных ниже. Вы можете сообщить нам, какие проблемы важны для вас, отметив проблему в нашем трекере проблем на GitHub.

  • Нет поддержки кросс-компиляции (проблема 28617): компилятор dart2native поддерживает создание машинного кода только для операционной системы, в которой он работает. Таким образом, вам нужно будет запустить компилятор три раза - в macOS, Windows и Linux - если вы хотите создать исполняемые файлы для всех трех. Один из способов сделать это - использовать поставщика непрерывной интеграции (CI), который поддерживает все три операционные системы.
  • Нет поддержки подписи (проблема 39106): созданные исполняемые файлы используют формат, несовместимый со стандартными инструментами подписи, такими как codesign и signtool.
  • Нет поддержки dart:mirrors и dart:developer (см. Основные библиотеки Dart).

Другие изменения в Dart 2.6

Версия 2.6 Dart SDK также содержит несколько других изменений.

Мы запустили предварительную версию dart:ffi, нашего нового механизма взаимодействия с C, в Dart 2.5. В Dart 2.6 появилась новая версия dart:ffi. В этой новой версии внесен ряд критических изменений API, чтобы упростить использование наших API, обеспечить большую безопасность типов и обеспечить удобный доступ к памяти. Дополнительные сведения см. В Журнале изменений Dart 2.6. С этими изменениями dart:ffi переходит на бета-версию, и мы ожидаем, что в будущем изменения API будут происходить гораздо реже, а общая стабильность будет высокой. Пожалуйста, продолжайте оставлять отзывы через трекер проблем.

Dart 2.6 также содержит предварительный просмотр захватывающей новой языковой функции, методов расширения. У нас еще есть немного доработок и инструментов для завершения этой функции, но мы надеемся официально запустить ее в нашей следующей версии Dart SDK. Тогда у нас будет гораздо больше информации о методах расширения; а пока вы можете прочитать о конструктивных соображениях, стоящих за этой функцией.

Следующие шаги

Загрузите Dart 2.6 SDK (dart.dev/get-dart), создайте что-нибудь классное с помощью dart2native и расскажите нам об этом. Если вы хотите поделиться подробностями, оставьте ответ внизу этой статьи. Мы рады видеть, что вы создаете!