RTLD
RTLD расшифровывается как Real-Time Library for D. Это рантайм-библиотека для D, которая позволяет не использовать стандартные druntime и Phobos. Она основана на модулях, которые я изначально писал для dlib2/dcore, а также на прямых портах из dlib 1.x. RTLD предоставляет самую базовую функциональность, работая поверх libc, WinAPI, POSIX, системных вызовов Linux, а также динамически загружаемых функций — X11 и OpenGL ES. По сути, это библиотека для тех, кто хочет писать на D как на C, не используя ничего лишнего.
Репозиторий проекта: https://github.com/gecko0307/rtld
Как гласит название, библиотека пригодна для разработки приложений реального времени — в том смысле, что все функции работают за предсказуемое время и не создают утечек памяти (стандартная библиотека D опирается на сборку мусора, поэтому в общем случае нельзя полагаться, что вызов ее функций не приведет к глобальной блокировке). Если вы пишете обычные приложения для x86, не ограниченные по таймингам и памяти, то вы можете использовать RTLD ситуативно, для каких-то отдельных задач, не отказываясь в целом от Phobos — обе библиотеки могут благополучно сосуществовать в одной программе. Полный переход на RTLD целесообразен в особых случаях, из которых я выделяю два главных сценария:
- Системное программирование: если вы пишете низкоуровневую библиотеку с интерфейсом C, которая будет использоваться другими программами — драйвер, сетевой протокол, графический или звуковой API и т.д.;
- Программирование встраиваемых систем и маломощных компьютеров. Сюда относятся одноплатные ARM-компьютеры вроде Raspberry Pi или Khadas. RTLD имеет минимальный отпечаток памяти, что позволяет использовать ее на самых слабых машинах, имеющих операционную систему.
На данный момент RTLD поддерживает Windows и Linux, компилируется под x86_64 и AArch64. Некоторые ее модули платформонезависимы, и их можно использовать под bare metal.
Текущий список фич:
rtld.core— ключевые функции: стандартный ввод/вывод, работа с динамической памятью, файлами, загрузчик библиотек, потоки, мьютексы, атомарные операцииrtld.container— контейнерыrtld.data— реализации форматов данных. Содержит быстрый (480 MiB/s) парсер JSONrtld.gui— кроссплатформенное создание окнаrtld.gl— биндинг к OpenGL ES 2/3 и создание контекста (поддерживаются Windows и Linux/X11)rtld.hash— хэш-функции (xxHash32, xxHash64)rtld.libc— функции библиотеки Crtld.math— элементарные математические функцииrtld.memory— аллокаторы памятиrtld.random— генератор псевдослучайных чиселrtld.sys.windows— функции WinAPIrtld.sys.posix— функции POSIXrtld.sys.linux— функции Linuxrtld.text— типString, текстовые кодировки (UTF-8, UTF-16), форматирование, лексический анализаторrtld.time— функции даты-времени, наносекундный таймер.
RTLD предоставляет собственный пакет математических функций. Его цель — оптимизация и обеспечение максимальной портируемости. При компиляции rtld.math.base выбирает оптимальную из всех доступных реализаций (std.math, libc math, LLVM-интринсики, независимые реализации). Пользовательский код, таким образом, будет максимально эффективным для всех целевых архитектур и сред. Если для компиляции библиотеки используется LDC, то везде, где возможно, используются LLVM-интринсики. В противном случае предпочтение отдается функциям из std.math, если библиотека компилируется вместе с Phobos. В противном случае используются функции рантайма C. В режиме FreeStanding (bare metal) используются встроенные платформонезависимые реализации.
История
Концепция библиотеки уходит корнями в проект dcore, которым я периодически занимался в начале 2020-х. Это был низкоуровневый бэкенд для dlib2, который можно было опционально собрать без зависимости от Phobos. Его разработка, однако, продвигалась очень медленно из-за жестких ограничений режима BetterC. Мне этот режим не очень нравился, и я давно искал какой-то более практичный способ писать на D без встроенного рантайма, не лишаясь при этом чуть ли не всех преимуществ языка над C++.
В какой-то момент я вернулся к работе над DIOS, учебным ядром операционной системы, которое я начал писать еще в середине десятых. Портируя DIOS на x86_64, я подумал, что неплохо бы вместо BetterC использовать для системной разработки полноценный D, пусть и слегка урезанный, и начал с этой целью писать библиотеку, которую назвал RTLD.
Затем у меня появился одноплатный ARM-компьютер Khadas, и я решил попробовать написать что-нибудь для него. Обнаружив, что LDC позволяет относительно легко кросс-компилировать под AArch64, я буквально за несколько дней собрал RTLD со своим собственным мини-рантаймом, окончательно избавившись там от модулей Phobos. Потом я просто перенес всю готовую функциональность dcore в RTLD, получив в итоге библиотеку, которая позволяет писать один и тот же низкоуровневый код на D под обе архитектуры. С этого момента проект стал публичным на GitHub.
От консольного вывода я довольно быстро перешел к кроссплатформенному созданию окна и контекста OpenGL ES (к тому моменту это уже было реализовано в dcore, но только для Windows). Затем перенес базовую функциональность из dlib 1.x: аллокаторы памяти, контейнеры, собственный строковой тип, кодировки Юникода и т.д. Так RTLD стала тем, чем она является сегодня.