вторник, 19 марта 2013 г.

Портируем CMake проект на ARM Windows RT

CMake замечательная штука для создания действительно кросс платформенных проектов. В заметке несколько рецептов о том, как быстро портировать свой любимый проект на новую систему.
CMake из коробки умеет генерировать проекты для Visual Studio, и это предпочтительный способ сборки, если вы работаете на Windows. К большому сожалению, cmake до сих пор, даже в ночных сборках не научился опознавать компилятор под ARM и генерировать правильный проект. Ребята из Kitware активно работают над новой версией и обещают поддержку Windows RT к версии 2.8.11, а мы тем временем пойдём другим путём.
Быстрый пробег по поисковой выдаче Гугла даёт обсуждение на Stackoverflow. Начальная идея найдена. Можно генерировать не проект для Visual Studio, а Makefile для nmake. Достаточно правильно выставить переменные окружения. После такого фокуса CMake думает, что имеет дело со стандартным хостовым компилятором и ничего не знает про кросс компиляцию.
Конфигурация обычно проходит нормально, но запустив билд любого мало мальски серьёзного проекта мы получим сообщение об ошибке:
C:\Program Files\Microsoft Visual Studio 11.0\VC\INCLUDE\crtdefs.h(338):
fatal error C1189: #error: Compiling Desktop applications for the ARM platform is not supported.
Решение проблемы можно найти в crtdefs.h или в том же обсуждении. Достаточно добавить макрос ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE. Для cmake это лучше сделать функцией add_definitions. Он сам добавит макрос в нужном формате и там где надо:
project(MyFavouriteProject)
add_definitions(ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE)
... 
В большинстве случаев добавление макроса решает все проблемы, но это не всё. Настоящие кросс платформенные проекты часто используют разные системные и не очень инклюды, которые могут отличаються от платформы к платформе. Для проверки наличия того или иного заголовочного файла в cmake используется функция check_include_file. При вызове этой функции cmake автоматически создаёт маленькую программу на C\С++ с подключенным заголовком и пытается её скомпилировать. Если билд прошёл успешно, значит заголовок есть и можно идти дальше. Но причиной падения может быть не только отсутствие заголовочного файла, но и та же беда в crtdefs.h, если это файл прямо или косвенно входит в тестовую программу.
Причину провала таких тестов можно посмотреть в логах в директории CMakeFiles в билд каталоге вашего проекта. Для того, чтобы такие логи сохранялись в файл добавьте ключ --debug-trycompile в командную строку cmake'a при конфигурации. Макрос добавленный функцией add_definitions не попадает в список макросов при компиляции тестовых программ. Его надо добавить самостоятельно в переменную CMAKE_REQUIRED_DEFINITIONS:
project(MyFavouriteProject)
set(CMAKE_REQUIRED_DEFINITIONS -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE) 
add_definitions(ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE)
check_include_file(assert.h HAVE_ASSERT_H)
...
И ещё один маленький рецепт напоследок. Вместо nmake можно использовать Ninja. Инструмент быстро и легко собирается из исходного кода. Правда для старта ему нужен Python. Такая полезная в хозяйств штука у большинства разработчиков и так есть, поэтому никакой сложности сборка составить не должна. После сборки складываем единственный получившийся исполняемый файл куда вам нравится и добавляем этот путь в PATH. После этого в командной строке cmake заменяем -G "NMake Makefiles" на -GNinja и зовём ninja вместо nmake.
Ninja работает намного быстрее своего штатного аналога и сразу распараллеливает билд на все доступные системе процессоры. Проект развивается как замена обычному Unix mak'у, работает на множестве платформ и вообще отличная штука!

воскресенье, 10 марта 2013 г.

GDB Седержимое ВСЕХ регистов на ARM архитектуре

