-
Некоторое время назад я получил заказ на разработку крупного приложения для GPS-навигаторов, которые «по науке» называются PNA — Personal Navigation Assistant. Ранее я работал с навигаторами, но никогда не общался с ними на языке Qt. Как ни странно, но велико было мое удивление, когда оказалось, что навигаторы работают на не совсем классических ОС и мои билды, успешно работающие во благо мобильников и «продвинутых» навигаторов оказались бессильны.
Как можно догадаться, это меня не остановило. Пришлось пошерстить интернет в поисках нужной информации. Увы, четкого ответа на все вопросы, меня интересующие, найти в одном месте не удалось — все пришлось собирать по крупицам, в большинстве случаев методом тыка проверяя «а что получится?».
Итак, сборки давно уже сделаны и прекрасно работают. В таком случае, позволю себе быть может повториться, но собрать воедино выводы, полученные мной в этом процессе.
Начну с краткого отступления на тему «области исследования». Предлагаю имеющим навигатор перевернуть его и посмотреть на наклейку с именем системы. С большей долей вероятности, если таковая присутствует, то она будет содержать на себе надпись Windows Embedded CE 5.0 (6.0) Core. Логично предположить, что это классический WinCE нужной нам циферьки. Увы, слово Core в достаточной степени портит нам жизнь.
Вообще, есть пласт устройств, которые не являются по своей сути многофункциональными — к примеру, упомянутые навигаторы. В таком случае зачем нагружать их бедную маленькую память и процессор совершенно не нужными для них процессами, библиотеками и т.п.? Правильно, незачем. Компания Microsoft сделала подарок пользователями — облегчила систему, путем создания из WinCE некоего конструктора, используемого по частям для нужд производителя. Причем сам производитель может делать свой собственный «микробилд» (или же вообще целиком свою сборку, если речь идет о WinCE Embedded 6). Очевидно, что это не добавляет нам радости как создателям ПО.
Речь о «модернизации PNA» — это отдельный разговор, поэтому я не буду обсуждать тему зачем нам это надо. Ответ простой — просто надо. Что такое Qt и какие у нее возможности — это так же отдельный разговор.
Поэтому вернемся к Qt и непосредственно к процессу сборки.
Итак, нам потребуется:
Акцентирую ваше внимание на том, что нам потребуется именно 2005ая версия студии. Как показала практика, 2008ая «плохо дружит» с Qt для «обычного» WinCE, отчего в интернете полно вопросов «а чего не работает?». Второй пункт — это выбор SDK. Для Windows Embedded 5.0Core нужно именно стандартное SDK нужной версии, без всяких там Mobile. Версия под номером 6.0 будет рассмотрена в другой раз, т.к. стандартного SDK для нее не существует, так что там есть свои ньюансы.
Запускаем Visual Studio 2005 Command Prompt, переходим в каталог с распакованными исходниками Qt. Наступает важнейший этап нашей эпопеи — конфигурирование.
configure -platform win32-msvc2005 -xplatform wince50standard-armv4i-msvc2005 -debug-and-release -nomake examples -nomake demos -no-accessibility -D QT_NO_CURSOR -D QT_NO_DRAGANDDROP -D QT_NO_CLIPBOARD -D QT_NO_ACCESSIBILITY -D QT_NO_SESSIONMANAGER
Приведенная выше конфигурация — некая «основа» для устройств типа навигаторов, по большей части за счет параметров -D и исключения демок и примеров. Все, что идет с -D — это как раз таки издержки «конструкторской» основы Core систем — чаще всего на навигаторах эти возможности вырезаны, поэтому если вы не отключите их сейчас, то на стадии линковки проект будет умирать. Собственно, по этим же причинам из конфигурации исключены демки и примеры — сами тролли писали, что в этом кроется проблема билда — многие из примеров так или иначе используют тот же QT_CURSOR и т.п.
Также хочу заметить, что для релиза своего приложения не поленитесь и создайте статическую сборку Qt — это значительно убыстряет как запуск приложения, так и его работу. Это можно сказать «правильно №1″ при программировании на WinCE.
В общем, ждем пока произойдет конфигурирование. После него консоль предложит нам установить пути к WinCE SDK, упомянув «автоматический способ». Все верно, но почему-то не указано, что изначально стоит перейти в папку /bin и только там воспользоваться их утилитой. Таким образом, для запуска процесса сборки получаем:
cd bin setcepaths.bat wince50standard-armv4i-msvc2005 cd ../ nmake
Дальнейший процесс сводится к ожиданию заветной сборки. Если все сделано как описано выше, проблем возникнуть не должно.
Повторюсь, что основой многих проблем, связанных не столько со сборкой Qt, сколько со сборкой и запуском конечного приложения на навигаторе является игнорирование флагов -D QT_NO_CURSOR -D QT_NO_DRAGANDDROP -D QT_NO_CLIPBOARD -D QT_NO_ACCESSIBILITY -D QT_NO_SESSIONMANAGER в процессе сборки Qt.
Вкратце, это основа для нужной нам сборки. Можем приступать к работе :)
Спасибо тов. thedimitrius - во время написания данной мини-статьи я совершенно забыл упомянуть про тот маленький факт, что вне зависимости от того, как собрана библиотека, исходники то остаются теми же самыми, и если при компиляции проекта не указать данные defines, компилятор так же будет обрабатывать «запрещенные нами» функции, и если вы получили сообщение, аналогичное представленном ниже, не пугайтесь.
mainwindow.obj : error LNK2001: unresolved external symbol "protected: virtual void __cdecl QWidget::dragEnterEvent(class QDragEnterEvent *)" (?dragEnterEvent@QWidget@@MAAXPAVQDragEnterEvent@@@Z) mainwindow.obj : error LNK2001: unresolved external symbol "protected: virtual void __cdecl QWidget::dragMoveEvent(class QDragMoveEvent *)" (?dragMoveEvent@QWidget@@MAAXPAVQDragMoveEvent@@@Z) mainwindow.obj : error LNK2001: unresolved external symbol "protected: virtual void __cdecl QWidget::dragLeaveEvent(class QDragLeaveEvent *)" (?dragLeaveEvent@QWidget@@MAAXPAVQDragLeaveEvent@@@Z) mainwindow.obj : error LNK2001: unresolved external symbol "protected: virtual void __cdecl QWidget::dropEvent(class QDropEvent *)" (?dropEvent@QWidget@@MAAXPAVQDropEvent@@@Z)
Решение этой проблемы кроется в указании необходимых дефайнов в «С/С++ — Command Line — Additional options» разделе свойств проекта:
/D "QT_NO_DRAGANDDROP" /D "QT_NO_DRAGANDDROP" /D "QT_NO_CLIPBOARD" /D "QT_NO_ACCESSIBILITY" /D "QT_NO_SESSIONMANAGER"
Я понимаю, что это только ликбез, поэтому если у вас возникли какие-то вопросы, либо приложение не запускается на навигаторе, коммуникаторе и прочих устройствах, есть проблемы со сборкой или установкой приложения — вы всегда можете связаться со мной, я постараюсь помочь.
С уважением,
тов. ufna
Comments
А скажите, в таком варианте сборки Qt есть поддержка QXmlPatterns?
Не проверял, но должна быть — я не вижу ничего этому препятствующего. Если в стандартной сборке есть, то будет и здесь.
А я вот сталкнулся с проблемой такого рода:
При сборке Qt 4.6.3-opensource-everywhere с флагами configure.exe -platform win32-msvc2005 -xplatform wince50standard-armv4i-msvc2005 -no-openssl -no-webkit -no-qt3support -no-scripttools -no-libmng -debug-and-release -opensource библиотека QXmlPatterns не собиралось, вычитал на Qt-interest, что к сборке нужно добавлять флаги -exceptions -xmlpatterns и тогда поддержка QxmlPatterns будет.
Возможно это будет полезно для этой статьи (для Windows CE).
ufna, какие размеры либ/бинарников получаются?
Не пробовал собирать с -no-exceptions?
woldemar,
Спасибо за информацию, не знал. Кстати, стоит добавить, что для статичной сборки с QXmlPatterns нужно -static указывать до -xml-patterns, желательно сразу после указания платформы.
alex,
Размеры посмотрю ближе к вечеру, а с -no-exceptions собираю постоянно, дабы сократить объем и повысить скорость работы. Для wince в принципе желательно отрубать все, что не используется.
Почему-то после сборки Qt под Windows Mobile 5.0 как статическую.
configure.exe -static -release -D NO_GETENV -D QT_NO_DRAGANDDROP -D QT_NO_ACCESSIBILITY -D QT_NO_SESSIONMANAGER -nomake examples -nomake demos -no-webkit -no-qt3support -no-opengl -qt-zlib -qt-libpng -platform win32-msvc2008 -xplatform wincewm50pocket-msvc2008
И перестало работать меню. В полноэкранном режиме (showFullScreen()) его просто нет. В оконном режиме (showMaximized()) остается меню от проводника (при запуске программы из проводника).
Подскажите как побороть это? Меню очень нужно.
Разобрался оказывается если Qt используется статически, то нужно еще подключать qmenu_wince.res
Александр,
Да, Вы правы — в статической сборки необходимо подключать qmenu_wince.res . Эти вещи к сожалению не очевидны и об этом мало где написано, однако они на автомате прописаны в линковке в MSVS если создавать новый проект на основе статической сборки.
Стоит наверное так же отметить, что для статической сборки следует также линковать следующие системные библиотеки:
corelibc.lib
ole32.lib
oleaut32.lib
uuid.lib
commctrl.lib
coredll.lib
winsock.lib
ceshell.lib
qmenu_wince.res
Для модуля QNetwork так же необходимо линковать ws2.lib, иначе полезут unresolved external для WSA.
Про -no-exceptions потому и спрашивал, что проброс эксепшинов отъедает кучу ресурсов и во многих Qt приложениях не используется.
А qconfig пробовал?
http://doc.qt.nokia.com/4.7/fine-tuning-features.html
Реально так просто всё повыкидывать, проблем нет? И сильно ли при этом бинарники уменьшаются?
Ещё видимо shadow builds полезно пользовать.
http://doc.qt.nokia.com/4.7/shadow-builds-wince.html
Пока не пробовал, но давно мысля про автонавигатор с ВинЦЕ покоя не даёт. Правда пока не придумал чего бы полезного написать. :)
Cовершенно верно, для нового проекта создается зависимость c qmenu_wince.res (именно так я и нашел, создал новый проект, проверил, заработало, начал искать отличия от своего). Просто у меня изначально проект был под динамическую сборку Qt. Память на КПК естественно кончилась быстро (использовал QtGui, QtNetwork, QtXml, плюс еще libvorbis — звук вывожу через waveOut*****() ).
Windows Mobile резервирует память под всю Dll, и подгружает только функции которые используются. Да еще и на один процесс ограничение в 32 мегабайта.
alex,
qconfig реально не применял — раньше он был очень сырым и глючным. В 4.7 пока еще не проверял :)
shadow builds — это уже как удобнее, на производительность и объем на конечном устройстве это не влияет, мне к примеру удобнее держать кучу сборок для своих нужд со своими исходиками.
А писать можно что угодно, советую посмотреть QML — там сразу идеи так и прут :) (правда нужно протестировать быстродействие на навигаторах — они медленнее современных кпк)
Александр,
Сами Тролли пишут что для мобильных платформ очень рекомендуется статичная сборка — да и это правильно :) я тоже начинал с динамической сборки, но быстро уперся в память и быстродействие — статическая сборка не только жрет меньше памяти, но и быстрее работает. Ну а 30 мб (реально 30-31, а не 32) — хорошее испытание для программиста как проектировщика, да и в реализации нужно знать свое дело в совершенстве :)
ufna,
Подскажи а куда в конфигах будет правильнее воткнуть опцию компилятору /QRthumb, чтобы тот генерировал Thumb код, тоже удасться съэкономить процетов 20% занимаемой Qt памяти.
Александр,
При компиляции самой Qt — если честно, то даже не знаю. Никогда с этим тегом не работал, т.к. пришел к мобильным устройствам только с Qt, а для Qt о таком впервые слышу, поиск в интернете так же ничего не дал.
В принципе, если только сам проект попробовать скомпилировать с этим свойством и оно будет работать, то можно попробовать и Qt с ним собрать.
Вчера таки собрал под wince50standard-armv4i-msvc2005. Правда не без танцев с бубном.
Точно про танцы уж не помню…
Сначала собирал как ufna, но версию 4.7.0, поломалось на qmlXXXX, но это видимо уже после самой либы тулсы компилялись.
nmake sub-src — помогает.
Потом ещё шаманил, чего то. Потом библиотек какихто не хватило в девайсэмуляторе.
Решил статиком скомпилять. Скомпилялось нормально, но пример вот не захотел линковаться, не хватило getenv() в libjpeg-е. Пришлось ещё поискать инфы, в результате поправил QTDIR\src\3rdparty\libjpeg.pri, добавил туда
wince*: {
DEFINES += NO_GETENV
}
И ура, бинарник (а это почемуто был spinboxes из примеров) собрался.
Но в девайсэмуляторе опять не запустился из-за недостатка либ. Пришлось скачать PEInfo под CE, выяснил что не хватает msvcr80.dll, подкинул в каталог девайсэмулятора соответствующую версию из SDK — и ура, заработало, правда в экран пример не влез, но это уже другая песня. :)
Бинарник получился 5760Кб, понятно что там много лишнего, и при желании многое можно выкинуть.
Александр, в моём
QTDIR\mkspecs\wince50standard-armv4i-msvc2005\qmake.conf
есть
QMAKE_CFLAGS += -QRarch4T -QRinterwork-return
QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:WINDOWSCE,5.00 /MACHINE:THUMB /ENTRY:mainACRTStartup
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWSCE,5.00 /MACHINE:THUMB
QMAKE_LFLAGS_DLL = /SUBSYSTEM:WINDOWSCE,5.00 /MACHINE:THUMB /DLL
Видимо там, или по аналогии в соответствующих спексах.
А по дефолту кстати как компиляется?
alex,
Про танцы с QML — все решается очень просто :)
1. QML нужен — убираем флаги -D QT_NO_CURSOR -D QT_NO_DRAGANDDROP
2. QML не нужен — добавляем -no-declarative
Если ругается на getenv(), то собираем Qt с флагом -D NO_GETENV
А msvcr80.dll и т.п. — это классика, это чисто от компилятора MSVS, это две разные «статики» :)
За конфиги спасибо, кажется Thumb по-умолчанию включен.
Размер бинарника в семерке еще не смотрел. В 4.6.3 размер очень большой проги у меня почти 5Мб, примеры — в районе 3Мб.
getenv() — это только для libjpeg, кстати для плагина эти
wince*: {
DEFINES += NO_GETENV
}
прописаны в QTDIR\src\plugins\imageformats\jpeg\jpeg.pro .
А вот в QTDIR\src\3rdparty\libjpeg.pri почемуто забыли.
Про классику с msvcr80.dll — оно понятно, просто меня напрягло то что в ВинЦЕ не говорят про то каких именно ДЛЛ-ок не хватает, а всемирный разум — инет, на тот момент был недоступен. :)
замена -MD на -MT помогает избавиться от msvcr80.dll, и получается только один бинакник (понятно что всякие coredll должны при этом присутствовать в ВинСЕ). Я менял QMAKE_CFLAGS_RELEASE в QTDIR\mkspecs\common\wince\qmake.conf
Про thumb не уверен, но есть подозрение что -QRarch4T говорит компиллеру что thumb есть (буква T), а далее компиллер может уже на основании опций оптимизатора (по размеру/скорости и т.д.) генерить как thumb так и ARM код. В Qt по дефолту -O2. Но не уверен, надо доки по MS-компиллеру курить, а я в основном GCC пользую.
Прикольно, а для включения libjpeg какой флаг при сборке? Надо будет на 4.7.0 проверить, на 4.6.3 с jpeg вроде все было ок.
На WinCE реально прикольно что не говорит чего ему не хватает )) Я когда под нее начинал, с бубном побегал, учитывая что для запуска на WinCE 5.0 Core еще пару dll обычно нужно, кроме тех что «учтены».
ufna, Thumb по умолчанию выключен проверено. Для того чтобы студия собирала код под Thumb нужно компилятору подставить опцию /QRthumb — пробовал в лоб подставить в конфиги…. не прокатило. Начал ругаться на сборке чего-то связанного с MMX.
Добавлял насколько помню на в скидку в файл:
\mkspecs\common\wince\qmake.conf
в эту строчку
QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t-
т.е. получилось нечто вроде:
QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t- /QRthumb
P.S. Пишу не уверенно ибо сборка эта лежит дома.
Нашлась ошибка в Qt 4.7 под WM, в полноэкранном режиме.
Если сделать полноэкранное приложение с тулбаром, и вызвать:
addToolBar(Qt::BottomToolBarArea, ui.mainToolBar);
т.е. чтобы тулбар был внизу, тогда получается что тулбар находится под меню (это отчетливо видно, если у тулбара задать размер иконок
ui.mainToolBar->setIconSize(QSize(32, 32));
Можно ли это как-то исправить?
Добрался я до сборки Qt под систему комманд Thumb — собралось. Приложение стало занимать на 1Мб оперативки меньше, только благодаря пересборки Qt. Если интересно кому расскажу как.
Александр, было бы очень интересно, если не сложно. Оптимизация по памяти — важнейшая вещь для мобильных устройств.
Сборка Qt под режим процессора Thumb для WinCE
1. Открывем файл mkspecs\common\wince\qmake.conf
2. Ищем строчку
QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t-
и добавляем в конец /QRthumb получим строчку вида:
QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t- /QRthumb
3. Конфигурируем Qt (я отключил все не нужное плюс обязательно нужно отключить MMX и прочие расширения системы команд):
configure.exe -static -release -no-exceptions -D QT_NO_CURSOR -D QT_NO_DRAGANDDROP -D QT_NO_CLIPBOARD -D NO_GETENV -nomake examples -nomake demos -no-qmake -no-accessibility -no-rtti -qt-zlib -qt-libpng -no-gif -no-libtiff -no-libjpeg -no-libmng -no-qt3support -no-mmx -no-3dnow -no-sse -no-sse2 -no-iwmmxt -no-openssl -no-dbus -no-phonon -no-phonon-backend -no-multimedia -no-audio-backend -no-script -no-scripttools -no-webkit -platform win32-msvc2008 -xplatform wincewm50pocket-msvc2008
4. Запускаем заранее подготовленный утилиткой из Qt батник примерно такого содержания:
echo Environment Selection:Windows Mobile 5.0 Pocket PC SDK (ARMV4I)
set PATH=c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_arm;c:\Program Files\Microsoft Visual Studio 9.0\VC\bin;$(WindowsSdkDir)\bin;c:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools;c:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE;c:\Program Files\Microsoft Visual Studio 9.0\Common\Tools;c:\Program Files\Microsoft Visual Studio 9.0\Common\IDE;c:\Program Files\Microsoft Visual Studio 9.0\;$(FrameworkSDKDir)Bin;%PATH%
set INCLUDE=c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\include;C:\Program Files\Windows Mobile 5.0 SDK R2\PocketPC\include\ARMV4I;C:\Program Files\Windows Mobile 5.0 SDK R2\PocketPC\include;c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\atlmfc\include;c:\Program Files\Microsoft Visual Studio 9.0\SmartDevices\SDK\SQL Server\Mobile\v3.0
set LIB=C:\Program Files\Windows Mobile 5.0 SDK R2\PocketPC\lib\ARMV4I;c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\atlmfc\lib\ARMV4I;c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\lib\ARMV4I
5. Собираем Qt
nmake sub-src
После сборки можно использовать, только не забываем в свой проект компилятору добавить /QRthumb (и если используются какие-то еще .lib файлы то их тоже необходимо пересобрать с /QRthumb).
Как результат получим примерно на 1Мб больше свободной оперативки.
Привет ufna. Спасибо за статью, но случайно нет похожей в закромах про сборку под Windows CE 6.0 с кастомным SDK? или вообще сборку под 6.0?
Привет!
В принципе, все шаги аналогичны, только пути INCLUDE и т.п. вручную прописать нужно
Спасибо огромное автору! Собрал рабочую версию прочтя эту статью :)
Здравствуйте, не могу сделать статическую сборку для wince. Вот батник, которым я собираю:
set QTDIR=C:\QTWinCEARM
set QTPATH=%QTDIR%
set QT_INSTALL_BINS=%QTDIR%\bin
@echo off
call «C:\Program Files (x86)\Microsoft Visual Studio 8\VC\vcvarsall.bat» x86
pause
nmake confclean
call configure.exe -platform win32-msvc2005 -xplatform wince50standard-armv4i-msvc2005 -static -qt-sql-sqlite -release -D NO_GETENV -D QT_NO_DRAGANDDROP -D QT_NO_ACCESSIBILITY -D QT_NO_SESSIONMANAGER -nomake examples -nomake demos -no-webkit -no-qt3support -no-opengl -qt-zlib -qt-libpng
pause
cd bin
call setcepaths wince50standard-armv4i-msvc2005
cd ..
pause
nmake
pause
После запуска nmake, идет сборка и вылетает ошибка:
.\qmlruntime.cpp(122) : error C2027: use of undefined type ‘QDragEnterEvent’
c:\qtwincearm\include\qtgui\../../src/gui/kernel/qwidget.h(88) : see dec
laration of ‘QDragEnterEvent’
.\qmlruntime.cpp(122) : error C2227: left of ‘->mimeData’ must point to class/st
ruct/union/generic type
.\qmlruntime.cpp(124) : error C2027: use of undefined type ‘QDragEnterEvent’
c:\qtwincearm\include\qtgui\../../src/gui/kernel/qwidget.h(88) : see dec
laration of ‘QDragEnterEvent’
.\qmlruntime.cpp(124) : error C2227: left of ‘->acceptProposedAction’ must point
to class/struct/union/generic type
.\qmlruntime.cpp(129) : error C2027: use of undefined type ‘QDragMoveEvent’
c:\qtwincearm\include\qtgui\../../src/gui/kernel/qwidget.h(89) : see dec
laration of ‘QDragMoveEvent’
.\qmlruntime.cpp(129) : error C2227: left of ‘->acceptProposedAction’ must point
to class/struct/union/generic type
.\qmlruntime.cpp(134) : error C2027: use of undefined type ‘QDragLeaveEvent’
c:\qtwincearm\include\qtgui\../../src/gui/kernel/qwidget.h(90) : see dec
laration of ‘QDragLeaveEvent’
.\qmlruntime.cpp(134) : error C2227: left of ‘->accept’ must point to class/stru
ct/union/generic type
.\qmlruntime.cpp(139) : error C2027: use of undefined type ‘QDropEvent’
c:\qtwincearm\include\qtgui\../../src/gui/kernel/qwidget.h(91) : see dec
laration of ‘QDropEvent’
.\qmlruntime.cpp(139) : error C2227: left of ‘->mimeData’ must point to class/st
ruct/union/generic type
.\qmlruntime.cpp(146) : error C2027: use of undefined type ‘QDropEvent’
c:\qtwincearm\include\qtgui\../../src/gui/kernel/qwidget.h(91) : see dec
laration of ‘QDropEvent’
.\qmlruntime.cpp(146) : error C2227: left of ‘->accept’ must point to class/stru
ct/union/generic type
proxysettings.cpp
qdeclarativetester.cpp
loggerwidget.cpp
deviceorientation.cpp
main.cpp
Generating Code…
NMAKE : fatal error U1077: ‘»C:\Program Files (x86)\Microsoft Visual Studio 8\VC
\ce\bin\x86_arm\cl.EXE»‘ : return code ’0×2′
Stop.
NMAKE : fatal error U1077: ‘»C:\Program Files (x86)\Microsoft Visual Studio 8\VC
\bin\nmake.exe»‘ : return code ’0×2′
Stop.
NMAKE : fatal error U1077: ‘cd’ : return code ’0×2′
Stop.
NMAKE : fatal error U1077: ‘cd’ : return code ’0×2′
Stop.
Для продолжения нажмите любую клавишу . . .
В чем причина. Хочу именно статическую сборку, потому как динамическая у меня на эмуляторе не завелась(