【问题标题】:Using LTO with arm-none-eabi and newlib-nano将 LTO 与 arm-none-eabi 和 newlib-nano 一起使用
【发布时间】:2018-11-15 21:17:05
【问题描述】:

我正在为 STM32F103 开发一个裸机嵌入式项目,我正在使用GNU ARM Embedded version 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 编译?

那么我该如何让它工作呢?我想我可以尝试compiling newlib-nano myself 并添加必要的标志(并更改工具以使用 -gcc-ar 等等),但我想/希望有人已经这样做了?我的 google-fu 不足以找到任何有用的东西。

【问题讨论】:

  • 我不知道为什么 LTO 需要这两个函数,但 specs=nosys.specs 提供了系统函数的基本实现,大部分只是返回错误代码。如果你愿意,你可以试试
  • @MikevanDyke 似乎确实有效!我不得不另外从_syscalls.c 中注释掉_exit 的自定义实现以避免另一个(新)链接器错误,但之后似乎没问题!

标签: c++ gcc arm newlib link-time-optimization


【解决方案1】:

nosys.specs 指定链接 -lnosys 应为 _fstat 和 _isatty 以及其他标准/posix 函数提供存根实现。
来自gcc manual link options

-图书馆
链接时搜索名为 library 的库。 ...
在命令中编写此选项的位置有所不同;链接器按照指定的顺序搜索和处理库和目标文件。因此,“foo.o -lz bar.o”在文件 foo.o 之后但在 bar.o 之前搜索库“z”。如果 bar.o 引用了 ‘z’ 中的函数,这些函数可能不会被加载。

因此,如果您将 --specs=nano.specs 移动到链接命令的末尾,则您的源将使用 -lnosys 链接并正确使用 libnosys 库中的 _isatty_fstat 实现。像这样:

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

我猜想没有 LTO 编译的 newlib-nano 与它无关。我正在使用带有 newlib-nano 的 LTO 的多个项目,它们工作得很好。通常 LTO 工作得非常好,去除了抽象函数层,可预测,优化非常好,但我只有 2 年的使用经验。如果我真的需要速度(并且可以忍受非标准行为),我会使用 -Ofast -flto -fno-fat-lto-objects

【讨论】:

  • 谢谢!这似乎可行,尽管我必须完全省略--specs=nano.specs(并添加--specs=nosys.specs-lnosys,其中一个或两个都可以解决问题)。此外,在我从 ARM Eclipse 示例项目中引入半主机支持的特定项目中,我必须从 _syscalls.c 中删除/注释掉 _exit
  • 另外,虽然这解决了我的问题,但我仍然想知道为什么只有在使用 -flto 时才会出现链接器错误?
  • @Timo 如果您使用的是半主机,您也可以尝试rdimon.specs。但除此之外,无法回答为什么 -flto 会进行这些系统调用。
猜你喜欢
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 2018-10-13
  • 2016-05-01
  • 1970-01-01
  • 2013-12-16
相关资源
最近更新 更多