RTLD — низкоуровневый рантайм для D

Я начал разработку dlib в далеком 2011 году, когда писал на старом добром OpenGL 1.x под 32-битным Linux. Тогда я и не помышлял об альтернативных архитектурах и кросс-компиляции, мне даже в голову не приходило, что у D когда-нибудь появится поддержка такого количества разнообразных платформ. Но к началу 20-х уже стало очевидно, что грядет эпоха ARM, и старичку x86 придется потесниться, а сегодня AArch64 на устройствах мощнее телефона — уже не причуда и экзотика, а обыденная реальность. Стоит это принять и начать уже думать об ARM не как о мобильной, а как о второй десктопной архитектуре. Это необычное положение дел, потому что на десктопе x86 всегда царил монопольно. Но я вообще-то люблю изучать все новое, и для меня как графического разработчика освоение еще одной процессорной архитектуры — интересный вызов. Надо ли прямо сейчас всем кидаться портировать весь софт на ARM? Я думаю, нет, но какие-то базовые штуки, полезные библиотеки, фреймворки — желательно. Вот и я решил не оставаться в стороне.

Хорошая новость состоит в том, что D, в лице компилятора LDC, отлично поддерживает ARM. LDC — это неявный кросс-компилятор, он умеет генерировать код почти под все платформы, поддерживаемые LLVM, и это можно делать на любой хост-системе, не пересобирая тулчейн. ARM существует в разных аппаратно-программных вариантах, я под ним буду подразумевать aarch64-linux-gnu — то есть, платформу с процессором AArch64, ядром Linux и окружением GNU. Проще говоря, установив LDC, вы можете на x86 собирать приложения под десктоп или сервер на базе AArch64, о чем я уже писал в предыдущем посте.

Плохая новость состоит в том, что для компиляции под нестандартные таргеты нужны соответствующие версии Phobos и druntime. Я боюсь представить, что это за квест — собрать их, и не имею никакого понятия о статусе Phobos для AArch64. Мне это даже не очень интересно, потому что Phobos я считаю не самой удачной стандартной библиотекой, я ее почти не использую — она сильно перегружена, половину можно было бы оттуда вынести в дополнительные DUB-пакеты, многие модули откровенно устарели, некоторые функции работают странно, а шаблоны порой не компилируются. Для меня уже привычен хардкорный путь — игнорировать Phobos и писать все свое. К тому же, под маломощными одноплатниками с маленькой памятью вам все равно GC не друг, и лучше все делать на @nogc-компонентах.

Все эти измышления подвели меня к идее создания новой библиотеки общего назначения, более низкоуровневой, чем dlib. Я ее назвал RTLD — Real-Time Library for D. Она основана на модулях, которые я изначально писал для dlib2/dcore, а также на прямых портах из dlib 1.x. В отличие от dlib, это будет настоящая замена Phobos. RTLD предоставляет самую базовую функциональность, работая поверх libc, WinAPI, POSIX, системных вызовов Linux, а также динамически загружаемых функций — X11 и OpenGL ES. По сути, это библиотека для тех, кто хочет писать на D как на C, не используя ничего лишнего. Однако я намеренно не стал делать ее BetterC, в отличие от dcore. Взвесив все «за» и «против», я решил, что от BetterC на десктопе толку мало — от классов никуда не деться, они все равно потребуются на определенном уровне абстракции, поэтому зачем изначально себя их лишать?

https://github.com/gecko0307/rtld

На данный момент RTLD поддерживает Windows и Linux, компилируется под x86_64 и AArch64. Некоторые ее модули платформонезависимы, и их можно использовать в системной разработке, под bare metal.

Текущий список фич:

  • rtld.core — ключевые функции: работа с динамической памятью, загрузчик библиотек, потоки, мьютексы, создание окна
  • rtld.gl— биндинг к OpenGL ES 2/3 и создание контекста (поддерживаются Windows и Linux/X11)
  • rtld.libc — функции библиотеки C
  • rtld.math — элементарные математические функции
  • rtld.random — генератор псевдослучайных чисел
  • rtld.sys.windows — функции WinAPI
  • rtld.sys.posix — функции POSIX
  • rtld.sys.linux — функции Linux
  • rtld.text — текстовые кодировки
  • rtld.time — функции даты-времени, наносекундный таймер.

Закономерен теперь вопрос архитектуры будущей dlib2. Я склоняюсь к мысли отказаться от dcore в пользу RTLD — это будет базовый бэкенд dlib2, реализующий львиную долю функциональности, которая не зависит от GC. К сожалению, полный отказ от GC в dlib невозможен по ряду причин, но я надеюсь сильно сократить его присутствие.