Недавно отлаживая очень странное падение нативного кода на Android телефоне с процессором, поддерживающем NEON, наткнулся на интересную особенность. Отладчик gdb из состава NDK-r8d по команде info registers показывает не все регистры для арифметики с плавающей точкой. Если точнее, то в дампе только первые 16, как будь то NEON расширения нет совсем. Как выяснилось чуть позднее, он ведёт себя так на ARM-v7a всегда. Чтобы посмотреть дополнительные регистры, надо сказать в  gdb консоли info all-registers.

четверг, 18 октября 2012 г.

Собираем ArDrone SDK на OpenSuse 12.2

Уже скоро приедет долгожданный квадрокоптер ArDrone 2.0, и в преддверии этого события я решил посмотреть на официальный SDK для этой машинки. Наибольший интерес для меня вызывает его линуксовая часть.
Всё что касается линукса, и не только него, написано на старом добром Си с не менее старыми и добрыми мейкфайлами. Судя по приложенному гайду для разработчиков (Docs/ARDrone_Developer_Guide.pdf, если вдруг кто-то его не нашёл) разработчики SDK ориентируются на Ubuntu 10.04. С ним всё хорошо, чего я не могу сказать про свой OpenSuse.

Решение, впрочем, очень простое:
  1. Ставим дополнительные пакеты с зависимостями. А Именно: libsdl-devel, libiw-devel, libxml2-devel. Но не исключаю, что вам может понадобиться что-то ещё.

  2. Идём в файлик Examples/Linux/Navigation/Build/Makefile и ищем там строку начинающуюся с переменной GENERIC_LIBS  и дописываем в конец через пробел -lm. Таким образом мы добавляем библиотеку libm к списку библиотек линкера. Без этого маленького довеска билд не идёт, завершаясь сообщением:

    usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: /usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../lib64/libiw.so: undefined reference to symbol 'floor@@GLIBC_2.2.5'
    /usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: note: 'floor@@GLIBC_2.2.5' is defined in DSO /lib64/libm.so.6 so try adding it to the linker command line
    /lib64/libm.so.6: could not read symbols: Invalid operation
    collect2: error: ld returned 1 exit status 

  3. После проделанных приготовлений переходим, как написано в инструкции, в Examples/Linux и зовём там make. Всё, что получилось, make складывает в Examples/Linux/Build/Release. У меня там: ardrone_navigation,  ardrone.xml,  common,  linux_sdk_demo, sym_ardrone_testing_tool, что вполне соответствует инструкции.

пятница, 12 октября 2012 г.

OpenCV4Android на MIPS архитектуре

Относительно недавно экосистему Android'a пополнили устройства на MIPS архитектуре. В месте с  появлением первых широко доступных устройств поддержка MIPS архитектуры появилась и в официальных NDK и SDK от Google. До этого инструменты для разработчика производитель развивал самостоятельно.
Но речь сейчас не об архитектуре так таковой, а о её поддержке в популярной библиотеке компьютерного зрения OpenCV. Сборка андроидной версии под MIPS была обеспечена ещё летом, но не было ни одного устройства на котором можно было бы "потрогать" полученный результат.
Недавно в руки попал девайс Novo 7 basic с SoC Ingenic JZ4770 на борту. С использованием открытого дерева Android для MIPS и системных библиотек, взятых с устройства, удалось построить плагин для нативной камеры. OpenCV чувствует себя на планшете вполне комфортно, тесты на core часть библиотеки проходят на ура. Примеры с Java камерой и нативной камерой в полном порядке. Кроме того, в OpenCV менеджер была добавлена экспериментальная поддержка этой архитектуры.
Судя по проделанной работе, официальную поддержку MIPS'a можно будет ожидать в будущих релизах библиотеки. Всем же, кому не терпится, могут попробовать библиотеку собрав её из публичного git репозитория.

воскресенье, 30 сентября 2012 г.

Intro

Доброго времени суток, всем кто читает этот блог. Это первое сообщение на блоге для проверки, а-ля "ping".

Пока здесь нет ничего полезного, но в ближайшее время здесь можно будет найти заметки на разнообразные темы касаемые Linux, Android, компьютерного зрения и робототехники. Т.е. всё то, чем я занимаюсь профессионально и в качестве хобби.