Использование LTO с arm-none-eabi и newlib-nano

Я работаю над встраиваемым проектом для STM32F103 без операционной системы и использую Набор инструментов GNU ARM Embedded версии 7-2017-q4-major. В настоящее время я компилирую через GNU ARM Eclipse.

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

Invoking: Cross ARM C++ Linker
arm-none-eabi-g++ -mcpu=cortex-m3 -mthumb -O3 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -flto -Wall -Wextra  -g3 -T mem.ld -T libs.ld -T sections.ld -nostartfiles -Xlinker --gc-sections -L"../ldscripts" -Wl,-Map,"Project.map" -Xlinker --cref --specs=nano.specs -o "Project.elf"  ./tiny-mt/tinymt/tinymt32.o  ... .o   
/Users/me/opt/gcc-arm-none-eabi-7-2017-q4-major/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/libg_nano.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
/Users/me/opt/gcc-arm-none-eabi-7-2017-q4-major/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/lib/thumb/v7-m/libg_nano.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
collect2: error: ld returned 1 exit status
make: *** [Project.elf] Error 1

Очевидно, это связано с тем, что newlib-nano не компилируется с LTO?

Итак, как мне заставить его работать? Полагаю, я мог бы попробовать скомпилировать newlib- nano сам и добавляю необходимые флаги (и меняя инструменты для использования -gcc-ar и т. д.), но я представляю / надеюсь, что кто-то уже сделал бы это? Моего гугл-фу не хватило, чтобы найти что-нибудь полезное.


person Timo    schedule 06.06.2018    source источник
comment
Я не понимаю, зачем LTO нужны эти две функции, но specs=nosys.specs предоставляет базовые реализации системных функций, которые в основном просто возвращают коды ошибок. Вы можете попробовать это, если хотите   -  person Mike van Dyke    schedule 06.06.2018
comment
@MikevanDyke, похоже, работает! Мне пришлось дополнительно прокомментировать пользовательскую реализацию _exit из _syscalls.c, чтобы избежать еще одной (новой) ошибки компоновщика, но после этого все в порядке!   -  person Timo    schedule 06.06.2018


Ответы (1)


nosys.specs указывает на ссылку -lnosys с следует предоставить реализации-заглушки для _fstat и _isatty и других стандартов / posix functions.
Из параметров ссылки вручную на gcc:

-llibrary - поиск библиотеки с именем библиотека при компоновке. ...
Имеет значение, где в команде вы указываете эту опцию; компоновщик ищет и обрабатывает библиотеки и объектные файлы в том порядке, в котором они указаны. Таким образом, «foo.o -lz bar.o» выполняет поиск в библиотеке «z» после файла foo.o, но перед bar.o. Если bar.o относится к функциям в «z», эти функции могут не быть загружены.

Поэтому, если вы переместите --specs=nano.specs в конец вашей команды связывания, ваши источники будут связывать с -lnosys и правильно использовать реализации _isatty и _fstat из библиотеки libnosys. Нравится:

arm-none-eabi-g++ -mcpu=cortex-m3 -mthumb -O3 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -flto -Wall -Wextra  -g3 -T mem.ld -T libs.ld -T sections.ld -nostartfiles -Xlinker --gc-sections -L"../ldscripts" -Wl,-Map,"Project.map" -Xlinker --cref -o "Project.elf"  ./tiny-mt/tinymt/tinymt32.o  ... .o --specs=nano.specs

Я могу предположить, что newlib-nano, скомпилированный без LTO, тут ни при чем. Я использую несколько проектов с LTO и newlib-nano, и они отлично работают. Обычно LTO работает очень хорошо, удаляет слои функций абстракции, предсказуем, отлично оптимизирует, но у меня всего 2 года опыта его использования. Я использую -Ofast -flto -fno-fat-lto-objects, если мне действительно нужна скорость (и могу жить с нестандартным поведением).

person KamilCuk    schedule 06.06.2018
comment
Спасибо! Кажется, это работает, хотя я должен полностью исключить --specs=nano.specs (и добавить либо --specs=nosys.specs, либо -lnosys, либо одно, либо оба делают трюк). Кроме того, в моем конкретном проекте, который включает поддержку полухостинга из примера проекта ARM Eclipse, я должен удалить / закомментировать _exit из _syscalls.c. - person Timo; 06.06.2018
comment
Кроме того, хотя это решает мою проблему, я все же хотел бы знать, почему я получаю ошибку компоновщика, только если использую -flto? - person Timo; 06.06.2018
comment
@Timo Если вы используете полухостинг, вы также можете попробовать rdimon.specs. Но в противном случае не могу ответить, почему -flto выполняет эти системные вызовы. - person Mike van Dyke; 07.06.2018