Pull to refresh

Mono и Windows Forms на Nokia N900? Да не вопрос!

Reading time 5 min
Views 3.9K
Я был несколько удивлён, не увидев mono в репозиториях для этого замечательного устройства. Но, поскольку оно было позарез нужно, решил всё-таки собрать. И тут же напоролся на весьма забавную особенность маэмовского SDK, которая этого сделать мне не позволила. Но обо всём по-порядку. А пока что небольшой скрин того, что получилось:
image

Вместо нормального эмулятора устройства и тулчейна для сборки, ребята из нокии приспособили под это дело scratchbox, который, эксплуатируя qemu-user, запускает arm-ные бинарники прямо на ядре текущей ОС. И всё бы замечательно, если бы оно работало как надо. На деле же во время сборки qemu выдаёт «unsupported syscall 242», после чего сборка стопорится. Обычным кросскомпилером тут что-либо сделать сложно, ибо mono в лучших традициях процедуры bootstrap (поднятие самого себя за шнурки ботинок) компилит сначала свой компилер и уже с его участием дособирает всё остальное. Как с этим бороться, не особо понятно, если только компилить на девайсе, но там это займёт годы. Для N800 mono какой-то герой таки смог собрать, но работать на n900 оно отказалось, вываливаясь с SIGSEGV. Если кому-то интересно, как сия проблема была решена, или же самостоятельно пощупать моно на устройстве (можно прямо в Visual Studio писать, если что) прошу под кат.


Для начала опишу, как сделать не получилось. Тем не менее, при этом был получен экспириенс и информация может быть весьма полезна.
Про SDK писать не буду, про его установку и настройку и без меня много написано.

Блин первый. Компилим на девайсе.


  1. Приводим /etc/apt/sources.list в следующий вид:
    deb http_s_://downloads.maemo.nokia.com/fremantle/ssu/apps/ ./
    deb http_s_://downloads.maemo.nokia.com/fremantle/ssu/002 ./
    deb http_s_://downloads.maemo.nokia.com/fremantle1.2/ovi/ ./

    deb http_://repository.maemo.org/extras/ fremantle-1.3 free non-free
    deb http_://repository.maemo.org/extras-testing/ fremantle-1.3 free non-free
    deb http_://repository.maemo.org/extras-devel/ fremantle-1.3 free non-free

    deb http_://repository.maemo.org/ fremantle/sdk free non-free
    deb http_://repository.maemo.org/ fremantle/tools free non-free
    _ из ссылок убираем, он там по той простой причине, что парсер — лох, и не понимает даже тега code.
  2. Ставим build-essential, bison, gettext, m4
  3. ./configure && make && make install
  4. Осознаём, что процесс займёт десятилетия и ищем иные пути


Блин второй. Компилим на эмуляторе.


Для начала нам потребуется вытащить саму необрезанную rootfs. Тут есть 2 пути. Во-первых вы можете распаковать прошивку флешером (flasher-3.5 -u -F ОБРАЗ) и смонтировать rootfs.jffs. На самом деле там не jffs, а ubifs, кстати. У меня получилось вот по этому мануалу.

Ещё можно подгрузить систему восстановления, как описано здесь. Там сей образ используют дабы подвинуть разделы, но нам это не надо. После чего во внутренней консольке делаем mount -t ubifs ubi:rootfs /mnt и сливаем всё на флешку. Хороший метод бекапа, кстати, настоятельно рекомендую.

Далее по мануалу делаем себе образ убунты для qemu.

Дабы облегчить себе жизнь и получить возможность chroot'иться в arm-ое окружение нужен будет пакет qemu-kvm-extras-static. Копируем после установки /usr/bin/qemu-arm-static в /bin своей системы и chroot магическим образом начинает работать. Если кому интересно, как это происходит, могут почитать про binfmt_misc и прочие вкусности, которые нам позволяет linux. Теоретически так можно на самом девайсе ubuntu x86 в chroot-окружении запустить, а в ней завести wine. Хотя, скорее всего не получится, ибо наткнёмся на всё те же неподдерживаемые системные вызовы.

