Как предотвратить включение функций разборки имен в C ++ в двоичный файл? - PullRequest
3 голосов
/ 03 мая 2019

Я разрабатываю прошивку для встроенного приложения на ARM Cortex-M на C ++ с GCC 7.3.1 в режиме C ++ 14. Доступно только 64 КБ флэш-памяти, и мой двоичный файл не подходит. Глядя на файл карты, я вижу, что есть функция с именем __gcclibcxx_demangle_callback в двоичном файле, которая занимает 27 Кбайт памяти. Я понимаю, что это связано с разборкой имен в C ++. Компоновщик не удаляет этот символ, хотя я определенно не делаю разметку имени в своем коде. Я использую STL здесь и там, хотя. Как я могу исключить эту функцию, чтобы получить немного места для вспышки?

Я попытался передать -ffreestanding -fno-exceptions -nostartfiles -fno-rtti компилятору и компоновщику. Передача -nostdlib приводит к сбою связи, даже если я передаю -lc -lg -lgcc -lstdc++.

Ответы [ 2 ]

0 голосов
/ 09 мая 2019

@ Комментарий Русса Шульца заставил меня задуматься.Очень вероятно, что на самом деле это был какой-то код STL, который использовал разделение имен, и было бы удивительно, если бы не было другого libstdc ++, который был бы более подходящим для встраиваемых систем.Очевидно, GNU Arm Embedded Toolchain предоставляет альтернативные версии libstdc ++.Одним из них является «нано» версия, которую можно легко использовать, передав -specs=nano.specs компоновщику.Это резко уменьшает размер получаемого двоичного файла (от 115k до 45k), и, грубо говоря, содержимое действительно включает только необходимые символы.Почти никакой код не раздувается, за исключением некоторых C ++ vtables, которые в любом случае крошечные.

0 голосов
/ 06 мая 2019

Дополнительные параметры:

-Os -flto  -fno-fat-lto-objects -fuse-ld=gold -fuse-linker-plugin \
-Wl,--icf=all -Wl,--icf-iterations=4 -Wl,--gc-sections -Wl,--as-needed \
-Wl,--strip-all -Wl,-O3 -Wl,--orphan-handling=discard -Wl,--no-eh-frame-hdr \
-Wl,--no-ld-generated-unwind-info -fno-unwind-tables

исправлена ​​ошибка
(--icf относится к «золоту»)

Я просто изучаю, как сам, но если это не поможет, вы можете начать модифицировать скрипт компоновщика ... вы можете добавить "неявный" скрипт компоновщика к постоянным настройкам по умолчанию, передав его в строке ссылки ( ld пытается прочитать все, что не похоже на объектный код, как скрипт). Мое лучшее предположение - вы захотите назначить проблемную библиотеку отдельному разделу, а затем отбросить ее >

Компоновщик будет игнорировать присвоение адресов (* примечание Раздел вывода Адрес: :) на удаленных разделах вывода, кроме случаев, когда скрипт компоновщика определяет символы в разделе вывода. В этом случае компоновщик будет подчиняться адресным присвоениям, возможно, продвигая точку, даже если раздел отбрасывается.

Специальное имя секции вывода '/ DISCARD /' может использоваться для удаления входные разделы. Любые входные разделы, которые назначены на выход раздел с именем '/ DISCARD /' не включен в выходной файл.

Я чувствую, что это действительно не должно быть, но есть также --no-demangle ...

edit: если вы пытаетесь скомпилировать с -nostdlib, вам может понадобиться комбинация -lgcc_s -lsupc++ -lm, -B `your/compiler/dir` и т. Д.

...