проблема сборки cmake при создании кода для avr

#cmake #avr

#cmake #avr

Вопрос:

Я пытаюсь создать пример проекта для avr atmega328p. И я столкнулся со странной проблемой. У меня следующая структура каталогов.

 inc/core/device_support.h
src/main.c
src/core/device_support.c
  

У меня есть две настройки проекта, одна с использованием make, а другая с использованием cmake. Когда я собираю с помощью make, все работает нормально. но когда я использую cmake, он не компилируется нормально. ( .текстовый раздел не совпадает, если я запускаю avr-size -A myProject.elf , и он не выполняется корректно на целевом mcu). Но если я запускаю команду компиляции вручную в каталоге проекта cmake с каталогом сборки в качестве рабочего каталога, все работает нормально.

Я сузил проблему до того факта, что если мы запускаем команду компиляции form core /home/user/avr/build/core , она не работает, а если я запускаю команду, находясь в /home/user/avr/build каталоге сборки, она работает нормально. Я понятия не имею, почему это может происходить.

Мой вопрос в том, почему нахождение в другом каталоге приводит к сбоям при компиляции и как я могу это исправить в cmake.

с make у меня есть что-то вроде:

 avr-gcc -DARDUINO=10808 -DF_CPU=160000000L -I/home/user/avr/inc/core -mmcu=atmega328p -ffunction-sections -fdata-sections -MMD -flto -std=gnu11 -fno-fat-lto-objects -Os -w -g -MD -MT /home/user/avr/src/core/device_support.c -o /home/user/avr/build/core/device_support.o
  

и с автоматически сгенерированным сценарием cmake у меня есть:

 cd /home/user/avr/build/core amp;amp; avr-gcc -DARDUINO=10808 -DF_CPU=160000000L -I/home/user/avr/inc/core -mmcu=atmega328p -ffunction-sections -fdata-sections -MMD -flto -std=gnu11 -fno-fat-lto-objects -Os -w -g -MD -MT -o src/CMakeFiles/core.dir/src/core/device_support.o /home/user/avr/src/core/device_support.c
  

ОБНОВЛЕНИЕ 01:

avr-size -Вывод MyProject.elf (cmake):

  section                    size      addr
.data                         0   8388864
.text                       740         0
.bss                          9   8388864
.comment                     17         0
.note.gnu.avr.deviceinfo     64         0
.debug_aranges              120         0
.debug_info                3537         0
.debug_abbrev              1965         0
.debug_line                1044         0
.debug_frame                124         0
.debug_str                 1175         0
.debug_loc                  843         0
.debug_ranges                40         0
Total                      9678
  

avr-size -Вывод MyProject.elf (make):

     section                     size      addr
.data                          0   8388864
.text                        930         0
.bss                           9   8388864
.comment                      17         0
.note.gnu.avr.deviceinfo      64         0
.debug_aranges               104         0
.debug_info                 3559         0
.debug_abbrev               2002         0
.debug_line                 1134         0
.debug_frame                 180         0
.debug_str                  1139         0
.debug_loc                  1154         0
.debug_ranges                 24         0
Total                      10316
  

Вы можете увидеть разницу в разделе .text. Это простой код мигания светодиода, когда я запускаю это на устройстве, в случае cmake светодиод иногда остается включенным, а в других случаях полностью выключен. И если я скомпилирую тот же код вручную, выполнив те же команды из выходных данных cmake, но с каталогом сборки в качестве моего рабочего каталога, тогда индикатор мигает, как и ожидалось.

Во время сборки ни в том, ни в другом случае ошибок нет. Единственное отличие заключается в том, что он находится в каталоге сборки. Если я выполняю сборку вручную, а мой рабочий каталог не собран, то в этом случае также произойдет сбой. По какой-то причине важно находиться в каталоге сборки во время компиляции, и я понятия не имею, почему.

Обновление 02: Пример кода был загружен на: https://github.com/systemangle/mcve_avr

Пожалуйста, смотрите проект readme.

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

1. «он некорректно запускается на целевом mcu» — Уточните это. Есть ли у вас какие-либо предупреждения или ошибки во время сборки проекта? Что выводится при попытке запустить созданный elf?

2. Вы опубликовали только команды для компиляции device_support.o . Возможно, проблема в командной строке компоновщика? Можете ли вы опубликовать все сообщения из cmake и make?

3. Команды компоновщика @KamilCuk выполняются нормально, когда я запускаю их вручную, просто копируя их из выходных данных. Я обновлю вопрос со всеми командами. Но, как я уже сказал, каждый скомпилированный объектный файл отличается по размеру, если я использую cmake, и один и тот же файл кода выдает правильный размер объектного файла, если я компилирую вручную, просто скопировав команду из выходных данных, важно только то, что я должен находиться в каталоге сборки во время компиляции.

4.Затем давайте проверим объектные .o файлы. Попробуйте создать самый маленький .c файл, для которого заметна разница, опубликуйте его, опубликуйте сгенерированный результат сборки. Заметна ли разница в main.o или device_support.o или в обоих? Имеет ли cmake или make вообще отношение к вопросу? Можете ли вы создать MCVE, небольшой скрипт для воспроизведения проблемы? Было бы здорово включить также cat <<EOF >file.c .... содержимое файла и avr-gcc .... cd .... amp;amp; avr-gcc .. команды компиляции и выходные данные avr-size обоих файлов в один скрипт. Проблема странная. Можете ли вы опубликовать avr-gcc версию?

5. @KamilCuk Да, все файлы .o отличаются при использовании cmake. Я попробую сделать MCVE. Актуальность make и cmake такова, что я пытаюсь перенести проект на основе make в cmake. что я сделал, так это заменил Makefile на CMakeLists.txt и создал набор инструментов для cmake, чтобы выбрать подходящий компилятор и т.д. Я пробовал как с gcc 8.3.0, так и с arduino gcc 5.4.0. На самом деле для MCVE я пытаюсь перенести файлы arduino в настройки моего проекта cmake. Пока я вижу похожие результаты. Я поделюсь этим после того, как это будет сделано.

Ответ №1:

По какой-то причине важно находиться в каталоге сборки во время компиляции, и я понятия не имею, почему

Тогда у вас, вероятно, уже есть ответ. Проблема, похоже, не связана с CMake. Возможно, вы можете попробовать сборку с использованием cmake и посмотреть, что произойдет. В противном случае, если вы хотите имитировать поведение Makefile, написанное от руки, вы можете избежать использования любого add_subdirectory и написать только большой fat CMakeLists.txt в корне вашего проекта.

Все, что сказано, если выходные данные компиляции различаются в зависимости от того, где вы находитесь при вызове компилятора, тогда, я думаю, вам лучше задать вопрос людям, предоставляющим кросс-компилятор, об этом странном поведении.

Вы пробовали вручную скомпилировать файл, находясь в другом каталоге? Изменяет ли это выводимый объектный файл?