Включает ли скомпилированный бинарный файл скетча неиспользуемые функции из библиотеки?

Я пишу графический интерфейс с использованием TFT-дисплея и библиотеки Adafruit GFX и ее шрифта по умолчанию на Arduino Nano. Я хочу экономить память, и я предположил, что настройка компилятора "оптимизировать по размеру" по умолчанию не будет компилироваться и включать все функции из всех включенных библиотек, если эти функции никогда не вызываются в скетче.

Однако я читал это руководство по управлению памятью, в котором советуется (на пейджере 20) удалить "неиспользуемые библиотеки" и "неиспользуемые функции" из вашего скетча, чтобы сэкономить память. Итак, у меня есть 2 связанных вопроса:

  1. Включает ли компилятор Arduino IDE все скомпилированные двоичные файлы из этих библиотечных функций, даже если они никогда не вызываются в исходном скетче (я знаю, что любые глобальные переменные в библиотеке будут занимать место, даже если они не используются, но я специально спрашиваю о неиспользуемых функциях)?

  2. Если это так, будет ли создание моей собственной модифицированной, урезанной версии стандартных библиотек экономить место?

Спасибо.

, 👍4


1 ответ


Лучший ответ:

6

Как правило, только функции, фактически используемые вашим кодом, включаются в конечную привязку двоичного файла.

Однако компилятор не всегда может знать, что используется, а что нет.

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

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

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

Кстати: "оптимизировать по размеру" не имеет ничего общего с тем, какой код включен / исключен. Вместо этого он управляет такими вещами, как то, какая функция выбрана для inline, и какие циклы разворачиваются или нет, среди прочего.

,

некоторые ядра Arduino не используют LTO. например, для ядра STM32 от STM опция LTO никогда не создает двоичный файл рабочего приложения, @Juraj

@Juraj Он по-прежнему будет включать только то, что необходимо. LTO больше подходит для обрезки полиморфизма. Это бит "По мере продвижения компилятора ...", который значительно улучшает его, но всегда было выборочное включение и "-ffunction-разделы -gc-разделы" и т. Д., @Majenko