Кросс-компиляция «Hello, World» под ARM

Я всю жизнь разрабатываю под x86 (за исключением экспериментов с MIPS-I/PSX, но это больше из исторического интереса), и мне всегда хотелось написать что-нибудь на D под вторую главную архитектуру современности — AArch64. Недавно я досконально изучил, как это правильно делать, причем самым, на мой вкус, безболезненным способом, который не требует WSL, Docker и монструозных тулчейнов — понадобится только обычный свежий LDC плюс несколько дополнительных бинарей, которые легко скачать в готовом виде.

Итак, программа (src/main.d):

module main;

extern(C) nothrow @nogc
{
    int printf(const(char)* fmt, ...);
}

extern(C) int main(int argc, char** argv) nothrow @nogc
{
    printf("Hello, World!\n");
    return 0;
}

Для начала нужно убедиться, что ваша версия LDC собрана с поддержкой aarch64: ldc2 --version.

Важный вопрос: в каком режиме компилировать — BetterC или нет? По моему мнению, на большинстве популярных платформ BetterC дает ноль преимуществ, отнимая важные фичи языка вроде классов. Он хорош для микроконтроллеров, для WASM, для всякой экзотики, но точно не для привычного GNU userspace, который наличествует на любой железке мощнее калькулятора. Так что я предлагаю сразу идти нормальным путем и заменить те функции druntime, которые вам нужны, самописными реализациями. Для простейшего примера, впрочем, это не требуется.

Моя команда сборки выглядит следующим образом:

ldc2 -Isrc -i --vgc
    -defaultlib= ^
    -debuglib= ^
    -mtriple=aarch64-linux-gnu ^
    -linker=lld ^
    -Xcc=--sysroot=sysroot/aarch64-linux-gnu/libc ^
    -Xcc=--gcc-toolchain=sysroot ^
    -Xcc=-unwindlib=none ^
    src/main.d ^
    -of=test

Она предполагает, что в папке sysroot находится минимальное системное окружение, необходимое для компиляции linux-приложений. Я его взял отсюда: https://github.com/ClickHouse/sysroot. Заберите папку linux-aarch64 из репозитория со всем содержимым и переименуйте в sysroot. Это же окружение понадобится для тестирования.

При желании можно оформить то же самое для DUB:

{
    "name": "test",

    "targetType": "executable",
    "targetName": "test",

    "sourcePaths": ["src"],
    "importPaths": ["src"],

    "dflags-ldc": [
        "--vgc",
        "-defaultlib=",
        "-debuglib=",
        "-mtriple=aarch64-linux-gnu",
        "-linker=lld",
        "-Xcc=--sysroot=sysroot/aarch64-linux-gnu/libc",
        "-Xcc=--gcc-toolchain=sysroot",
        "-Xcc=-unwindlib=none"
    ],
    "postBuildCommands-windows": [
        "copy /Y test.exe C:\\Users\\gecko\\Documents\\vbshared\\arm\\test",
        "del test.exe"
    ]
}

Последнее нужно под Windows, чтобы на выходе получился бинарник без расширения «.exe».

Если все хорошо, то вы получите файл test, который можно сразу проверить:

file ./test

Команда выведет что-то вроде

./test: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for
GNU/Linux 3.7.0, with debug_info, not stripped

Если есть ARM-компьютер, то можно запустить приложение на нем (я тестировал на Khadas VIM2), но для тестов гораздо практичнее настроить виртуальное окружение. Если у вас Linux, то рекомендую https://github.com/multiarch/qemu-user-static — нужно скачать qemu-aarch64-static на странице релизов. Это эмулятор пользовательского режима QEMU, который позволяет запускать бинарники AArch64 непосредственно на хост-системе.

Использую я его так:

./qemu-aarch64-static -L ./sysroot/aarch64-linux-gnu/libc/ ./test

Параметр -L передает эмулятору путь к корневой папке окружения, там должны быть динамический линкер /lib/ld-linux-aarch64.so.1 и папка lib64 с библиотеками C/POSIX — проверьте. Важно убедиться, что вместо симлинков не лежат пустые файлы, под Windows часто так получается.

Для Windows я, к сожалению, не нашел эмулятор юзерспейса linux-aarch64 (может, его и нет вовсе). Ручной запуск ARM-машины QEMU — это жуткий геморрой. Самый беспроблемный способ, который не заставляет постоянно запускать и останавливать тяжелые сессии эмуляции (равно как и вводить много команд вручную) — тупо установить обычный десктопный Linux в VirtualBox и там гонять qemu-aarch64-static, не выключая систему. Это немного костыльно, но жить можно, особенно если держать весь проект сразу в shared-папке хоста. Мне лично это удобно тем, что я и так использую Linux на виртуалке для других тестов.

