Каковы механизмы выбора режима эмуляции для компоновщика?

#c #linker #codeblocks #avr-gcc

#c #компоновщик #codeblocks #avr-gcc

Вопрос:

Я пытаюсь скомпилировать код arduino в codeblocks с помощью компилятора avr-gnu. Я получал эту ошибку:

 avr-ld.exe unrecognized emulation mode: mcu=atmega328p.
Supported emulations:avr2 avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny
  

Я нашел эту страницу: https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html что предполагает, что он должен быть связан в режиме avr5 sim, поэтому я добавил -mmcu= avr5 в параметры компоновщика. Теперь я получаю:

 avr-ld.exe unrecognized emulation mode: mcu=avr5
Supported emulations:avr2 avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny
  

Каким образом avr5 не распознается, если он поддерживается?o0
Я пробовал несколько разных наборов инструментов за несколько разных лет, но, похоже, компоновщик не может правильно интерпретировать этот режим эмуляции. Более новые цепочки инструментов поддерживали 328p, но все еще почему-то не работают. Я также пытался создать проект CodeBlocks, предназначенный для Arduino, но разница в том, что он сам передает -mmcu=atmega328p и все еще не работает на этой или более новых цепочках инструментов.
Обновить:
Есть кое-что, чего я здесь совершенно не понимаю. Я сменил компоновщик на стандартный x86 32 ld.exe из Mingw и передал -mmcu=i386pe, и я получаю аналогичную ошибку:

 ld.exe unrecognized emulation mode: mcu=i386pe
Supported emulations:i386pe
  

Таким образом, это приводит только к моему непониманию механизмов выбора / настройки режима эмуляции компоновщика.

Комментарии:

1. mcu=avr5 а avr5 это разные строки? Почему в одном есть mcu= префикс, а в другом нет? То же самое для mcu=i386pe и i386pe

2. Ха, верно, это неправильно. Забавно, что я получил предложение от того, как проекты arduino в CodeBlocks настроены по умолчанию. Они выдают ошибку: mcu=atmega328p, которая предложила мне написать: -mmcu=avr5. Итак, я изменил его на: -mavr5, и он прошел через. Сгенерировал мой файл. elf и куча файлов .o из библиотек. Однако теперь у меня проблема с: нераспознанной опцией ‘-W1, —gc-selections’

3. Это «W one»? Это должно быть -Wl (строчная буква L, для компоновщика)

4. Это Wl. l для компоновщика.

5. @Genome: Если вы хотите опубликовать вопрос по этому поводу, убедитесь, что скопировали точную формулировку. Приведенный выше комментарий имеет '-W1'

Ответ №1:

Почти в любом случае, вы не хотите вызывать компоновщик ( ld соответственно. avr-ld ) вручную!

Используйте avr-gcc для компоновки ваших программ!

Обратите внимание, что avr-gcc это не компилятор сам по себе, это просто программа-драйвер, которая вызывает такие подпрограммы, как собственно компилятор ( cc1 для C, cc1plus для C , lto1 для LTO-скомпилированного байт-кода), ассемблер и компоновщик в зависимости от параметров командной строки и входных файлов, предоставляемых в командной строке.

avr-gcc знает, как предоставить соответствующим инструментам соответствующие параметры командной строки, такие как: эмуляция, библиотеки, пути для включений и библиотек, запускаемый код, дополнительные параметры и т.д.

Чтобы увидеть, какие инструменты вызываются с помощью avr-gcc , добавьте -v опцию. Например, для команды компиляции, такой простой, как

 > avr-gcc -v main.c -mmcu=atmega328p -save-temps
  

Вы увидите что-то вроде (здесь для avr-gcc версии 8.5.0):

 ...
COLLECT_GCC_OPTIONS='-v'  '-save-temps' '-specs=device-specs/specs-atmega328p' '-mmcu=avr5'

 $AVRGCC_HOME/bin/../libexec/gcc/avr/8.5.0/collect2 <many options> -plugin-opt=-pass-through=-latmega328p -mavr5 -Tdata 0x800100 $AVRGCC_HOME/bin/../lib/gcc/avr/8.5.0/../../../../avr/lib/avr5/crtatmega328p.o -L$AVRGCC_HOME/bin/../lib/gcc/avr/8.5.0/avr5 -L$AVRGCC_HOME/bin/../lib/gcc/avr/8.5.0/../../../../avr/lib/avr5 -L$AVRGCC_HOME/bin/../lib/gcc/avr/8.5.0 -L$AVRGCC_HOME/bin/../lib/gcc -L$AVRGCC_HOME/bin/../lib/gcc/avr/8.5.0/../../../../avr/lib main.o --start-group -lgcc -lm -lc -latmega328p --end-group
  

collect2 это просто какой-то другой инструмент, который переносит вызов в ld . Если вы хотите увидеть реальную вещь, используйте avr-gcc ... -v -Wl,-v .

Правильная эмуляция для компоновщика разрабатывается файлом спецификации для конкретного устройства, device-specs/specs-atmega328p расположенным по адресу ./lib/gcc/avr/$version в каталоге установки компилятора. Спецификации «language» — это средство описания сопоставлений параметров; в частности, биты, которые отвечают за сопоставление `-mmcu=atmega328p’ с правильной эмуляцией, являются

 *link_arch:
    %{mmcu=*:-m%*} 
...

*self_spec:
    %{!mmcu=avr*: %<mmcu=* -mmcu=avr5} %<mshort-calls %<msp8
  

self_spec удаляет -mmcu=* из командной строки и устанавливает -mmcu=avr5 , к какому семейству ядер принадлежит ATmega328P. Затем, как часть вызова компоновщика, link_arch сопоставляется -mmcu=avr5 с -mavr5 тем, какая эмуляция компоновщика будет использоваться.