Мой личный бложек. Пишу о жизни в Чехии, программировании и просто свои мысли обо всём. Пишу не часто.

 
Просто уёбищная поддержка Android и iOS в компиляторе LDC
Заметки не программиста
В DMD есть поддержка только x86 платформ и это фатальный недостаток классического D компилятора. Но появляется компилятор LDC, который транслирует код через LLVM, тем добавляя возможность компилировать D код под все известные платформы. Ну не прелесть ли? Большинство всяких нестандартных платформ обычно нужно 3.5 анонимусам и не более. Но вот поддержка arm/aarch64 выводят D на совершенно новый уровень, делая его более привлекательным и перспективным языком. На IT-сайтах появляются статьи что на D теперь можно писать под Android и iOS.

Но чтоже с этим не так?
Да практически всё. Нет примеров чуть более чем полность. Есть какая-то вырвиглазная инструкция как собрать Hello World под Android, половина комманд в ней не работают т.к. она писалась несколько лет назад и за это время аргументы запуска компилятора поменялись. Чтобы собрать Hello World нужно потратить неделю времени. И в итоге получается очень большой shell script для сборки с кучей ебических параметров.

TLS не поддерживается, а ведь TLS в D это наше всё. Приходилось все static переменные заменять на __gshared, что не есть гуд. В последних версиях наконец-то пофиксили.
Программа линкуется только ld.bfd, при том что на Android ld.gold уже давно стал нормой. В последних версиях пофиксили, ld.gold стал поддерживаться, но местами выдаёт странные баги из-за того что по другому располагает сегменты данных в памяти, так что до сих пор стабильно можно использовать только ld.bfd.

D заявляет себя как кроссплатформенный компилятор, например размеры типов данных на всех платформах одинаковые, например long на любой платформе 8 байт (в том же C это не так).

Типы float/double обязательно должны быть выравнены на границу 8 байт, что с одной стороны является нормой, но на x86 невыравненные данные не выдают ошибку, а на arm/aarch64 выдают, а компилятор не выводит никаких warning'ов. Где вообще это может понадобиться? При парсинге пакетов данных в структуру, пакет естественно хранит данные как можно компактнее. И для arm/aarch64 приходится читать эти данные как uint/ulong, а при сохранении в структуру делать cast в float/double.

ubyte x = 0xF0; x >>= 8;
чему равно??? На x86 - 0, на arm/aarch64, хер там плавал, x - будет абсолютно рандомным. Це ж просто ёбаный пиздец. Компилятор хотя бы выдавал бы warning, но он молча компилирует в ubyte x = random.

asm {}
не работает чуть более чем полностью, вместо этого используется ебический шаблон __asm!T(``); с LLVM-ассемблером, который мягко говоря очень специфический. Мои эксперименты показали, что не соблюдается call convention для arm, т.е. параметры передаются не через те регистры, которые заявлены в документации к arm. Сам же LDC вообще не предоставляет документации о call convention под arm.

iOS
Все теже баги что на Android, только всё ещё хуже, документации нет, примеров нет, phobos до недавнего времени вообще не собирался под iOS. В последних версиях пофиксили, но он всё равно уёбищно работает. LDC нужно патчить, иначе некоторые блоки кода просто не компилируются.

Биндинги и интеграция с Objective-C в LDC не поддерживатеся, в DMD хотя бы начали работу в этом направлении, но в целом там тоже это не работает как надо.
Единственный способ сделать двусторонний мост Objective-C <-> D, это сделать промежуточные функции на чистом C, которые могут вызываться из обоих языков.

Но есть ведь плюсы?
Да есть. Если выкинуть стандартную библиотеку phobos и заменить его нашим framework'ом, который фиксит все эти баги, то программа стабильно работает.  Причём даже сложные проекты собираются под Android и работают, и работают достаточно быстро.

Что в итоге у меня получилось?
  • Сборка консольного приложения
  • Сборка консольного приложения в режиме unittest + скрипт для автоматической заливки тестируемого проекта по adb на устройство/эмулятор с автоматическим запуском, не требующий root-прав.
  • Классическое графическое приложение, .apk файл состоящий из небольшого java-кода и .so файла с скомпилированным D-кодом, двусторонний мост java <-> D, позволяющий вызывать функции друг друга и синхронизирующий результаты, т.к. D и java работают в разных потоках.
  • .apk с unittest'ами, таки да, даже это работает.
  • iOS? Таки да, тоже всё перечисленное работает, но проверялось только на симуляторе, т.к. у меня просто нет iPhone. Отладка честно говоря несколько неудобная, приходится запускать MacOSX под VirtualBox, а из под него запускать iOS Simulator, и это очень медленно работает. Но за счёт того что наш framework полностью кроссплатформенный и даёт одинаковый результат на всех платформах, то тестировать логику приложения можно на Android или вообще на Desktop, а на iOS Simulator проверять только пред-релиз версию на наличие специфических багов.

[next]
0