Как (перекрестно) скомпилировать как ARM hard-, так и soft-float (softfp) с помощью одного GCC (cross-) компилятора?
Я хотел бы использовать один (кросс-) компилятор для компиляции кода для различных соглашений о вызовах ARM: так как я всегда хочу использовать инструкции с плавающей запятой и NEON, я просто хочу выбрать соглашение о вызовах с плавающей запятой или soft-float (softfp) соглашение о вызовах.
Мой компилятор по умолчанию использует hard-float, но он поддерживает обе архитектуры, которые мне нужны:
$ arm-linux-gnueabihf-gcc -print-multi-lib
.;
arm-linux-gnueabi;@marm@march=armv4t@mfloat-abi=soft
$
Когда я компилирую с параметрами по умолчанию:
$ arm-linux-gnueabihf-g++ -Wall -o hello_world_armhf hello_world.cpp
Это удается без каких-либо ошибок.
Если я скомпилирую с параметрами, возвращаемыми -print-multi-lib:
$ arm-linux-gnueabihf-g++ -marm -march=armv4t -mfloat-abi=soft -Wall -o hello_world hello_world.cpp
Он снова компилируется без ошибок (Кстати, как я могу проверить, что результирующий код является хард-или софт-плавающим?)
К сожалению, если я попробую это:
$ arm-linux-gnueabihf-g++ -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon -Wall -o hello_world hello_world.cpp
[...]/gcc/bin/../lib/gcc/arm-linux-gnueabihf/4.7.3/../../../../arm-linux-gnueabihf/bin/ld: error: hello_world uses VFP register arguments, /tmp/ccwvfDJo.o does not
[...]/gcc/bin/../lib/gcc/arm-linux-gnueabihf/4.7.3/../../../../arm-linux-gnueabihf/bin/ld: failed to merge target specific data of file /tmp/ccwvfDJo.o
collect2: error: ld returned 1 exit status
$
Я протестировал некоторые другие перестановки параметров, но кажется, что что-либо, кроме комбинации, показанной -print-multi-lib, приводит к ошибке.
Я прочитал ошибку компиляции ARM, зарегистрированный VFP используется исполняемым файлом, а не объектным файлом, но проблема заключалась в том, что некоторые части двоичного файла были программными, а некоторые - жестко плавающими. У меня есть один файл C++ для компиляции...
Какие параметры мне не хватает, чтобы иметь возможность компилировать с -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon?
Как это возможно, что ошибка связана с аргументами регистра VFP, в то время как у меня явно есть -mfloat-abi = softfp в командной строке, которая запрещает аргументы регистра VFP?
Спасибо!
Для записей hello_world.cpp содержит следующее:
#include <iostream>
int main()
{
std::cout << "Hello, world!" << std::endl;
return 0;
}
2 ответа
Вам нужен другой компилятор с соответствующей поддержкой multilib. Вы можете проверить поддержку multilib следующей командой.
arm-none-eabi-gcc -print-multi-lib
.;
thumb;@mthumb
fpu;@mfloat-abi=hard
armv6-m;@mthumb@march=armv6s-m
armv7-m;@mthumb@march=armv7-m
armv7e-m;@mthumb@march=armv7e-m
armv7-ar/thumb;@mthumb@march=armv7
cortex-m7;@mthumb@mcpu=cortex-m7
armv7e-m/softfp;@mthumb@march=armv7e-m@mfloat-abi=softfp@mfpu=fpv4-sp-d16
armv7e-m/fpu;@mthumb@march=armv7e-m@mfloat-abi=hard@mfpu=fpv4-sp-d16
armv7-ar/thumb/softfp;@mthumb@march=armv7@mfloat-abi=softfp@mfpu=vfpv3-d16
armv7-ar/thumb/fpu;@mthumb@march=armv7@mfloat-abi=hard@mfpu=vfpv3-d16
cortex-m7/softfp/fpv5-sp-d16;@mthumb@mcpu=cortex-m7@mfloat-abi=softfp@mfpu=fpv5-sp-d16
cortex-m7/softfp/fpv5-d16;@mthumb@mcpu=cortex-m7@mfloat-abi=softfp@mfpu=fpv5-d16
cortex-m7/fpu/fpv5-sp-d16;@mthumb@mcpu=cortex-m7@mfloat-abi=hard@mfpu=fpv5-sp-d16
cortex-m7/fpu/fpv5-d16;@mthumb@mcpu=cortex-m7@mfloat-abi=hard@mfpu=fpv5-d16
https://stackru.com/questions/37418986/how-to-interpret-the-output-of-gcc-print-multi-lib
Как интерпретировать вывод gcc-print-multi-lib
С этой конфигурацией gcc -mfloat-abi=hard
не только создаст ваши файлы без инструкций FPU, но и свяжет их с соответствующими библиотеками, избегая ошибки "X использует аргументы регистра VFP, Y не делает".
Вышеупомянутый -print-multi-lib
вывод, произведенный GCC с этим патчем и --with-multilib-list=armv6-m,armv7,armv7-m,armv7e-m,armv7-r,armv7-a,cortex-m7
Вариант конфигурации. Если вы заинтересованы в создании собственного gcc с поддержкой мультибиблиотек серии Cortex-A, просто используйте --with-multilib-list=aprofile
вариант конфигурации для любого arm*-*-*
цель без каких-либо исправлений ( в списке с gcc-6.2.0).
Согласно Linaro FAQ, если ваш компилятор печатает arm-linux-gnueabi;@marm@march=armv4t@mfloat-abi=soft
тогда вы можете использовать только -march=armv4t
, Если вы хотите использовать -march=armv7-a
вам нужно собрать компилятор самостоятельно.
Следующая ссылка может быть полезна при создании GCC ARM Builds.