【问题标题】:Cross-ld can’t find libstdc++.a, but shouldn’t have been lookingCross-ld 找不到 libstdc++.a,但不应该一直在寻找
【发布时间】:2015-10-17 19:42:52
【问题描述】:

我正在使用 OS X 和 Debian 上托管的 GCC 为 arm-eabi(arm-none-eabi 的别名)构建。相关代码不使用 C++。但是,该链接在 Debian 上失败了

/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/../../../../arm-eabi/bin/ld: cannot find libstdc++.a
collect2: error: ld returned 1 exit status

这让我感到惊讶,因为报告的链接行(带有-Wl,-v)也没有提到libstdc++(见最后)。

Debian 版本没有交叉libstdc++.a,而 OS X 版本有(我不知道这是怎么发生的;它只包含empty_arm_object.o)。如果我将此libstdc++.a 复制到 Debian 端,则构建工作正常;但我想了解为什么首先需要它。

链接命令行(为了清楚起见,我希望编辑)是

/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/../../../../arm-eabi/bin/ld                            \
-plugin                                                                                                 \
/opt/gnat-gpl-2015/bin/../libexec/gcc/arm-eabi/4.9.3/liblto_plugin.so                                   \
-plugin-opt=/opt/gnat-gpl-2015/bin/../libexec/gcc/arm-eabi/4.9.3/lto-wrapper                            \
-plugin-opt=-fresolution=/tmp/cctcp4CP.res                                                              \
-EL                                                                                                     \
-X                                                                                                      \
-o                                                                                                      \
/home/simon/cortex-gnat-rts/test-stm32f4//testbed                                                       \
-L/home/simon/cortex-gnat-rts/test-stm32f4/.build/                                                      \
-L/home/simon/cortex-gnat-rts/test-stm32f4/.build/                                                      \
-L/home/simon/cortex-gnat-rts/test-stm32f4/../stm32f429i-disco-rtos/adalib/                             \
-L/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/fpu                                                  \
-L/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/../../../../arm-eabi/lib/fpu                         \
-L/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3                                                      \
-L/opt/gnat-gpl-2015/bin/../lib/gcc                                                                     \
-L/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/../../../../arm-eabi/lib                             \
testbed.o                                                                                               \
b__testbed.o                                                                                            \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/last_chance_handler.o                                   \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/memory_streams.o                                        \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/containing.o                                            \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/dispatching.o                                           \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/iteration.o                                             \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/so.o                                                    \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/streams.o                                               \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/strings.o                                               \
/home/simon/cortex-gnat-rts/test-stm32f4/../stm32f429i-disco-rtos//adalib/libgnat.a                     \
/home/simon/cortex-gnat-rts/test-stm32f4/../stm32f429i-disco-rtos//adalib/libbsp-rtos.a                 \
-lgcc                                                                                                   \
-Map /home/simon/cortex-gnat-rts/test-stm32f4/testbed.map                                               \
-T /home/simon/cortex-gnat-rts/test-stm32f4/../stm32f429i-disco-rtos//adalib/stm32f429i-flash.ld
/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/../../../../arm-eabi/bin/ld: cannot find libstdc++.a
collect2: error: ld returned 1 exit status

链接描述文件的结尾包含

/DISCARD/ :
{
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
    libstdc++.a ( * )
}

/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }

第一个显然是arm-eabi-ld 在哪里找到对libstdc++.a 的引用。恐怕这些部分是从网络上的某个地方盲目复制的,我不知道第一个实际上是为了什么。是“您尚未分配的来自libstdc++.a 的任何东西”吗?

【问题讨论】:

  • 你能分享链接器脚本的内容吗? /home/simon/cortex-gnat-rts/test-stm32f4/../stm32f429i-disco-rtos//adalib/stm32f429i-flash.ld 它可能包含一些关于 libstdc++ 如何链接的指针...
  • 请注意,使用g++ 编译的任何代码默认链接到libstdc++。此外,如果任何预编译的 .o 对象是使用包含 libstdc++ 的不同工具链构建的,那么可能会有对它的引用。
  • 我在链接器脚本的末尾找到了libstdc++.a,并用相关的/DISCARD/ 部分更新了问题。感谢您的指点.. 但我不知道省略这些部分是否安全。链接器是否会丢弃所有在SECTIONS 下找不到位置的输入?
  • 特殊的输出节名称/DISCARD/ 可用于丢弃输入节。分配给名为/DISCARD/ 的输出节的任何输入节都不包含在输出文件中。如果任何输入对象文件都引用了libstdc++,那么这可能是链接器错误的原因。如果没有更多的编译和代码细节,我能想到隐式引用libstdc++ 的一个原因是一个或多个输入 object-filesstatic-libraries 使用g++ 编译。
  • 嗯...确实很有趣!您是否可以准备任何人都可以用来重现错误的最小可重现 code+makefile+linkerscript 设置? (......如果你很幸运,上述去除非必要部分的过程将解决问题,你将自己了解问题。)

标签: arm ld


【解决方案1】:

链接器寻找libstdc++.a 的原因是链接器脚本中的/DISCARD/ 部分提到了该库。

/DISCARD/ 部分中包含整个文件似乎很奇怪,其目的是省略输入的某些部分。如果您不想包含该文件,请将其排除在链接命令行之外!

调查显示ld 在这种情况下有一个意外行为,因为在/DISCARD/ 部分中包含libc.a 与在链接命令行中包含-lc 具有非常相似(如果不相同)的效果;在这种情况下使用的链接命令行以-nostdlib -lgcc结尾。应该是-nostdlib -lgcc -lc。这与删除特殊的 /DISCARD/ 部分一起解决了问题。

【讨论】:

    猜你喜欢
    • 2018-12-04
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 2021-05-07
    • 2020-06-18
    • 2021-12-21
    • 2015-01-30
    • 2018-06-15
    相关资源
    最近更新 更多