Как (перекрестно) скомпилировать как 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.

Другие вопросы по тегам