Об администрировании сервера

Сегодня, в эпоху облачных провайдеров и SaaS, управлять сервером самостоятельно — крайне нишевое занятие. Для этого нужно очень хорошо разбираться в Linux и его многочисленных системных компонентах, которые, к тому же, постоянно обновляются и меняются, из-за чего знания и опыт быстро устаревают. Я много лет пользуюсь Linux, но и то не знаю всех тонкостей, постоянно учусь. Сама система принципиально несложная и понятная, но в ней постоянно появляется что-то новое, какие-то дополнительные слои абстракции. Linux многолик, его можно использовать в самых разных контекстах — отсюда и сложность. Ну и, конечно, знать систему на уровне десктопа — это одно, а админить по SSH — слегка другое.

(далее…)

Обновления

bindbc-wgpu 0.19.0, соответствующий wgpu-native 0.19.x. Каких-то существенных изменений в этой версии нет, кроме того, что структуры и функции опроса статистики конвейера вынесены в платформоспецифичную часть API (bindbc.wgpu.types2).

Также рад сообщить, что bindbc-wgpu теперь успешно собирается и работает под Linux — как и демо-приложение с моделью Cerberus. Тестировал на Mint 21.2 с wgpu-native 0.19.1.1.

Работа над новым релизом Dagon продолжается: на днях внес множество исправлений, связанных с поддержкой Linux. В частности, теперь расширения dagon:newton и dagon:imgui загружают библиотеки из папки проекта, если не находят их в /usr/lib. При сборке под 64-битный Linux нужные библиотеки теперь копируются в папку с проектом — это должно упростить работу с расширениями, пользователи неоднократно жаловались на неинтуитивность подключения Newton. Также обновлен биндинг ImGui.

Я возвращаюсь на Linux!

Если вы читаете мой блог с самого начала, то должны помнить, что в первой половине десятых я в основном пользовался именно этой ОС: я даже написал две статьи о своем опыте работы с системой — Почему я выбираю Linux? (2012) и 7 лет с Linux (2015). К сожалению, с 2018 года мне по работе пришлось стать виндузятником. Не то, чтобы это создало какие-то неудобства, но времени на Linux хватать перестало — к тому же я купил новые компьютеры, а старый линуксовый ноутбук отдал родственникам. Систему, естественно, пришлось снести. Но недавно захотелось мне привести в рабочее состояние другой ноут, с ужасно тормозной OEM-версией Windows 10. Я выбрал для него все тот же Linux Mint, а именно 21.2 MATE Edition (кто не в курсе — MATE является форком классического рабочего стола GNOME 2). Кстати, впервые в жизни не стал ставить Linux в дуалбут с Windows, переформатировал весь диск — терять было нечего. И вот я опять как дома!

Я был приятно удивлен: за 5 лет моего отсутствия линуксовый десктоп стал заметно лучше. Системные приложения, конечно, в основном все те же, привычные для старого гномовода. Однако в мое время пакеты ставились вручную в консоли, при помощи apt-get — теперь же есть удобный каталог ПО с графическим интерфейсом. Хорошая поддержка оборудования: Wi-Fi заработал из коробки без необходимости устанавливать драйвер. Драйвер для видеокарты система сама обнаруживает и скачивает — правда, показалось странным, что при этом нужно вводить пароль Secure Boot. Ну, видимо, такие теперь порядки в эпоху UEFI.

Пожалуй, самое важное нововведение последних лет — это Flatpak. Я в свое время прошел все круги ада в плане установки приложений — наверное, каждому линуксоиду нулевых знакомы проблемы с зависимостями бинарников, версиями glibc, зоопарком звуковых подсистем. О том, чтобы ставить программы инсталляторами, как в Windows, приходилось только мечтать — я всегда твердил, что популярности Linux на десктопе мешает именно это. Похоже, что Flatpak решает данную проблему: это утилита для создания самодостаточных бинарных пакетов без зависимостей, которые запускаются в изолированном окружении-песочнице. Они могут взаимодействовать с ОС через механизм порталов — можно дать приложениям доступ к диску, сети, устройствам и т.д. При этом в системные папки типа /usr/bin, /usr/lib ничего не устанавливается, и это просто замечательно! Флатпаки, естественно, дистрибутиво-независимы — не нужно создавать отдельные пакеты на каждый дистрибутив и разные его версии, что всегда было дичайшей головной болью разработчиков. В Mint поддержка Flatpak встроена в менеджер приложений: вы можете устанавливать как традиционные deb-пакеты, так и пакеты с Flathub. Минусом такого подхода является то, что флатпаки достаточно много весят, но, по современным стандартам объемов носителей, это не так уж важно.

