g ++ arm-none-eabi обновление с 4.9 до gcc 8.2. Сгенерированный бинарный файл больше не помещается во флэш - PullRequest
0 голосов
/ 04 января 2019

Я недавно обновил свой ноутбук с Linux с Ubuntu 16.04 до 18.04.

У меня был проект на основе Makefile STM32 (Cortex-M4), который правильно скомпилирован с версией arm-none-eabi g ++, предоставленной Ubuntu. Сгенерированный файл требует 47620 байт в разделе .text.

При обновлении Ubuntu я также установил обновленную версию gcc (с веб-сайт ARM ). Версия 8.2.1.

Когда я компилирую тот же проект (make clean && make), сгенерированный двоичный файл не помещается во флэш-память (требуется 97424 байта, более чем в два раза!). Проект точно такой же (исходники, скрипт ссылки, файлы запуска, Makefile).

Опции компилятора: -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -DSTM32F303x8 -DARMCM4 -O0 -g -Wall -fexceptions -Wno-deprecated.

Опции компоновщика: -mthumb -mcpu=cortex-m4 -Tstm32f303K8.ld -mfloat-abi=hard -mfpu=fpv4-sp-d16 --specs=nosys.specs -lm -Wl,--start-group -lm -Wl,--end-group -Wl,--gc-sections -Lsys -Xlinker -Map=test.elf.map

Когда я смотрю на сгенерированный файл .Map, все пользовательские функции имеют примерно одинаковый размер (новая версия экономит 8 байт!). Но после этого он включает в себя отдельные части C ++, и одна из них составляет более 26 КБ (из файла карты): .text 0x00000000080079e8 0x683c /usr/local/gcc-arm-none-eabi-8-2018-q4-major/bin/../lib/gcc/arm-none-eabi/8.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard/libstdc++.a(cp-demangle.o) 0x000000000800e13c __cxa_demangle

Примечание: нет проблем с проектами только на C, только с C ++. Включенные библиотеки одинаковы (gcc 4.9.3 -> armv7e-m/fpu и gcc 8.2.1 -> thumb/v7e-m+fp/hard): libm.a libstdc++.a libc.a libnosys.a libgcc.a

Есть ли способ избавиться от этого, чтобы я мог скомпилировать и прошить мой (не такой старый) проект?

С уважением,

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Я нашел решение, используя libstdc++_nano (вместо неявного libstc ++). При этом размер кода уменьшается с 84 до 26 КБ!

LDFLAGS += -lstdc++_nano

Это просто работает. Спасибо @Henrik, @Matthieu и @EOF за поддержку!

0 голосов
/ 04 января 2019

Это может быть связано с обработкой исключений, так как std :: terminate (), которая используется с исключениями, может вызывать процедуру разборки. Если вам не нужны исключения, попробуйте отключить их с помощью -fno-exceptions, как описано здесь .

Другим решением может быть просмотр заголовков GCC :

Разрушение рутины. ABI-обязательная точка входа в C ++ библиотека времени выполнения для разборки. [...] возвращает указатель на начало NUL-концевого деманглиста name, или NULL, если раскладка не удалась. Звонящий ответственность за освобождение этой памяти с помощью бесплатных.

Прототип: char* __cxa_demangle(const char* __mangled_name, char* __output_buffer, size_t* __length, int* __status); Таким образом, вы могли бы просто предоставить свою собственную фиктивную функцию, возвращающую NULL (учитывая, что все библиотечные функции являются слабыми и могут быть переопределены). Тем не менее, я посоветую вам сначала взглянуть на дизассемблированный код и выяснить, как и почему он вызывается в первую очередь, так как он может изменить поведение, просто отбрасывая функциональность).

Они также дают другие советы в Это сообщение на форуме , которое также может быть полезно для вас:

  • Оптимизируйте по размеру с помощью -Os вместо -O0 (возможно, вместо этого добавьте параметр -Og, если вы предпочитаете легко отлаживаемый код, он часто меньше и быстрее, чем -O0).
  • Оптимизация во время компоновки с -flto при компиляции и компоновке.
  • Может быть, отключить RTTI, если не используется.
...