Монтируемся, создаём директорию maemo, разворачиваем образ, который сдампили, далее всё по первому блину.

В итоге во время компиляции mcs начал вылетать с internal error и ничего я с этим поделать не мог. Тем не менее была получена среда сборки независимая от бажного scratchbox-а (который ко всему прочему ещё и только под i386).

Наконец-то успех!


На третий день Зоркий Глаз заметил, что у сарая нет стены. А именно: практически весь mono — это управляемые dll-ки, которым решительно всё-равно под какой платформой их запускают. В результате созрел следующий план:

  1. Через apt-src install вытаскиваем сырцы моно. При этом они уже разложены по пакетам так, чтобы их потом удобно было ставить.
  2. Издеваемся над содержимым директории с дебиановскими сборочными скриптами так, чтобы все файлы оказались в /opt (на нокии совсем маленькая rootfs, если кто не в курсе)
  3. Собираем под amd64
  4. Собираем платформозависимые бинарники в chroot-окружении из п. 2 (в scratchbox опять полезли ошибки, не стал разбираться)
  5. Капитально издеваемся над пакетами, меняя в них эти самые бинарники, правя зависимости, вставляя костыли


Собственно, 4-ый шаг был облегчён наличием опции --disable-mcs-build, которую дяди из Novell специально придумали для таких случаев. Описывать процесс сборки не буду, он на этот раз (после 5-то неудачных попыток!) оказался весьма тривиален.

Наборы пакетов и версии библиотек в Maemo и на убунте несколько отличаются, так что пришлось покорпеть. Но оно того стоит: удалось перенести на устройство нормальную систему раскиданных по пакетам библиотек (пока не полностью, но я над этим работаю) вместо 260-иметрового тарболла, который генерится при ./configure && make. Собственно, сейчас mono у меня сожрал около 27 метров /opt при весе пакетов в 12. При этом уже сейчас доступен практически весь .NET 2.0:
System.dll, System.ServiceProcess.dll, System.Drawing.Design.dll, System.Transactions.dll, mscorlib.dll, System.Drawing.dll, System.EnterpriseServices.dll, System.Web.dll, System.ComponentModel.DataAnnotations.dll, System.IdentityModel.dll, System.Web.DynamicData.dll, Mono.Data.SqliteClient.dll, System.Configuration.dll, System.IdentityModel.Selectors.dll, System.Web.Extensions.Design.dll, Mono.Data.Sqlite.dll, System.Configuration.Install.dll, System.Management.dll, System.Web.Extensions.dll, System.Core.dll, System.Messaging.dll, System.Web.Routing.dll, System.Data.DataSetExtensions.dll, System.Runtime.Serialization.dll, System.Web.Services.dll, Mono.Messaging.dll, System.Data.dll, System.Security.dll, System.Windows.Forms.dll, System.Data.Linq.dll, System.ServiceModel.dll, System.Xml.dll, Mono.Security.dll, System.Design.dll, System.ServiceModel.Web.dll, System.Xml.Linq.dll


Установить себе на устройство это чудо можно, добавив в sources.list следующую строку:
deb http_://archive.kebrum.com/n900/ all main

и установив пакет libmono-winforms2.0-cil, который потянет за собой всё остальное. К сожалению, пока больше никакие пакеты не переносил, ибо уже 4 утра, но обязательно этим займусь позже (мне же gtkшный софт переносить).

Если кто-то захочет перенести свой софт на C# на N900 с использованием этой сборки, обязательно свяжитесь со мной, чтобы я держал вас в курсе событий.

И не судите строго за орфографию с пунктуацией, ночь на дворе, глаза красны, очень спать хочется, да и по клавишам еле попадаю.

UPD: С помощью лома и какой-то матери перенесено GTK# (пока не всё). Ну и нехилый такой кусок mono, необходимый для пакета mono-devel.
Tags:
Hubs:
+34
Comments 25
Comments Comments 25

Articles