Очень понравилось, что в виде флатпаков можно установить все бесплатные приложения, нужные мне для работы: Figma, VS Code, GitHub Desktop и др. А еще в мое время под Linux было совсем мало игр. Сегодня ситуация гораздо позитивнее: есть Steam, где я обнаружил linux-версии многих своих любимых игр последних лет. Радует полноценная поддержка Linux в мейнстримных игровых движках, особенно свободных. Установил Node.js, и с полоборота запустились все мои тулчейны для разработки баннеров и браузерных игр — благо там почти все кроссплатформенное. Хобби-проекты теперь, конечно, тоже буду полноценно тестировать под Linux.

Единственный серьезный минус, который пока заметил: свежий Photoshop не запускается под WINE. Но в моем случае жить можно и без ФШ, учитывая, что linux-машина не является основной для работы. Может быть, получится запустить какую-нибудь старую версию — буду экспериментировать.

Растягиваемое окно

Atrium теперь поддерживает окна любого размера (развернуть окно игры на весь экран можно в режиме паузы — Esc). Также в свежей сборке исправлены различные баги физики и управления.

Сборка под Windows
Сборка под Linux

Новая демка Atrium

Скачиваем новую демку с тенями:

Для Windows (2,36 МБ)
Для Linux (3,89 МБ)

Под Windows запускайте с параметром --enableShadows=1, либо используйте прилагающийся bat-файл, в котором этот параметр уже указан.

Репозиторий Atrium на GitHub также будет обновлен в ближайшее время.

7 лет с Linux

Именно такой у меня «стаж». С некоторых пор я вовсе перестал активно пользоваться Windows — под Linux у меня буквально все: работа, учеба, хобби и развлечения. Начиналась вся эта история достаточно забавно: я сам очень люблю читать подобные статьи-воспоминания, поэтому хочу поделиться и своими.

Мое знакомство с Linux началось в 2006-2007 годах благодаря нижегородскому журналу «Мой друг компьютер». Помимо информации для начинающих пользователей ПК, различных обзоров софта и железа, он содержал и материалы по Linux — рецензии на дистрибутивы, инструкции по установке, полезные команды Bash, различные советы и хитрости по эксплуатации linux-систем.

Я мгновенно влюбился — пусть и «дистанционно». Забавно вспомнить: в то время у меня еще не было безлимитного подключения к Интернету, и скачать даже самый маленький дистрибутив было проблематично (с помегабайтной тарификацией и 10 Мб казались заоблачной цифрой). В компьютерных магазинах диски с этой системой тогда тоже почему-то было не найти, поэтому попробовать Linux на практике мне долгое время не удавалось — и я помногу перечитывал подшивку «МДК», смаковал, запоминал информацию…

В одном из номеров был опубликован обзор Ubuntu — тогда еще молодой и малоизвестной системы на основе Debian. Позиционировалась она как дружелюбный дистрибутив для начинающих, и отдельно подчеркивалась возможность запуска системы прямо с CD, без необходимости установки. Особенно поразила меня щедрость разработчиков: компания Canonical тогда бесплатно рассылала диски с Ubuntu по почте — для тех, кто не имеет возможности скачать ее. Ведь это же как раз про меня!

Я тут же оформил заказ, и через пару месяцев в руках у меня был диковинный заграничный пакет, а внутри — симпатично оформленный LiveCD с Ubuntu 7.10. Моему восторгу не было предела! Впрочем, радоваться, как выяснилось, было особо нечему: LiveCD запустился, но, то ли из-за бага в видеодрайверах, то ли из-за неправильных настроек, изображение на экране было ужасным: сквозь дико смещенные и постоянно подрагивающие ряды пикселей с трудом узнавался рабочий стол GNOME. Нечего было и думать о том, чтобы устанавливать систему в таком состоянии на жесткий диск…

Уже впоследствии я узнал, какой бардак творится с видео в Linux: о глючности драйверов ATI ходили легенды и анекдоты. У меня же был старый ноутбук с интегрированной видеокартой Intel, и поиск стабильно работающего на нем дистрибутива отнял в свое время не одну неделю.

Осенью 2008 года у меня, наконец-то, появилась безлимитка по телевизионному кабелю. Правда, на ужасающе низкой скорости — почти на уровне dial-up, менее 64 кб/c. Но и этого хватало, чтобы кое-как выкачать Slitaz — мой первый полноценно работающий дистрибутив. Узнал я о нем на сайте https://distrowatch.com — тогда это был самый авторитетный ресурс по Linux, на него неизменно ссылались все авторы статей «МДК».

