Привет!
Эта небольшая статья адресована разработчикам приложений под мобильную платформу Samsung Bada, которые не желают мириться с мыслью, что Samsung «знает лучше, что надо», а также людям, занимающимся сборкой кода под ARM с помощью GNU Compiler Collection.
Думаю, многие замечали, что при сборке проекта в Target-Release или Target-Debug пишется лог наподобие
Нас будут интересовать флаги сборки, т.е. часть
В свойствах проекта можно добавлять свои флаги, но вот незадача: они все приписываются слева, а кусок
вообще статичный и всегда дописывается справа, и в IDE про него ни слова. Более того, опция "-Os" — неизменяемая в свойствах проекта («серая»). Поясню, что происходит.
Итак, видим следующую несправедливость:
Позицию Samsung можно понять: шаловливые руки, изменив упомянутые флаги, запросто могут запороть сборку проекта, а корейской службе поддержки потом им доказывать, кто они на самом деле. Однако, мы с вами знаем, что делаем. Сможем ли мы исправить ситуацию? Да!
Обратим внимание на файл <корень Bada SDK>/IDE/buildoptions.xml. Там как раз и содержится набор флагов, который нельзя изменить обычным человеческим способом через IDE. После редактирования этого файла, не забудьте перезапустить Eclipse. Оттягиваемся по-полной:
-mthumb заставляет собирать Thumb код, -O2 нормально оптимизирует программу, а теперь уже бессмысленный -mthumb-interwork убран. Я проверил работу при таких флагах на множестве программ, и все они работают как надо. Замечу две вещи:
Что же мы видим во флагах сборки на устройства Bada 1.1 (линейка бюджетных Wave, вроде 52x)?
Во-первых, в глаза бросается убогий процессор, о котором вообще не написано в спецификации на официальном сайте Samsung, а также -mfloat-abi=soft, из-за которого FPU вообще не используется. В спецификации ARM9 на arm.com указано, что FPU действительно опционален. У меня этих устройств нет, и я не могу точно сказать, хорошая ли идея поменять этот флаг на -mfloat-abi=softfp или -mfloat-abi=hard. Зато я снова рекомендую добавить -mthumb.
Дам совет тем, у которых много вычислений с плавающей точкой: добавьте в флаги проекта (обычным способом) флаги -funsafe-math-optimizations -ffast-math. Не пожалеете.
Напоследок ссылка на все флаги GCC, специфичные для ARM.
Спасибо за внимание, удачной вам разработки!
Эта небольшая статья адресована разработчикам приложений под мобильную платформу Samsung Bada, которые не желают мириться с мыслью, что Samsung «знает лучше, что надо», а также людям, занимающимся сборкой кода под ARM с помощью GNU Compiler Collection.
Думаю, многие замечали, что при сборке проекта в Target-Release или Target-Debug пишется лог наподобие
arm-samsung-nucleuseabi-g++ -DSHP -I"D:/Work/Bada/1.2.1/include" -I"???/inc" -Os -Wall -E -fpic -fshort-wchar -mcpu=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard -mlittle-endian -mthumb-interwork -o"???/Target-Release/dirent.i" "../src/bada/dirent.cpp"
'Finished building: ../src/bada/dirent.cpp'
Нас будут интересовать флаги сборки, т.е. часть
-Os -Wall -E -fpic -fshort-wchar -mcpu=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard -mlittle-endian -mthumb-interwork
В свойствах проекта можно добавлять свои флаги, но вот незадача: они все приписываются слева, а кусок
-fpic -fshort-wchar -mcpu=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard -mlittle-endian -mthumb-interwork
вообще статичный и всегда дописывается справа, и в IDE про него ни слова. Более того, опция "-Os" — неизменяемая в свойствах проекта («серая»). Поясню, что происходит.
- -Os — применяются только оптимизации, не увеличивающие размер объектника
- -fpic — сборка по Position Independant Code relocation model. Напоминаю, что все результаты (т.н. артефакты) сборки на Bada Toolchain — динамические библиотеки (shared library). Для кого это новость — можете также посмотреть на типичный код <ИмяПроекта>Entry.cpp:
Если скакнуть на определение _EXPORT_, то увидим (FBaseConfig.h):_EXPORT_ int OspMain(int argc, char *pArgv[])
Это я все для чего? Так вот, PIC — надежная, но слегка медленная модель. Тем более, учитывая, что в Bada все приложения находятся в своих песочницах и не могут делить общие динамические библиотеки — бессмысленно использовать PIC. К сожалению, без этого флага сборка проекта может падать на этапе линковки динамической библиотеки (и падает, я проверял), т.к. ld (в исполнении arm-samsung-nucleusabi-ld) не умеет линковать в некоторых случаях, поэтому корейцы из Samsung зашили этот флаг внутрь. Из-за недоработки в GCC 4.x компилятор делает релок R_ARM_MOVW_ABS_NC, который не любят в binutils. Вот если бы сборка была с помощью LLVM… Я что-то увлекся. В общем, в данной ситуации без -fPIC не обойтись.#if defined(_WIN32) // MS Compiler & MinGW GCC<br/>
# define _EXPORT_ __declspec(dllexport)<br/>
#elif defined(__GNUG__) // GCC<br/>
# define _EXPORT_ __attribute__((visibility("default")))<br/>
#elif defined(__ARMCC_VERSION) // ARM Compiler (RVCT 3.1)<br/>
# define _EXPORT_<br/>
#else<br/>
# define _EXPORT_<br/>
#endif
- -mfpu=vfpv3 — версия модели вычислений с плавающей точкой
- -mfloat-abi=hard — использовать только «железные» операции с плавающей точкой. Вообще говоря, если в коде встречается вызов функции с плавающей точкой, которой нет в ARM FPU, то компиляция упадет, но это очень маловероятно.
- -mlittle-endian — непонятно зачем, т.к. про Cortex-A8 и так известно, что он little endian.
- -mthumb-interwork — возможность безопасно сочетать в одном исполняемом файле код как ARM, так и Thumb. Как известно, ARM архитектура хороша помимо всего прочего еще и тем, что содержит набор 16-битных инструкций Thumb. Смысл в том, что одна ARM инструкция занимает 32 бита, а Thumb инструкция — в два раза меньше. Итого имеем сокращение размера результирующего кода в два раза (теоретически). Практически — почти в два раза (там есть накладные расходы в виде дополнительных операций и еще кое-что). По умолчанию сборка проходит в ARM код, в Thumb код программа может вообще не скомпилироваться (кто там например любит «оптимизированные» ассемблерные вставки? Наши компиляторщики кроют таких матом), в прошивке Samsung Wave скорее всего код Thumb, и корейцы перестраховались. В качестве минуса — размер объектников немного растет из-за дополнительных инструкций сопряжения.
Итак, видим следующую несправедливость:
- Не всегда оптимизация на размер исполняемого файла предпочтительней (особенно для системных, алгоритмических вещей!)
- mfpu=vfpv3 это, конечно, хорошо, но у кортекса есть NEON
- Проекты собираются в набор инструкций ARM вместо «няшного» Thumb
Позицию Samsung можно понять: шаловливые руки, изменив упомянутые флаги, запросто могут запороть сборку проекта, а корейской службе поддержки потом им доказывать, кто они на самом деле. Однако, мы с вами знаем, что делаем. Сможем ли мы исправить ситуацию? Да!
Обратим внимание на файл <корень Bada SDK>/IDE/buildoptions.xml. Там как раз и содержится набор флагов, который нельзя изменить обычным человеческим способом через IDE. После редактирования этого файла, не забудьте перезапустить Eclipse. Оттягиваемся по-полной:
<comp>-fpic -mthumb -fshort-wchar -O2 -mcpu=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard</comp>
-mthumb заставляет собирать Thumb код, -O2 нормально оптимизирует программу, а теперь уже бессмысленный -mthumb-interwork убран. Я проверил работу при таких флагах на множестве программ, и все они работают как надо. Замечу две вещи:
- Если сделать -mfpu=neon, приложения падают при запуске на устройстве. Почему — не ясно, я этот момент исследую. На работе на тестовых бордах так много раз делал.
- -mthumb-interwork возможно, все-таки будет нужен в некоторых частных случаях. Я прогнал тесты — без него отлично все работает.
Что же мы видим во флагах сборки на устройства Bada 1.1 (линейка бюджетных Wave, вроде 52x)?
<comp>-fpic -fshort-wchar -mcpu=arm9 -mfloat-abi=soft -mlittle-endian -mthumb-interwork</comp>
Во-первых, в глаза бросается убогий процессор, о котором вообще не написано в спецификации на официальном сайте Samsung, а также -mfloat-abi=soft, из-за которого FPU вообще не используется. В спецификации ARM9 на arm.com указано, что FPU действительно опционален. У меня этих устройств нет, и я не могу точно сказать, хорошая ли идея поменять этот флаг на -mfloat-abi=softfp или -mfloat-abi=hard. Зато я снова рекомендую добавить -mthumb.
Дам совет тем, у которых много вычислений с плавающей точкой: добавьте в флаги проекта (обычным способом) флаги -funsafe-math-optimizations -ffast-math. Не пожалеете.
Напоследок ссылка на все флаги GCC, специфичные для ARM.
Спасибо за внимание, удачной вам разработки!