#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 в корне вашего проекта.
Все, что сказано, если выходные данные компиляции различаются в зависимости от того, где вы находитесь при вызове компилятора, тогда, я думаю, вам лучше задать вопрос людям, предоставляющим кросс-компилятор, об этом странном поведении.
Вы пробовали вручную скомпилировать файл, находясь в другом каталоге? Изменяет ли это выводимый объектный файл?