При весе в 30 мегабайт Slitaz включал полноценный графический режим (Xvesa вместо Xorg, рабочий стол Openbox) и достаточно богатый для такого размера набор пркладных программ (аудиоплеер, браузер, текстовый редактор, просмотровщик изображений, простенький графический редактор наподобие Paint и даже несколько игр). Правда, в той версии дистрибутива не работала сеть, поэтому приходилось постоянно переключаться между Slitaz и Windows, чтобы посидеть в Интернете. Но я все равно был счастлив: наконец-то я пользуюсь Linux!

Slitaz я запускал исключительно в режиме LiveCD, первое время не пытаясь установить систему насовсем. Хотелось сначала попрактиковаться на чем-то легковесном, а для постоянного использования найти что-то посерьезнее. Постепенно я перепробовал множество разных LiveCD: Puppy Linux, MCNLive, Austrumi, CDLinux и т.д. В каждом было что-то уникальное: например, MCN «из коробки» поддерживал Compiz — спецэффекты для окон.

Одним из самых интересных был дистрибутив Slax — он мог работать с флешки в режиме чтения/записи. При этом для систем, которые не поддерживали загрузку с флеш-накопителей, была предусмотрена возможность начальной загрузки с CD, а затем управление передавалось системе на флешке, и дисковод можно было освободить для других нужд. В Slax я просидел довольно долго, почти полгода — научился устанавливать пакеты, работал с Blender, GIMP, офисным ПО. Единственное, что портило настроение: система изредка могла намертво зависнуть — видимо, сказывались мизерные 512 Мб памяти при отсутствии своппинга.

И все же полноценным линуксоидом я себя считать не мог, пока не установил систему на жесткий диск. Случилось это летом 2009 года — тогда я как раз добрался до дистрибутива Mint. Интернет у меня тогда был временно отключен, и тут, как назло, слетела Windows Vista на одном из ноутбуков, к которому не прилагалась ОС на диске. Другого компьютера под рукой не было, но необходимо было срочно выполнить несложную офисную работу — OpenOffice Write было бы достаточно. Не оставалось ничего иного, как установить Mint — и в тот знаменательный день мои эксперименты с дистрибутивами, столь характерные для всех начинающих, благополучно завершились.

Система (если быть точным, Mint 6, основанный на Ubuntu 8.10) прекрасно встала на мое железо, без особого шаманизма заработало практически все периферийное оборудование, за исключением графического планшета — но его я впоследствии тоже сумел запустить. Это были времена расцвета GNOME 2: классический десктоп и привычный набор приложений делал миграцию с Windows легкой и безболезненной — «из коробки» шли традиционные GIMP, OpenOffice.org, Firefox, Thunderbird, Pidgin и т.д.

Производительность системы, по сравнению с Vista, поражала воображение: до этого я и не подозревал, что бюджетные ноутбуки способны включаться за десять секунд, а выключаться — за три!

Mint 6 выжимал максимум из моей видеокарты: была поддержка OpenGL 1.4, но при этом — внушительный набор доступных расширений, в том числе GL_ARB_shading_language и GL_ARB_vertex_buffer_object. Для полного счастья не хватало разве что поддержки FBO. Конечно, без полной поддержки OpenGL 2.0 было невозможно играть в современные игры, но для работы в Blender и монтажа видео этого хватало с лихвой. Linux надолго продлил жизнь этого ноутбука.

Продолжение спустя 8 лет: Я возвращаюсь на Linux!

Обновление Atrium

Доступна новая демонстрация проекта Atrium:

  • В игру интегрирован физический движок dmech в его актуальном состоянии
  • Проект теперь использует графический движок DGL
  • Готова модель гравитационного излучателя с эффектом электрического разряда
  • Добавлен HUD, который отображается на дисплее внутри шлема. Забрало шлема можно открывать и закрывать (планируется сделать локации в вакууме, проходить которые можно только с закрытым забралом)
  • Идет работа над первой игровой локацией.

Скачать:
atrium-demo-03122014-windows.zip 
atrium-demo-03122014-linux.tar.gz 

Составные тела в dmech

В физическом движке dmech реализованы составные тела (поддержка нескольких геометрий на тело). Корректировка позиции теперь основана на псевдоскоростях. Кроме того, устранен артефакт дрожания (jittering), возникающий в некоторых ситуациях.
Также dmech теперь использует последнюю версию dlib.

Сборка для Windows
Сборка для Linux
Исходники

Репозиторий на GitHub будет обновлен в ближайшее время.